Lex与Yacc交互式输入EOF等待问题:输入回车无响应如何修复
Lex/Yacc计算器回车无响应问题分析与修复
问题原因
- Lex默认会累积输入直到遇到**EOF(文件结束符)**才把所有token传递给Yacc解析。普通回车只是换行符,不会触发EOF,所以Yacc会一直等待更多输入,直到你用
Ctrl+Z(Windows)或Ctrl+D(Linux/Unix)手动触发EOF,才会执行解析并输出结果。 - 你的语法规则(calc.y)没有定义表达式结束的触发条件——没有把换行符作为当前表达式完成的标记,导致Yacc无法判断何时开始解析。
修复方法
1. 修改Lex文件(calc.l),识别换行符为独立token
在Lex的规则中添加换行符的处理,将其定义为NEWLINEtoken,这样每次回车时,Lex会立即把这个token传给Yacc:
%{ #include "calc.tab.h" %} %% [0-9]+ { yylval = atoi(yytext); return NUMBER; } "+" { return PLUS; } "-" { return MINUS; } "*" { return MUL; } "/" { return DIV; } "\n" { return NEWLINE; } // 新增:把换行符转为NEWLINE token [ \t] ; // 忽略空格、制表符 . { printf("Invalid character\n"); } %% int yywrap() { return 1; }
2. 修改Yacc文件(calc.y),添加换行触发的解析规则
在Yacc的语法规则中,让表达式跟随换行符,并在匹配到expr NEWLINE时立即执行处理动作(比如输出验证信息或计算结果):
%{ #include <stdio.h> %} %token NUMBER NEWLINE %token PLUS MINUS MUL DIV %% program: | program expr NEWLINE { printf("Valid.\n"); // 可选:输出计算结果 // printf("Result: %d\n", $2); } ; expr: NUMBER { $$ = $1; } | expr PLUS expr { $$ = $1 + $3; } | expr MINUS expr { $$ = $1 - $3; } | expr MUL expr { $$ = $1 * $3; } | expr DIV expr { $$ = $1 / $3; } ; %% int main() { yyparse(); return 0; } void yyerror(const char *s) { printf("Error: %s\n", s); }
核心逻辑说明
NEWLINEtoken告诉Yacc:当前输入的表达式已完整,可以立即解析,无需等待EOF。program规则中的expr NEWLINE分支会在每次回车时触发动作,直接输出结果或验证信息,解决回车无响应的问题。
内容的提问来源于stack exchange,提问作者user27828776
相关产品推荐
相关产品推荐

