Flex/Bison区间算术程序输入闭区间时出现语法错误的问题求助
问题排查与解决方案
咱们来一步步拆解你遇到的问题:闭区间输入触发语法错误,但开区间能正常运行,核心原因出在Bison代码的两个关键错误上:
1. %union 声明顺序错误
Bison有严格的语法声明顺序要求:必须先定义%union,再声明带类型的%token和%type。你的代码里把%union放在了%token和%type之后,这会导致Bison在处理%token <n> NUMBER和%type <n> E T时,完全不知道<n>对应什么类型成员。这种情况下生成的解析器会出现逻辑异常,无法正确匹配闭区间的语法规则,从而触发语法错误。
2. 语义动作缺少分号
在E和T的规则里,你写的{$$ = $1}是不完整的C语句,必须加上分号变成{$$ = $1;}。虽然开区间似乎能运行,但这只是编译器的侥幸行为,缺少分号会导致编译阶段的语法隐患,直接影响解析器的稳定性。
修正后的Bison代码
%{ #include <stdio.h> int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; %} // 先定义类型联合,再声明token和非终结符类型 %union { int n; int ar[10]; } %token <n> NUMBER %token LEFTOPEN RIGHTOPEN LEFTCLOSE RIGHTCLOSE %token MID %type <n> E T %% O: | LEFTOPEN E MID T RIGHTOPEN { for(int i = $2; i < $4 - 1; i++){ printf("%d ", arr[i]); } printf("\n"); } | LEFTCLOSE E MID T RIGHTCLOSE { for(int i = $2 - 1; i < $4; i++){ printf("%d ", arr[i]); } printf("\n"); } ; E: NUMBER {$$ = $1;} ; // 补充分号 T: NUMBER {$$ = $1;} ; // 补充分号 %% int main(int argc, char** argv) { yyparse(); return 0; } void yyerror(const char* msg) { fprintf(stderr, "ERROR! %s\n", msg); }
验证结果
重新编译Flex和Bison代码后:
- 输入
(1:5)会输出2 3 4(符合开区间预期) - 输入
[1:5]会输出1 2 3 4 5(符合闭区间预期)
内容的提问来源于stack exchange,提问作者Shahin Mammadov
相关产品推荐
相关产品推荐

