Yacc 不接受有效输入
Yacc not accepting valid input
我正在使用 Bison/Flex 为类 C(C 的简化版本)语言创建编译器。我正在尝试实现数组,但 运行 遇到了问题,我找不到错误的来源。我已经坚持了几天,所以非常感谢任何帮助!
当前输出:
g[
illegal character in yacc
示例输入:
g[10]
这是 yacc 中处理数组的两行。
Factor : Arr {$$ = ;}; //doRval
Arr : Id '[' Expr ']' {$$ = getArr(, );};
完整的 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(); } ;
Declarations : Dec Declarations { };
Declarations : { };
Dec : ArrDec {arrDec(yytext);} {};
Dec : Int Ident {enterName(table, yytext); }';' {};
StmtSeq : Stmt StmtSeq {$$ = AppendSeq(, ); } ;
StmtSeq : {$$ = NULL;} ;
Stmt : Write Expr ';' {$$ = doPrint(); };
Stmt : Id '=' Expr ';' {$$ = doAssign(, );} ;
//Stmt : Arr '=' Expr ';' {$$ = doArrAssign(, );} ;
Stmt : FOR '(' Stmt Expr ';' Stmt ')' '{' StmtSeq '}' {$$ = doFor(, , , );};
Stmt : WHILE '(' Expr ')' '{' StmtSeq '}' {$$ = doWhile(, );};
Stmt : IF '(' Expr ')' '{' StmtSeq '}' {$$ = doIf(, );};
Stmt : IF '(' Expr ')' '{' StmtSeq '}' ELSE '{' StmtSeq '}' {$$ = doIfElse(, , );};
Stmt : Write '(' eList ')' ';' {$$ = doPrintExpList();};
Stmt : PrintLine '(' Expr ')' ';' {$$ = doPrintLine();};
Stmt : PrintSpaces '(' Expr ')' ';' {$$ = doPrintSpaces();};
Stmt : READ '(' vList ')' ';' {$$ = doRead();};
eList : Expr {$$ = addExpr(, NULL);};
eList : Expr ',' eList {$$ = addExpr(, );};
eList : {$$ = NULL;};
vList : Id {$$ = addId(, NULL);};
vList : Id ',' vList {$$ = addId(, );};
vList : {$$ = NULL;};
Expr : Expr EQ Expr {$$ = doEQ(, );};
Expr : Expr NEQ Term {$$ = doNEQ(, ); } ;
Expr : Expr LTE Term {$$ = doLTE(, ); } ;
Expr : Expr GTE Term {$$ = doGTE(, ); } ;
Expr : Expr '<' Term {$$ = doLess(, ); } ;
Expr : Expr '>' Term {$$ = doGreater(, ); } ;
Expr : Expr '^' Term {$$ = doExp(, ); } ;
Expr : Expr OR Term {$$ = doOr(, ); } ;
Expr : Expr '-' Term {$$ = doSub(, ); } ;
Expr : Expr '+' Term {$$ = doAdd(, ); } ;
Expr : Term {$$ = ; } ;
Term : Term AND Factor {$$ = doAnd(, ); } ;
Term : Term '%' Factor {$$ = doRemainder(, );} ;
Term : Term '/' Factor {$$ = doDiv(, ); } ;
Term : Term '*' Factor {$$ = doMult(, ); } ;
Term : Factor {$$ = ;};
Factor : '!' Factor {$$ = doNot();};
Factor : '-' Factor {$$ = doUnary();};
Factor : '(' Expr ')' {$$ = };
Factor : Arr {$$ = ;}; //doRval
Arr : Id '[' Expr ']' {$$ = getArr(, );};
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;
}
这是我的 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"); }
%%
该语法中没有任何内容允许语句以带下标的数组开头,因为您不允许语句是表达式,并且允许数组赋值的产生式已被注释掉。
//Stmt : Arr '=' Expr ';' {$$ = doArrAssign(, );} ;
因此 bison 报告语法错误,您的 yyerror
实现忽略了该错误,宁愿打印其自己的误导性错误消息。除非你知道自己在做什么,否则 yyerror
应该总是打印它给出的参数。 (请参阅 bison 手册中任意数量的简单 yyerror
实现示例。)
我正在使用 Bison/Flex 为类 C(C 的简化版本)语言创建编译器。我正在尝试实现数组,但 运行 遇到了问题,我找不到错误的来源。我已经坚持了几天,所以非常感谢任何帮助!
当前输出:
g[
illegal character in yacc
示例输入:
g[10]
这是 yacc 中处理数组的两行。
Factor : Arr {$$ = ;}; //doRval
Arr : Id '[' Expr ']' {$$ = getArr(, );};
完整的 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(); } ;
Declarations : Dec Declarations { };
Declarations : { };
Dec : ArrDec {arrDec(yytext);} {};
Dec : Int Ident {enterName(table, yytext); }';' {};
StmtSeq : Stmt StmtSeq {$$ = AppendSeq(, ); } ;
StmtSeq : {$$ = NULL;} ;
Stmt : Write Expr ';' {$$ = doPrint(); };
Stmt : Id '=' Expr ';' {$$ = doAssign(, );} ;
//Stmt : Arr '=' Expr ';' {$$ = doArrAssign(, );} ;
Stmt : FOR '(' Stmt Expr ';' Stmt ')' '{' StmtSeq '}' {$$ = doFor(, , , );};
Stmt : WHILE '(' Expr ')' '{' StmtSeq '}' {$$ = doWhile(, );};
Stmt : IF '(' Expr ')' '{' StmtSeq '}' {$$ = doIf(, );};
Stmt : IF '(' Expr ')' '{' StmtSeq '}' ELSE '{' StmtSeq '}' {$$ = doIfElse(, , );};
Stmt : Write '(' eList ')' ';' {$$ = doPrintExpList();};
Stmt : PrintLine '(' Expr ')' ';' {$$ = doPrintLine();};
Stmt : PrintSpaces '(' Expr ')' ';' {$$ = doPrintSpaces();};
Stmt : READ '(' vList ')' ';' {$$ = doRead();};
eList : Expr {$$ = addExpr(, NULL);};
eList : Expr ',' eList {$$ = addExpr(, );};
eList : {$$ = NULL;};
vList : Id {$$ = addId(, NULL);};
vList : Id ',' vList {$$ = addId(, );};
vList : {$$ = NULL;};
Expr : Expr EQ Expr {$$ = doEQ(, );};
Expr : Expr NEQ Term {$$ = doNEQ(, ); } ;
Expr : Expr LTE Term {$$ = doLTE(, ); } ;
Expr : Expr GTE Term {$$ = doGTE(, ); } ;
Expr : Expr '<' Term {$$ = doLess(, ); } ;
Expr : Expr '>' Term {$$ = doGreater(, ); } ;
Expr : Expr '^' Term {$$ = doExp(, ); } ;
Expr : Expr OR Term {$$ = doOr(, ); } ;
Expr : Expr '-' Term {$$ = doSub(, ); } ;
Expr : Expr '+' Term {$$ = doAdd(, ); } ;
Expr : Term {$$ = ; } ;
Term : Term AND Factor {$$ = doAnd(, ); } ;
Term : Term '%' Factor {$$ = doRemainder(, );} ;
Term : Term '/' Factor {$$ = doDiv(, ); } ;
Term : Term '*' Factor {$$ = doMult(, ); } ;
Term : Factor {$$ = ;};
Factor : '!' Factor {$$ = doNot();};
Factor : '-' Factor {$$ = doUnary();};
Factor : '(' Expr ')' {$$ = };
Factor : Arr {$$ = ;}; //doRval
Arr : Id '[' Expr ']' {$$ = getArr(, );};
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;
}
这是我的 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"); }
%%
该语法中没有任何内容允许语句以带下标的数组开头,因为您不允许语句是表达式,并且允许数组赋值的产生式已被注释掉。
//Stmt : Arr '=' Expr ';' {$$ = doArrAssign(, );} ;
因此 bison 报告语法错误,您的 yyerror
实现忽略了该错误,宁愿打印其自己的误导性错误消息。除非你知道自己在做什么,否则 yyerror
应该总是打印它给出的参数。 (请参阅 bison 手册中任意数量的简单 yyerror
实现示例。)