此方的呆毛吧 关注:65贴子:1,048
  • 3回复贴,共1

visitor pattern

只看楼主收藏回复


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())



1楼2012-10-28 12:01回复
    print(')', end = '')
    class Evaluator(Visitor):
    def __init__(self):
    self.value_stack_ = []
    def eval(self, expr):
    self.visitExpr(expr)
    return self.value_stack_[-1]
    def visitNumberExpr(self, expr):
    self.value_stack_.append(expr.number())
    def visitBinaryExpr(self, expr):
    self.visitExpr(expr.getLHS())
    self.visitExpr(expr.getRHS())
    lhs_value = self.value_stack_.pop()
    rhs_value = self.value_stack_.pop()
    eval_func = {
    '+': lambda l, r: l + r,
    '-': lambda l, r: l - r,
    '*': lambda l, r: l * r,
    '/': lambda l, r: l / r
    }
    if expr.getOp() in eval_func:
    result = eval_func[expr.getOp()](lhs_value, rhs_value)
    self.value_stack_.append(result);
    else:
    raise Exception('unknown binary operator: {0}'.format(expr.getOp()))
    if __name__ == '__main__':
    # 1 + 2 * 3 + 4
    e1 = NumberExpr(2)
    e2 = NumberExpr(3)
    e3 = BinaryExpr('*', e1, e2)
    e4 = NumberExpr(1)
    e5 = BinaryExpr('+', e4, e3)
    e6 = NumberExpr(4)
    e7 = BinaryExpr('+', e5, e6)
    printer = Printer()
    printer.print(e7)
    print(' = ', end = '')
    evaluator = Evaluator()
    print(evaluator.eval(e7))
    


    2楼2012-10-28 12:01
    回复


      IP属地:江苏3楼2012-10-28 12:20
      收起回复