PLY解析器语法使用expression触发未定义符号错误如何解决
问题原因
Symbol 'expression' used, but not defined as a token or a rule
该报错的核心是你在show语句的语法规则中引用了expression非终结符,但你的解析器代码中没有定义expression对应的语法规则。PLY的yacc模块要求所有出现在语法规则中的非终结符,都必须有对应的p_前缀的规则函数定义,否则无法生成语法分析表。你参考的官方示例中实际是有expression相关规则定义的,对应示例里计算器的各类运算规则部分。
解决方法
你需要补充expression的语法规则,覆盖你需要支持的所有可打印内容类型,按你当前代码支持的字符串、变量两类内容,修改方案如下:
- 新增
expression规则对应的解析函数
# 字符串字面量表达式 def p_expression_string(p): 'expression : STRING' # 去掉字符串前后的引号,返回原始内容 p[0] = p[1][1:-1] # 变量引用表达式 def p_expression_name(p): 'expression : NAME' # 从变量存储中取值,可自行补充变量不存在的异常处理 p[0] = Variables.get(p[1], f"[Error: 变量 {p[1]} 未定义]")
- 修改
show语句的处理逻辑,直接取expression返回的解析结果
def p_show(p): 'statement : SHOW LPAREN expression RPAREN ' value = p[3] print(value)
- 删除冗余的
p_variable函数,变量引用的逻辑已经合并到expression规则中。
拓展说明
如果后续你需要支持更多类型的可打印内容,比如数字、算术运算、函数返回值等,只需要新增对应的expression子规则即可,不需要修改show语句的现有规则,即可自动支持打印新类型的内容,符合你泛化匹配的需求。
比如要新增数字支持的话,只需要:
- 在
tokens列表中新增NUMBER - 新增
NUMBER对应的词法规则 - 新增
p_expression_number的语法规则即可
内容的提问来源于stack exchange,提问作者Jael Andres
相关产品推荐
相关产品推荐

