In the code down below, although I added \t as a token, with a priority higher than the digits, still when I test it, it accepts -2- 2 (with a single whitespace after the -) and -2 - 2 (with 2 whitespaces surrounding the -) but it does not accept -2-2 (with no whitespaces). Is there a solution for this particular situation?
What I'm aiming for is that when i give it an input such as -2-2-2 or 2*3/6-1 it works fine and does not output 'syntax error'.
lexical.l
/* recognize tokens for the calculator and print them out */
/*"--"[0-9]+ { yytext++; yylval = atoi(yytext); return NUMBER; }*/
%{
#include"syntax.tab.h"
%}
%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|" { return ABS; }
[ \t] { /* ignore whitespace */ }
(-|"")[0-9]+ { yylval = atoi(yytext); return NUMBER; }
\n { return EOL; }
. { printf("Mystery character %c\n", *yytext); }
%%
syntax.y
/* simplest version of calculator */
%{
#include <stdio.h>
%}
/* declare tokens */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL
%%
calclist: /* nothing */
| calclist exp EOL { printf("= %d\n", $2); }
;
exp: factor
| exp ADD factor { $$ = $1 + $3; }
| exp SUB factor { $$ = $1 - $3; }
;
factor: term
| factor MUL term { $$ = $1 * $3; }
| factor DIV term { $$ = $1 / $3; }
;
term: NUMBER
| ABS term { if ($2 < 0) $$ = -$2; else $$ = $2; }
;
%%
main(int argc, char **argv)
{
yyparse();
}
yyerror(char *s)
{
fprintf(stderr, "error: %s\n", s);
}`
-2-2is interpreted by the lexer as-2-2, not as-2-2. Lexer always looks for the longest match so it will always prefer to treat a minus and a number as a single token.Your parser doesn't have a rule that accept two consecutive numbers so it shows an error. (You should learn to turn on debug output in the lexer and the parser. It is very helpful in such cases.)
To fix the problem, you need to remove
-as part of a number in the lexer. Having it baked into a number is very common mistake that leads to exactly such problems as you encountered. Instead, you can define unary-operator in the parser.(Btw.,
(-|"")can be written as-?.)