分析yacc中的赋值语句时出现语法错误

分析yacc中的赋值语句时出现语法错误,c,yacc,lex,C,Yacc,Lex,[注意家庭作业] 当我试图运行测试用例时,我需要一个提示来解释为什么以下代码失败:inta=3所有代码编译时都没有警告或错误,就我所知,结构是正确的。我觉得赋值规则中肯定有问题 错误消息显示:错误:第1行符号“a”处的语法错误 这是.lex文件: %{ #include "calc.h" #include "symbol-table.h" #include "tok.h" int yyerror(char *s); int yylinenum = 1; %} digit [0-

[注意家庭作业]

当我试图运行测试用例时,我需要一个提示来解释为什么以下代码失败:
inta=3所有代码编译时都没有警告或错误,就我所知,结构是正确的。我觉得
赋值规则中肯定有问题

错误消息显示:
错误:第1行符号“a”处的语法错误

这是.lex文件:

%{

#include "calc.h"
#include "symbol-table.h"
#include "tok.h"
int yyerror(char *s);
int yylinenum = 1;
%}

digit        [0-9]
int_const    {digit}+
float_const  {digit}+[.]{digit}+
id           [a-zA-Z]+[a-zA-Z0-9]*

%%

{int_const}    { yylval.int_val = atoi(yytext); return INTEGER_LITERAL; }
{float_const}  { yylval.float_val = atof(yytext); return FLOAT_LITERAL; }
"="            { yylval.str_val = strdupclean(yylval.str_val, yytext); return EQUALS; }
"+"            { yylval.str_val = strdupclean(yylval.str_val, yytext); return PLUS; }
"*"            { yylval.str_val = strdupclean(yylval.str_val, yytext); return MULT; }
"-"            { yylval.str_val = strdupclean(yylval.str_val, yytext); return MINUS; }
"/"            { yylval.str_val = strdupclean(yylval.str_val, yytext); return DIV; }
"("            { yylval.str_val = strdupclean(yylval.str_val, yytext); return OPAREN; }
")"            { yylval.str_val = strdupclean(yylval.str_val, yytext); return CPAREN; }
";"            { yylval.str_val = strdupclean(yylval.str_val, yytext); return SEMIC; }
"sqrt"         { yylval.str_val = strdupclean(yylval.str_val, yytext); return SQRT; }
{id}           { yylval.str_val = strdupclean(yylval.str_val, yytext); 
                 /*HINT: One way to simplify parsing is to have lex return what
                  * type of variable we have.  IVAR = int, FVAR = float
                  * UVAR = unknown var.
                  * Naturally, you may use your own solution.
                  */
              if (strcmp(yylval.str_val, "int")) {return IVAR;}
              else if (strcmp(yylval.str_val, "float")) {return FVAR;}
                  else {return UVAR;} 
               }

[ \t]*         {}
[\n]           { yylinenum++;    }

.              { yyerror("Unknown Symbol"); exit(1); }
%%
这是yacc文件:

%{
#include "calc.h"
#include "symbol-table.h"
int yyerror(char *s);
int yylex(void);
%}

%union{
int         int_val;
float       float_val;
char*       str_val;
}

%start input

%token <int_val>   INTEGER_LITERAL
%token <float_val> FLOAT_LITERAL
%token <float_val> SQRT
%token OPAREN CPAREN SEMIC IVAR FVAR UVAR
%type  <int_val>   int_exp
%type  <float_val> float_exp
%type  <str_val>  IVAR FVAR UVAR
%right EQUALS /*right associative, everything on the right side of the = should be evaluated and stored*/
%left  PLUS MINUS/*The order matters, by listing PLUS/MIUS first and then MULT/DIV we are */
%left  MULT DIV /*telling yacc to evaluate MULTs & DIVs before PLUSes and MINUSes*/

%%

input:           /*empty*/
            | int_exp                   { printf("Result %d\n", $1); }
            | float_exp                 { printf("Result %f\n", $1); }
            | assignment                { printf("Result \n"); }
            ;

int_exp:          INTEGER_LITERAL           { $$ = $1; }
            | int_exp PLUS int_exp      { $$ = $1 + $3; }
            | int_exp MULT int_exp      { $$ = $1 * $3; }
            | int_exp MINUS int_exp     { $$ = $1 - $3; }
            | int_exp DIV int_exp       { $$ = $1 / $3; }
            | OPAREN int_exp CPAREN     { $$ = $2; }
            ;

float_exp:        FLOAT_LITERAL             { $$ = $1; }
            | float_exp PLUS float_exp  { $$ = $1 + $3; }
            | float_exp MULT float_exp  { $$ = $1 * $3; }
            | float_exp MINUS float_exp { $$ = $1 - $3; }
            | float_exp DIV float_exp   { $$ = $1 / $3; }
            | int_exp PLUS float_exp    { $$ = (float)$1 + $3; }
            | int_exp MULT float_exp    { $$ = (float)$1 * $3; }
            | int_exp MINUS float_exp   { $$ = (float)$1 - $3; }
            | int_exp DIV float_exp     { $$ = (float)$1 / $3; }
            | float_exp PLUS int_exp    { $$ = (float)$1 + $3; }
            | float_exp MULT int_exp    { $$ = (float)$1 * $3; }
            | float_exp MINUS int_exp   { $$ = (float)$1 - $3; }
            | float_exp DIV int_exp     { $$ = (float)$1 / $3; }
            | OPAREN float_exp CPAREN   { $$ = $2; }
            | SQRT OPAREN float_exp CPAREN  { $$ = sqrt((double)$3); }
            | SQRT OPAREN int_exp CPAREN    { $$ = sqrt((double)$3); }
            ;

assignment:       UVAR EQUALS float_exp SEMIC           { //if UVAR exists and is float, update value
                                          //if UVAR doesn't exist, error: unknown type
                                          symbol_table_node *n1 = symbol_table_find( $1, *st);
                                          if(n1) { 
                                            if(n1->type == FLOAT_TYPE) {
                                                n1->val.float_val = $3;
                                            } else {
                                                //error
                                            }
                                            //error, variable not defined
                                          //if UVAR is not float, error: illegal assignment
                                          }
                                        }
            | UVAR EQUALS int_exp SEMIC         { 
                                          symbol_table_node *n1 = symbol_table_find( $1, *st);
                                          if(n1) { 
                                            if(n1->type == INT_TYPE) {
                                                n1->val.int_val = $3;
                                            } else {
                                                //error
                                            }
                                          }
                                        }
            | IVAR UVAR EQUALS int_exp SEMIC { //UVAR should not be in symbol table
                                          if(symbol_table_find($2, *st)) {
                                            //error
                                          } else {
                                            //how to handle errors?
                                            symbol_table_add_i($2, $4, *st);
                                          }
                                        }
            | FVAR UVAR EQUALS float_exp SEMIC { 
                                          if(symbol_table_find($2, *st)) {

                                          } else {
                                            symbol_table_add_f($2, $4, *st);
                                          }
                                        }
            ;

%%

int yyerror(char *s){
extern int yylinenum; /* defined and maintained in lex.c*/
extern char *yytext;  /* defined and maintained in lex.c*/

printf("ERROR: %s at symbol \"%s\" on line %d\n", s, yytext, yylinenum);
return -1;
}
%{
#包括“calc.h”
#包括“符号表h”
int yyerror(字符*s);
int yylex(无效);
%}
%联合{
国际价值;
浮动值;
char*struval;
}
%开始输入
%令牌整数
%令牌浮点数
%令牌SQRT
%象征性蛋白石半IVAR FVAR UVAR
%类型int\u exp
%类型float\u exp
%IVAR-FVAR-UVAR型
%right EQUALS/*right associative,应计算并存储=右侧的所有内容*/
%左加减/*顺序很重要,首先列出PLUS/MIUS,然后列出MULT/DIV*/
%左MULT DIV/*告诉yacc在加和减之前评估MULT和DIV*/
%%
输入:/*空*/
|int_exp{printf(“结果%d\n”,$1);}
|float_exp{printf(“结果%f\n”,$1);}
|赋值{printf(“Result\n”);}
;
int\u exp:INTEGER\u LITERAL{$$=$1;}
|int_exp加int_exp{$$=$1+$3;}
|int_exp MULT int_exp{$$=$1*$3;}
|int_exp减去int_exp{$$=$1-$3;}
|int_exp DIV int_exp{$$=$1/$3;}
|OPAREN int_exp CPAREN{$$=$2;}
;
float_exp:float_LITERAL{$$=$1;}
|浮点数加浮点数{$$=$1+$3;}
|float\u exp MULT float\u exp{$$=$1*$3;}
|float_exp减去float_exp{$$=$1-$3;}
|float_exp DIV float_exp{$$=$1/$3;}
|int\u exp加浮点\u exp{$$=(浮点)$1+$3;}
|int_exp MULT float_exp{$$=(float)$1*$3;}
|int_exp减去float_exp{$$=(float)$1-$3;}
|int_exp DIV float_exp{$$=(float)$1/$3;}
|float_exp加int_exp{$$=(float)$1+$3;}
|float_exp MULT int_exp{$$=(float)$1*$3;}
|float_exp减去int_exp{$$=(float)$1-$3;}
|float_exp DIV int_exp{$$=(float)$1/$3;}
|OPAREN float_exp CPAREN{$$=$2;}
|SQRT OPAREN float_exp CPAREN{$$=SQRT((双)$3);}
|SQRT OPAREN int_exp CPAREN{$=SQRT((双)$3);}
;
赋值:UVAR等于float_exp semi{//如果UVAR存在并且是float,则更新值
//如果UVAR不存在,错误:未知类型
symbol_table_node*n1=symbol_table_find($1,*st);
如果(n1){
如果(n1->type==浮点型){
n1->val.float_val=$3;
}否则{
//错误
}
//错误,未定义变量
//如果UVAR不是浮点,则错误:非法赋值
}
}
|UVAR等于int_exp半{
symbol_table_node*n1=symbol_table_find($1,*st);
如果(n1){
如果(n1->type==INT\u type){
n1->val.int_val=$3;
}否则{
//错误
}
}
}
|IVAR UVAR EQUALS int_exp semi{//UVAR不应在符号表中
如果(符号表查找($2,*st)){
//错误
}否则{
//如何处理错误?
symbol_table_add_i($2,$4,*st);
}
}
|FVAR UVAR等于float_exp semi{
如果(符号表查找($2,*st)){
}否则{
symbol_table_add_f($2,$4,*st);
}
}
;
%%
int yyerror(字符*s){
extern int yylinenum;/*在lex.c中定义和维护*/
外部字符*yytext;/*在lex.c中定义和维护*/
printf(“第%d\n行的符号\%s\,s,yytext,yylinenum上的错误:%s”);
返回-1;
}

这个错误非常简单:

if (strcmp(yylval.str_val, "int"))
不会做你认为它会做的事<如果两个字符串相等,则code>strcmp
返回
0
;如果第一个字符串按字典顺序较早,则返回负值;如果第一个字符串按字典顺序较晚,则返回正值。用作布尔值,这意味着如果字符串比较相等,
strcmp
false
,否则为
true
。因此,令牌
int
不会生成令牌值
IVAL

但我不认为你真的想这么做。讲师关于让lexer返回与已知da对应的令牌类型的提示
int b = 0;
int a = b + 3;