I'm writing a parser in Bison for a basic compiler (and then expand it to contain subroutines and dynamic memory allocation). The grammar is defined in Appendix A of the dragon book. My Flex scanner works--I ran my test files through it and it printed out all the correct tokens it found. Sorry about the strange formatting below. My bison and flex modes in emacs are a little haywire so I'm just using C mode until I fix.
%{
#include <stdio.h>
#define YYERROR_VERBOSE 1066
extern FILE* yyin ;
extern int yylineno ;
extern char* yytext ;
extern int yylex() ;
extern void yyerror() ;
int YYDEBUG = 1 ;
%}
/* Tokens */
%token AND BASIC BREAK DO ELSE EQ FALSE
%token GREQ ID IF INDEX LEEQ MINUS NOEQ NUM OR REAL TEMP TRUE WHILE
/* Grammar rules from Appendix A */
%%
program: block { printf( "Matched program\n" ) ; }
;
block: '{' decls stmts '}' { printf( " Matched block\n" ) ; }
;
decls: decls decl |
;
decl: type ID ';'
;
type: type '[' NUM ']' | BASIC
;
stmts: stmts stmt |
;
stmt: loc '=' bool ';'
| IF '(' bool ')' stmt
| IF '(' bool ')' stmt ELSE stmt
| WHILE '(' bool ')' stmt
| DO stmt WHILE '(' bool ')' ';'
| BREAK ';'
| block
;
loc: loc '[' bool ']' | ID
;
bool: bool OR join | join
;
join: join AND equality | equality
;
equality: equality EQ rel | equality NOEQ rel | rel
;
rel: expr '<' expr | expr LEEQ expr | expr GREQ expr | expr '>' expr | expr
;
expr: expr '+' term | expr '-' term | term
;
term: term '*' unary | term '/' unary | unary
;
unary: '!' unary | '-' unary | factor
;
factor: '(' bool ')' | loc | NUM | REAL | TRUE | FALSE
;
%%
/*
* Additional C Code
* Main Routine
* yyerror()
*/
int main( int argc, char *argv[] ) {
int i ;
if ( argc < 2 ) {
fprintf( stderr, "No input files.\n\n" ) ;
return 1 ;
}
for ( i = 0 ; i < argc ; i++ ) {
yyin = fopen( argv[i], "r" ) ;
if ( !yyin ) {
fprintf( stderr, "Error opening file: %s.\n\n", argv[i] ) ;
return 1 ;
}
yyparse() ;
}
return 0 ;
}
void yyerror( char *s ) {
/* fprintf( stderr, "Error parsing - %d: %s at %s\n", yylineno, s, yytext ) ; */
fprintf( stderr, "Error parsing - %d: %s at %s\n", yylineno, s, yytext ) ;
}
I feel like I might be missing something important. I don't think it's the rules. I set yyin to be the input files provided in argv[]. The errors are
Error parsing - 1: syntax error, unexpected TRUE, expecting '{' at
Error parsing - 1: syntax error, unexpected FALSE, expecting '{' at ELF
Any help would be greatly appreciated!
EDIT: If I change the main function to not set yyin (so yyparse just reads from stdin), I get this:
{ int x; }
Error parsing - 1: syntax error, unexpected TRUE, expecting '{' at {
I don't understand how that is wrong...