from abc import ABCMeta, abstractmethod
class Expr(metaclass = ABCMeta):
pass
class NumberExpr(Expr):
def __init__(self, num):
self.number_ = num
def number(self):
return self.number_
class BinaryExpr(Expr):
def __init__(self, op, lhs, rhs):
self.op_ = op
self.lhs_ = lhs
self.rhs_ = rhs
def getOp(self):
return self.op_
def getLHS(self):
return self.lhs_
def getRHS(self):
return self.rhs_
class Visitor(metaclass = ABCMeta):
@abstractmethod
def visitNumberExpr(self, expr):
pass
@abstractmethod
def visitBinaryExpr(self, expr):
pass
def visitExpr(self, expr):
visit_method = getattr(self, 'visit' + expr.__class__.__name__)
visit_method(expr)
class Printer(Visitor):
def __init__(self, pretty = True):
self.pretty_ = pretty
def print(self, expr):
self.visitExpr(expr)
def visitNumberExpr(self, expr):
print(expr.number(), end = '')
def visitBinaryExpr(self, expr):
print('(', end = '')
self.visitExpr(expr.getLHS())
if self.pretty_:
print(' {0} '.format(expr.getOp()), end = '')
else:
print(expr.getOp(), end = '')
self.visitExpr(expr.getRHS())