使用PLY开发C-minus编译器时无法获取打印AST问题求助
PLY构建C-minus编译器parser返回None问题排查
问题常见原因
- 语法规则动作块未显式返回节点
PLY的每个语法规则对应处理函数中,必须给p[0]赋值为当前规则构造的AST节点,这个值会作为父规则的p[n]参数向上传递。如果顶层规则(整个程序的根规则)没有给p[0]赋值,parser.parse()最终返回的结果就会是None。你可以先排查所有语法规则的处理函数,确认每个构造完节点的逻辑后都有类似p[0] = 构造的节点的代码。
示例正确写法:
# 顶层规则示例 def p_program(p): '''program : declaration_list''' # 构造Program类型的AST根节点,将子规则的返回值作为参数传入 p[0] = Program(p[1])
- 起始规则配置错误
如果没有在parser代码中显式指定start = '你的顶层规则名',PLY会默认把你写的第一个语法规则作为匹配的起始规则。如果第一个规则不是对应整个C-minus程序的根规则,会出现输入匹配不完整、匹配失败的情况,最终返回None。 - 语法错误未正常处理
如果你的输入代码存在语法错误,而你自定义的p_error错误处理函数没有做容错返回逻辑,也会导致parse方法返回None。你可以调用parser.parse(输入内容, debug=True)开启调试模式,查看详细的匹配过程、错误位置,快速定位问题。 - 代码执行顺序问题
你提到的运行输出顺序为pass 1、Nonepass 3、pass 2,如果你的代码中pass 2的打印逻辑是写在语法规则的动作块里,那说明parser.parse()执行完成前就已经打印了返回值,也侧面验证了parse方法确实返回了None,问题还是出在AST节点的返回逻辑上。
AST构建学习参考
你可以直接参考PLY官方文档里的语法分析部分的AST构造示例,里面有完整的表达式解析、节点构造的可运行代码。另外国内很多高校的编译原理公开实验指导都包含基于PLY实现C-minus编译器的完整步骤,其中AST构建、遍历打印的部分写的非常详细,可以跟着逐步调试。
内容的提问来源于stack exchange,提问作者Tiago de Luna
相关产品推荐
相关产品推荐

