如何在Bison表达式的开头、中间或末尾插入任意符号?
代码失效原因
现有代码无法正常运行是几个低级逻辑问题导致的:
- 词法层没处理
!和_:yylex遇到这两个字符直接返回ERROR,语法里写的匹配规则永远触达不到 - 数字读取逻辑错漏:循环读多位数时反复覆盖yylval,最后只会存最后一位的值;读完数字后多取的字符没回退输入流,后续所有字符识别都会错位
- 错误处理逻辑粗暴:碰到任意非法字符就直接吞掉整行,根本做不到格式校验
- 存在死代码:return ERROR之后的yyerror调用永远不会执行
可运行修正版代码
%{ #define YYDEBUG 1 #include <stdio.h> #include <string.h> int yylex(void); void yyerror(char *); int line=0; %} %token INTEGER NEWLINE %% program: | program '!' expr '_' expr NEWLINE { printf("NUMERICAL EXPRESSION\n"); line++; } | program NEWLINE { line++; } ; expr: INTEGER { $$ = $1; } ; %% int yylex() { char c; // 不需要跳过空格、制表符的话可以删掉下面这行循环 while((c = getchar()) == ' ' || c == '\t'); if (c >= '0' && c <= '9') { int val = 0; while(c >= '0' && c <= '9' ){ val = val * 10 + (c - '0'); c = getchar(); } yylval = val; ungetc(c, stdin); // 把多读的非数字字符塞回输入流 return INTEGER; } if (c == '\n'){ return NEWLINE; } // 单独识别!和_,直接返回字符本身作为终结符 if (c == '!' || c == '_') { return c; } // 其他非法字符直接返回本身,触发语法报错 return c; } void yyerror(char *s) { fprintf(stderr, "Line %d: invalid input, %s\n", line+1, s); } int main(void) { yyparse(); return 0; }
运行效果
- 输入
!44_22回车,会正确输出NUMERICAL EXPRESSION - 输入
!123_456这类多位数组合也能正常识别 - 输入不符合格式的内容(比如
44_22、!4422、!_44)会直接抛出语法错误
内容的提问来源于stack exchange,提问作者martsi
相关产品推荐
相关产品推荐

