自定义编程语言解析器语法错误排查:T_RCURPAR异常分析
自定义编程语言解析器语法错误排查
问题背景
开发自定义编程语言,已实现词法分析器、解析器与AST,多数场景下AST构建正常,但测试特定输入时出现语法错误,解析器表现不符合预期。
测试输入代码
whole_y a -> 5; floaty b -> 6; chain d -> ^ciao come stai^; throw_up 5; send_back 5; ciao(a,a); go as_long_as(a>5){ a->5; } all_set;
错误信息
Error at line 1: syntax error, unexpected T_RCURPAR, expecting ';'
相关文法规则片段
block: T_GO control_block T_ALL_SET { $$ = node1(_CONTROLBLOCK, $2); } ; control_block: if_block { $$ = $1; } | while_block { $$ = $1; } | for_block { $$ = $1; } | switch_case { $$ = $1; } ; while_block: T_AS_LONG_AS T_LPAREN expression T_RPAREN T_LCURPAR statements T_RCURPAR { $$ = node2(_WHILE, $3, $6); } ; statements: statement ';' { $$ = $1; } | statements statement ';' { $$ = node2(_STATEMENTS, $1, $2); } ; statement: declaration { $$ = node1(_DECLARATION, $1); } | assignment { $$ = node1(_ASSIGNMENT, $1); } | function_call { $$ = $1; } | block { $$ = $1; } | T_SENDBACK expression { $$ = node1(_RETURN, $2); } | T_THROWUP expression { $$ = node1(_PRINT, $2); } ;
已执行排查步骤
- 检查缺失或冲突的文法规则
- 调试词法分析器确保token生成正确
- 简化输入以隔离问题文法规则
问题原因分析
statements规则未明确终止条件while_block中statements被包裹在{}内,但当前statements仅定义为以;结尾的语句序列,没有识别}作为终止标记。解析完a->5;后,解析器会持续尝试匹配下一个statement ';',此时遇到}(T_RCURPAR),与预期的;冲突,触发语法错误。block规则与输入格式不匹配
文法中block规则要求结尾为T_ALL_SET(即all_set),但测试输入中结尾是all_set;(多了分号)。解析器完成control_block匹配后,期望遇到T_ALL_SET,后续的;打破规则匹配,加剧解析混乱。递归规则存在隐式歧义
statement包含block选项,而block又依赖control_block,这种递归结构可能导致解析器错误地将all_set识别为内部block的一部分,而非当前go块的结束标记。
修复方案
- 调整
statements规则,添加终止逻辑
修改statements规则,允许空语句或在遇到}时终止解析:
statements: statement ';' { $$ = $1; } | statements statement ';' { $$ = node2(_STATEMENTS, $1, $2); } | /* 空规则,支持空语句块 */ { $$ = NULL; } ;
- 对齐
block规则与输入格式
二选一:
- 将输入中的
all_set;改为all_set(移除分号) - 修改
block规则,允许T_ALL_SET后跟分号:
block: T_GO control_block T_ALL_SET ';' { $$ = node1(_CONTROLBLOCK, $2); } ;
- 优化递归规则优先级
为T_GO设置更高优先级,确保解析器优先识别go块结构,避免将其作为普通statement处理。
内容的提问来源于stack exchange,提问作者gigigagagogo
相关产品推荐
相关产品推荐

