Reputation: 33
I am using Bison/Flex to create a compiler for a C-like (simplified version of C) language. I am trying to implement arrays and I am running into an issue and I can not find the source of the error. I have been stuck on this for a couple days so any help would be greatly appreciated!
Current output:
g[
illegal character in yacc
Sample Input:
g[10]
These are the two lines in the yacc that deal with the array.
Factor : Arr {$$ = $1;}; //doRval
Arr : Id '[' Expr ']' {$$ = getArr($1, $3);};
Full yac:
extern int yylex(); /* The next token function. */
extern char *yytext; /* The matched token text. */
extern int yyleng; /* The token text length. */
extern int yyparse();
extern int yyerror(char *);
void dumpTable();
extern SymTab *table;
%}
%union {
long val;
char * string;
struct ExprRes * ExprRes;
struct InstrSeq * InstrSeq;
struct BExprRes * BExprRes;
struct IdList * vL;
struct ExprResList * eL;
}
%type <string> Id
%type <ExprRes> Factor
%type <ExprRes> Arr
%type <ExprRes> Term
%type <ExprRes> Expr
%type <InstrSeq> StmtSeq
%type <InstrSeq> Stmt
%type <vL> vList
%type <eL> eList
%token Ident
%token ArrDec
%token IntLit
%token Int
%token Write
%token IF
%token WHILE
%token FOR
%token ELSE
%token EQ
%token AND
%token OR
%token LTE
%token GTE
%token NEQ
%token READ
%token PrintLine
%token PrintSpaces
%%
Prog : Declarations StmtSeq {Finish($2); } ;
Declarations : Dec Declarations { };
Declarations : { };
Dec : ArrDec {arrDec(yytext);} {};
Dec : Int Ident {enterName(table, yytext); }';' {};
StmtSeq : Stmt StmtSeq {$$ = AppendSeq($1, $2); } ;
StmtSeq : {$$ = NULL;} ;
Stmt : Write Expr ';' {$$ = doPrint($2); };
Stmt : Id '=' Expr ';' {$$ = doAssign($1, $3);} ;
//Stmt : Arr '=' Expr ';' {$$ = doArrAssign($1, $3);} ;
Stmt : FOR '(' Stmt Expr ';' Stmt ')' '{' StmtSeq '}' {$$ = doFor($3, $4, $6, $9);};
Stmt : WHILE '(' Expr ')' '{' StmtSeq '}' {$$ = doWhile($3, $6);};
Stmt : IF '(' Expr ')' '{' StmtSeq '}' {$$ = doIf($3, $6);};
Stmt : IF '(' Expr ')' '{' StmtSeq '}' ELSE '{' StmtSeq '}' {$$ = doIfElse($3, $6, $10);};
Stmt : Write '(' eList ')' ';' {$$ = doPrintExpList($3);};
Stmt : PrintLine '(' Expr ')' ';' {$$ = doPrintLine($3);};
Stmt : PrintSpaces '(' Expr ')' ';' {$$ = doPrintSpaces($3);};
Stmt : READ '(' vList ')' ';' {$$ = doRead($3);};
eList : Expr {$$ = addExpr($1, NULL);};
eList : Expr ',' eList {$$ = addExpr($1, $3);};
eList : {$$ = NULL;};
vList : Id {$$ = addId($1, NULL);};
vList : Id ',' vList {$$ = addId($1, $3);};
vList : {$$ = NULL;};
Expr : Expr EQ Expr {$$ = doEQ($1, $3);};
Expr : Expr NEQ Term {$$ = doNEQ($1, $3); } ;
Expr : Expr LTE Term {$$ = doLTE($1, $3); } ;
Expr : Expr GTE Term {$$ = doGTE($1, $3); } ;
Expr : Expr '<' Term {$$ = doLess($1, $3); } ;
Expr : Expr '>' Term {$$ = doGreater($1, $3); } ;
Expr : Expr '^' Term {$$ = doExp($1, $3); } ;
Expr : Expr OR Term {$$ = doOr($1, $3); } ;
Expr : Expr '-' Term {$$ = doSub($1, $3); } ;
Expr : Expr '+' Term {$$ = doAdd($1, $3); } ;
Expr : Term {$$ = $1; } ;
Term : Term AND Factor {$$ = doAnd($1, $3); } ;
Term : Term '%' Factor {$$ = doRemainder($1, $3);} ;
Term : Term '/' Factor {$$ = doDiv($1, $3); } ;
Term : Term '*' Factor {$$ = doMult($1, $3); } ;
Term : Factor {$$ = $1;};
Factor : '!' Factor {$$ = doNot($2);};
Factor : '-' Factor {$$ = doUnary($2);};
Factor : '(' Expr ')' {$$ = $2};
Factor : Arr {$$ = $1;}; //doRval
Arr : Id '[' Expr ']' {$$ = getArr($1, $3);};
Factor : IntLit {$$ = doIntLit(yytext); };
Factor : Id {$$ = doRval(yytext); };
Id : Ident {$$ = strdup(yytext);};
%%
int yyerror(char *s) {
writeIndicator(getCurrentColumnNum());
writeMessage("illegal character in yacc");
return 1;
}
here is my lex:
letter [A-Za-z]
digit [0-9]
%%
if {return IF; }
else {return ELSE;}
while {return WHILE;}
for {return FOR;}
int {return Int;}
print {return Write;}
read {return READ;}
printlines {return PrintLine;}
printspaces {return PrintSpaces;};
"int "{letter}({letter}|{digit})*\[{digit}+\]\; {return ArrDec;}
{letter}({letter}|{digit})* {return Ident;}
\, {return ',';}
{digit}{digit}* {return IntLit; }
\[ {return '[';}
\] {return ']';}
\=\= {return EQ; }
\!\= {return NEQ; }
\= {return '='; }
\+ {return '+'; }
\^ {return '^'; }
\- {return '-'; }
\< {return '<'; }
\> {return '>'; }
\<\= {return LTE; }
\>\= {return GTE; }
\! {return '!'; }
&& {return AND;}
\|\| {return OR;}
\* {return '*'; }
\; {return ';'; }
\{ {return '{'; }
\} {return '}'; }
\( { return '('; }
\) { return ')'; }
\% { return '%'; }
\/ { return '/'; }
[ ] {}
\t {}
\r {}
\n {}
. {writeIndicator(getCurrentColumnNum()); writeMessage("Illegal Character in lex"); }
%%
Upvotes: 0
Views: 212
Reputation: 241861
Nothing in that grammar allows a statement to start with a subscripted array, since you don't allow statements to be expressions, and the production which would have allowed array assignment has been commented out.
//Stmt : Arr '=' Expr ';' {$$ = doArrAssign($1, $3);} ;
So bison reports a syntax error, which your yyerror
implementation ignores, preferring to print its own misleading error message. Unless you know what you're doing, yyerror
should always print the argument it's given. (See any number of examples of simple yyerror
implementations throughout the bison manual.)
Upvotes: 4