如何修复Bison解析器中decl_gvar与decl_function的语法歧义?
问题原因
你的解析器优先匹配decl_gvar而非decl_function,核心原因是语法结构顺序与LALR(1)解析器的决策逻辑冲突:
- 程序入口规则
progr中,decl_gvars排在decl_functions之前,解析器会优先尝试把所有以TYPE开头的结构匹配到decl_gvar; - 当遇到
TYPE ID时,decl_gvar的规则(typedecl list_ID)已经可以完成匹配(list_ID能匹配单个ID),解析器会直接归约为decl_gvar,导致后续函数声明的(被视为语法错误,无法触发decl_function规则。
解决方案
将全局变量声明和函数声明合并到同一个顶层规则中,让解析器能根据后续token区分两者。具体修改如下:
1. 修改程序入口与声明规则
替换原有的decl_gvars和decl_functions为合并后的declarations:
progr : decl_classes declarations block {printf("The programme is correct!\n");} ;/*1. classes 2.global vars/functions 3.enetry point*/ declarations : declaration ';' declarations | {cout<<"No more declarations\n";} ; declaration : decl_function | decl_gvar ;
2. 保留原有规则
decl_function、decl_gvar、typedecl等其他规则无需改动。此时解析器会在遇到TYPE ID后,根据下一个token判断:
- 若为
(,则移进并匹配decl_function; - 若为
[、,或;,则归约为decl_gvar。
3. 验证冲突
执行bison -v your_parser.y生成.output文件,检查是否存在移进/归约冲突。若仍有冲突,可进一步调整规则优先级(不过合并规则后通常能解决问题)。
测试验证
修改后,输入函数声明(如int foo() { ... })会正确匹配decl_function;输入全局变量声明(如int a, b[10];)会匹配decl_gvar。
内容的提问来源于stack exchange,提问作者Stefan Cristea Olaru WolfGamer
相关产品推荐
相关产品推荐

