编写YACC规则识别C语言注释遇语法错误,求解决方法
解决C语言注释的Lex/YACC识别问题
一、核心问题分析
Lex正则表达式错误
- 单行注释:
[//]([^"])* [\n]写法逻辑错误:[//]字符组仅匹配单个/,应直接写//;[^"]错误限制注释不能包含双引号,C语言单行注释允许包含任意字符直到换行,需改为[^\n]*;- 换行符无需放在字符组,直接写
\n即可,多余空格会导致匹配异常。
- 多行注释:
[/*]([^"])*[*/]完全不符合规则:[/*]字符组仅匹配单个/或*,无法识别/*起始标记,应直接写/*;[^"]会在遇到双引号时终止匹配,不符合多行注释的语法;- 未处理中间包含
*但不是*/的情况,比如/* abc * def */会匹配失败。
- 单行注释:
YACC规则与Lex Token不匹配/上下文缺失
- Lex中定义的模式返回的Token名称需与YACC中使用的完全一致(大小写敏感);
- YACC的起始符号规则必须包含
comentario非终结符,否则YACC无法识别注释输入。
二、修正后的代码示例
1. Lex文件(lex.l)
%{ #include "y.tab.h" #include <stdio.h> %} %% //[^\n]*\n { yylineno++; return COMENTARIO; } \/\*([^*]|\*+[^/*])*\*+\/ { return COMENTARIMULTILINEA; } .|\n { yylineno++; /* 忽略其他字符或更新行号 */ } %% int yywrap() { return 1; }
2. YACC文件(yacc.y)
%{ #include <stdio.h> int yylineno; %} %token COMENTARIO COMENTARIMULTILINEA %% program: /* 空规则,允许空输入 */ | program comentario ; comentario: COMENTARIO | COMENTARIMULTILINEA ; %% int yyerror(char *s) { fprintf(stderr, "语法错误 en la línea %d\n", yylineno); return 0; } int main() { yyparse(); return 0; }
三、编译与运行步骤
- 生成中间文件:
lex lex.l yacc -d yacc.y - 编译可执行文件:
gcc lex.yy.c y.tab.c -o comentarios - 测试运行:
输入C语言单行或多行注释,按./comentariosCtrl+D结束输入,无错误则正常退出。
内容的提问来源于stack exchange,提问作者Péritas
相关产品推荐
相关产品推荐

