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 实现示例。)