Hi everyone I'm trying to write a parser for this simple java simple file basically I want this parser to recognise and validate instuction blocks. Upon finding a correct instruction block, the validator would print a success message.
Input file:
{
a = b;
}
{
counter = counter- 1;
i = i + 1;
}
{
variable1 = i / j;
variable2 = i * j;
i++;
j--;
}
but no matter what I tried I always get syntax error
Bison parser.y code:
%{
#include <stdio.h>
%}
%union {
char * str;
}
%token IDENTIFIER
%token INT_LITERAL
%token STRING_LITERAL
%token PLUS PLUS_PLUS MINUS MINUS_MINUS EQUAL SEMICOLON
%%
program: block
| /* empty */
;
block: '{' statement_list '}'
;
statement_list: statement
| statement_list statement
;
statement: assignment_statement
| increment_statement
| decrement_statement
;
assignment_statement: IDENTIFIER EQUAL INT_LITERAL SEMICOLON
;
increment_statement: IDENTIFIER PLUS_PLUS SEMICOLON
;
decrement_statement: IDENTIFIER MINUS_MINUS SEMICOLON
;
%%
int yyerror (char *s) {
fprintf (stderr, "%s\n", s);
}
int main() {
yyparse();
return 0;
}
Flex parserlex.l code:
%{
#include "parser.tab.h"
%}
%%
"{" { return '{'; }
"}" { return '}'; }
"=" { return EQUAL; }
";" { return SEMICOLON; }
"++" { return PLUS_PLUS; }
"--" { return MINUS_MINUS; }
[ \t\n\r]+ ; // Ignore white spaces
[a-zA-Z_][a-zA-Z0-9_]* { yylval.str = strdup(yytext); return IDENTIFIER; }
[0-9]+ { yylval.str = strdup(yytext); return INT_LITERAL; }
. { fprintf(stderr, "Unrecognized token: %s\n", yytext); return 0; }
%%
int yywrap() {
return 1;
}
I don't know what is wrong and since the only error message I get is "syntax error" I don't even know where to start looking for potential solutions. I also tried to use bison -v and reading bison.output file but it didn't got me much. Any help would be greatly appreciated
Some obvious limitations of your grammar:
Your assignment_statement rule only accepts IDENTIFIER EQUAL INT_LITERAL
so anything other than a constant on the rhs (such as a = b;
-- the second line in your input) will give a syntax error
Your top-level program only accepts a single block so it would give a syntax error on seeing a second block (if it ever got that far).
To help tracing your program, you can enable tracing code (by using the -t
argument to bison) and turn it on by setting yydebug = 1
before calling yyparse()
. I prefer putting something like
if (getennv('YYDEBUG')) yydebug = 1;
in the beginning of main and always using -t
(or %define parse.trace
near the top of the .y file -- same effect). That way it will print a trace if you set YYDEBUG
in your environment before running your program.