Lex/Yacc计算器无法处理特殊情况

vfhzx4xs  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(125)

我正在开发一个Lex+Yacc计算器,它能够执行基本的算术运算,并支持括号的使用。从我的测试来看,它基本上能够处理每一种情况,为有效输入提供整数解,并在提供无效输入时指示输入无效。
然而,在我的测试中,我发现如果我简单地输入:5)99+22+33)或任何以')'结尾的字符,它仍然被认为是有效的。事实上,我甚至可以输入“7)asdfghjk”,它仍然会认为它有效并输出7。看起来当结尾有一个单独的')'时,它并不在意。而如果我有(5,它就会出错。
我的Lex文件和Yacc文件在下面提供。任何帮助将不胜感激。非常感谢。

  • Lex文件:*
/* ========== DECLARATIONS SECTION ========== */
%{
    #include <stdio.h>
    #include <stdlib.h>
    #include "y.tab.h"
    extern int yylval;
%}
/* ========================================== */


/* ========== SHORTHAND DEFINITIONS ========= */
/* ========================================== */


/* ================== RULES ================= */
%%
([1-9][0-9]*|0) { 
    yylval = atoi(yytext);
    return INT;
}

[+] {return PLUS;}
[-] {return MINUS;}
[*] {return MULT;}
[/] {return DIV;}
[(] {return LPAREN;}
[)] {return RPAREN;}
[ \t] {;}
[\n] {return 0;}
. {yyerror();}
%%
/* ========================================== */


/* ================ USER CODE =============== */
int yywrap() {
    return 1;
}
/* ========================================== */
  • Yacc文件:*
/* ========== DECLARATIONS SECTION ========== */
%{
    #include <stdio.h>
    #include <stdlib.h>
%}

%token INT

%left PLUS MINUS
%left MULT DIV
%left UMINUS
%left LPAREN RPAREN
/* ========================================== */


/* ============ GRAMMAR SECTION ============= */
%%
ResultantExpression: E{
    printf("Result = %d\n", $$);

    return 0;
};

E: E PLUS T {$$ = $1 + $3;}
 | E MINUS T {$$ = $1 - $3;}
 | MINUS E %prec UMINUS {$$ = -$2;}
 | T {$$ = $1;}
 ;

T: T MULT F {$$ = $1 * $3;}
 | T DIV F {if ($3 == 0) {yyerror();} else {$$ = $1 / $3;}}
 | F {$$ = $1;}
 ;

F: INT {$$ = $1;}
 | LPAREN E RPAREN {$$ = ($2);}
 ; 
%%
/* ========================================== */


/* ============ USER CODE SECTION =========== */
int main() {
    printf("Enter the expression:\n");
    yyparse();

    return 0;
}

void yyerror() {
    printf("The entered expression is invalid!\n");
    exit(1);
}

/* ========================================== */
ia2d9nvy

ia2d9nvy1#

因为在ResultExpression操作中有一个return 0;,所以在识别出ResultExpression之后,即使有更多的输入,它也会成功退出。如果您想在此之后检查EOF是否正确,请删除return 0;并让它继续解析--如果输入中有任何垃圾,它会给予语法错误消息。或者如果有预期的换行符(词法分析器将其作为EOF返回),则成功返回。

相关问题