I'm working on a Lex Yacc calculator that is capable of performing basic arithmetic operations, as well as supporting usage of parentheses. From my testing, it is capable of handling essentially every scenario, providing an integer solution for valid inputs, and indicating an input was invalid if invalid input is provided.
However, in my testing I found that if I simply type in: 5) or 99 22 33) or basically anything where ')' is the final character, it'll still be deemed valid. In fact, I could even type in "7)asdfghjk", and it would deem it valid and still output 7. It seems like when there is a lone ')' at the end it does not care. Whereas if I had (5 it would error out.
My Lex file and Yacc file are provided below. Any help would be greatly appreciated. Thank you so much.
Lex File:
/* ========== 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 File:
/* ========== 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);
}
/* ========================================== */
CodePudding user response:
Because you have a return 0;
in your ResultExpression
action, it will exit successfully after recognizing a ResultExpression, even if there is more input. If you want to check for a correct EOF after that, remove the return 0;
and let it continue parsing -- it will give a syntax error message if there's any garbage left in the input, or return successfully if there is the expected newline (which your lexer returns as EOF).