Reputation: 11
My yacc parser is showing syntax error even though the syntax is as per grammar. my Yacc code:
%{
void yyerror (char *s);
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int symbols[100];
int yylex();
int symbolVal(char symbol);
void updateSymbolVal(char symbol,int val);
%}
%union {int num; char id;}
%start line
%token WHILE
%token lt
%token gt
%token exit_command
%token <num> number
%token <id> identifier
%type <num> line exp term
%type <id> assignment
%type <num> condition
%%
line: assignment {;}
|line assignment {;}
|exit_command {exit(EXIT_SUCCESS);}
|line exit_command {exit(EXIT_SUCCESS);}
|whileLoop {;}
|condition {;}
;
whileLoop: WHILE '(' condition ')' '{' assignment '}' {printf("while loop condition var:%d\n",$3);}
;
assignment : identifier '=' exp {updateSymbolVal($1,$3);}
;
exp : term {$$ = $1;}
| exp '+' term {$$ = $1 + $3;}
| exp '-' term {$$ = $1 - $3;}
;
term : number {$$ = $1;}
| identifier {$$ = symbolVal($1);}
;
condition : identifier cond_op identifier {$$ = $1;}
|identifier cond_op number {$$ = $1;}
;
cond_op : lt
| gt
;
%%
int computeSymbolIndex(char token){
int idx = -1;
if(islower(token)){
idx = token - 'a' +26;
}
else if(isupper(token)){
idx = token - 'A' + 26;
}
return idx;
}
int symbolVal(char symbol){
int bucket = computeSymbolIndex(symbol);
return symbols[bucket];
}
void updateSymbolVal(char symbol, int val){
int bucket = computeSymbolIndex(symbol);
symbols[bucket] = val;
}
int main(void){
int i;
for(i=0;i<52;i++){
symbols[i] = 0;
}
return yyparse();
}
void yyerror (char *s){fprintf (stderr, "%s\n",s);}
My Lex code:
%{
#include "y.tab.h"
%}
%%
"while" {printf("while\n"); return WHILE;}
"exit" {return exit_command;}
[a-zA-Z] {yylval.id = yytext[0]; return identifier;}
[0-9]+ {yylval.num = atoi(yytext); return number;}
"<" {return lt;}
">" {return gt;}
[ \t\n] ;
[-+=;] {return yytext[0];}
. ;
%%
int yywrap (void)
{
return 1;
}
Example text on which a syntax error is shown:
while(i>0){i = i-1}
"while" gets printed as per lex but the next line of output is "Syntax Error".
Even the "while loop condition var" is not getting printed.
The syntax error is shown especially of the while loop.
All the other things like the condition statements assignments etc seem to work fine.
Why is this happening?
Upvotes: 0
Views: 421
Reputation: 241671
You have a lexer fallback rule which silently discards unrecognised characters:
. ;
That's really not a good idea, as you have just discovered. In this case, no other rule recognises (
or )
, so they are ignored by the above rule. Your parser, however, is expecting a parenthesis. It doesn't get one, so it reports a syntax error.
Better is the following fallback rule, which could replace the preceding rule:
/* [-+=;] {return yytext[0];} */ /* now redundant*/
. {return yytext[0];}
This accepts any character in the lexer. However, most characters are not used as character literals anywhere in the grammar, so they will be treated as invalid tokens by the parser, causing a syntax error.
You could get a more precise error message by writing the error in your lex fallback rule, but yhen you need to make sure that all vslid characters are recognised:
[-+=;(){}] {return yytext[0];}
. {return yytext[0];}
Personally, I'd add <>
to that list rather than having dedicated rules (and unnecessary token names.)
Upvotes: 3