python解释器实现及其嵌入式应用:抽象语法树

英文原文地址

第七部分开始引入了抽象语法树,开始考虑到代码的耦合性。剥离了lexer,parser和interpreter。值得一提的是,上一篇随笔提到的右括号匹配问题在这里解决了,也是通过添加额外代码解决的。

def parse(self):
    node = self.expr()
    if self.current_token.type != EOF:
        self.error()

这里通过增加parse函数,隔离了expr递归时候的耦合,然后再检查expr结束时是不是还有token,如果右括号多于左括号,那么在检测到第一个多余的右括号的时候,expr递归就会结束,导致后面的表达式无法匹配。如果没有语法错误,那么parse函数就返回一棵抽象语法树的根节点。

通过AST这个中间结构就把parser和interpreter给隔离了,可以独立的去设计语法分析程序和解释程序。

类的包含关系

interpreter->parser->lexer

练习题

  • 返回Reverse Polish Notation
    就是打印就是后序遍历的过程,这个很简单,因为spi.py中的interpreter就是后序遍历的。只要添加打印就可以了。

    1. 在visit_BinOp返回前打印运算符
    2. 在visit_Num返回前打印整型值
   def visit_BinOp(self, node):
        if node.op.type == PLUS:
            value = self.visit(node.left) + self.visit(node.right)
        elif node.op.type == MINUS:
            value = self.visit(node.left) - self.visit(node.right)
        elif node.op.type == MUL:
            value = self.visit(node.left) * self.visit(node.right)
        elif node.op.type == DIV:
            value = self.visit(node.left) / self.visit(node.right)
        print node.op.value,
        return value

    def visit_Num(self, node):
        print node.value,
        return node.value
  • 返回Lisp Style Notation

Lisp Style Notation等效于前序遍历,怎么实现呢? 只要在递归开始前打印运算符就可以了。

    def visit_BinOp(self, node):
        print '(', node.op.value,
        if node.op.type == PLUS:
            value = self.visit(node.left) + self.visit(node.right)
        elif node.op.type == MINUS:
            value = self.visit(node.left) - self.visit(node.right)
        elif node.op.type == MUL:
            value = self.visit(node.left) * self.visit(node.right)
        elif node.op.type == DIV:
            value = self.visit(node.left) / self.visit(node.right)
        #print node.op.value,
        print ')',
        return value    

    def visit_Num(self, node):
        print node.value,
        return node.value
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶玄青

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值