You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python基于PLY yacc开发Cool编译器解析器报BLOCK_INIT语法错误

问题背景
  • 开发环境:基于Python的PLY库lex、yacc模块开发Cool语言编译器,已完成词法分析文件lexer.py、语法分析文件parser.py,按Cool语言规范实现了保留字定义、词法规则、语法产生式、运算符优先级配置、AST生成逻辑。
  • 测试代码:
class Main inherits IO { main(): SELF_TYPE { out_string("Hello, World."); }; }
  • 故障现象:执行yacc.parse(data)时返回None,控制台抛出错误:
Syntax error: Unexpected BLOCK_INIT({) on line 1
触发原因

该语法错误由两个配置不匹配问题共同导致:

  1. 词法token与语法规则的命名不统一:词法层将左大括号{标记为BLOCK_INIT类型token,但编写语法产生式时,类定义、方法体位置的左大括号仍使用字面量'{'做匹配。PLY的yacc模块会将字面量符号识别为独立token类型,和lex输出的BLOCK_INIT类型无法匹配,解析到{位置时找不到可归约的产生式,直接抛出语法错误。
  2. 方法定义产生式结构缺失:Cool规范中类内方法的语法结构为方法名(参数列表): 返回类型 { 方法体 };,现有语法规则要么漏写了返回类型段与方法体块的衔接逻辑,要么类成员列表的产生式没有将该形式的方法定义纳入合法匹配项,导致解析到SELF_TYPE后,后续的{被判定为非法位置的token。
修复步骤

按以下顺序调整代码即可解决问题:

  • 统一token命名:全局检查parser中的产生式,所有大括号位置的匹配项,将字面量'{'替换为BLOCK_INIT、字面量'}'替换为对应词法定义的块结束token名(通常是BLOCK_END),确保词法输出的token类型和语法规则中写的token名完全一致。
    示例修正后的方法定义产生式:
    def p_method_feature(p):
        'feature : ID LPAREN formal_list RPAREN COLON type BLOCK_INIT expr BLOCK_END SEMI'
    
  • 对齐类定义产生式:严格按照Cool规范补全类定义结构,确保类内特征(属性、方法)列表能正确匹配无参数的main方法定义,参考类产生式写法:
    def p_class(p):
        'class_def : CLASS TYPE INHERITS TYPE BLOCK_INIT feature_list BLOCK_END SEMI'
    
    注意要给feature_list配置空规则、多特征递归规则,支持类内0到多个属性/方法的匹配。
  • 校验优先级配置:移除给BLOCK_INIT/BLOCK_END配置的错误优先级,块标记优先级需低于常规表达式运算符,避免解析过程中提前归约导致块结构断裂。
  • 调试定位细节:启动yacc时开启debug模式,通过解析栈日志确认具体哪条产生式匹配断裂:
    parser = yacc.yacc(debug=True)
    parse_result = parser.parse(test_code)
    

内容的提问来源于stack exchange,提问作者BLGO 94

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 18:57:25