使用PLY构建编译器时yacc开启debug出现RKEY报错如何解决
错误含义
这个是PLY语法分析阶段抛出的语法不匹配错误,各字段含义如下:
State: 0表示语法分析器当前处于初始状态,尚未匹配到任何你定义的语法规则前缀Stack : . LexToken(RKEY,'}',5,94)表示当前分析栈为空,待处理的下一个词法单元是右大括号},该token位于输入文件第5行、第94个字符位置- 核心问题:你定义的语法起始规则无法匹配输入代码的结构,初始状态下遇到的token不属于起始规则允许的首符号集合;也可能是词法分析器输出token的顺序异常,导致语法分析器拿到的第一个有效token就是右大括号。
修复方案
你可以按照以下顺序排查修复:
- 验证词法分析器输出
先单独运行词法分析器,输出所有token的顺序、类型、行号信息,确认token顺序和输入代码结构一致,没有漏掉开头的int、gcd等token,也没有提前输出末尾的右大括号。 - 检查语法起始符号声明
在你的Parser模块中必须显式指定语法的起始产生式,比如你的顶层语法规则是program,则需要添加声明:
未显式声明的情况下PLY会默认取你写的第一个产生式作为起始规则,大概率和输入的完整代码结构不匹配。start = 'program' - 匹配函数定义的语法规则
你的测试输入本身存在逻辑问题:函数定义仅声明了一个参数int u,但函数体内使用了未声明的变量v,递归调用gcd时也传入了2个参数,和定义的参数个数不符。如果你的语法规则对参数个数、变量声明有校验,需要先修正输入代码的函数定义为:int gcd(int u, int v) { if (v == 0) return u; else return gcd(v, u-u/v*v); /* comment */ } - 补充错误处理逻辑
在Parser模块中添加专用的错误处理函数,输出更精准的错误上下文,方便后续排查:def p_error(p): if p: print(f"语法错误:第{p.lineno}行,非法token类型:{p.type},值:{p.value}") else: print("语法错误:输入意外结束")
内容的提问来源于stack exchange,提问作者Tiago de Luna
相关产品推荐
相关产品推荐

