C 在'之前的预期表达式=';代币

C 在'之前的预期表达式=';代币,c,bison,yacc,lex,C,Bison,Yacc,Lex,我想做一个解析器,它将表达式打印成计算步骤。当我编译代码时,我无法解决这些问题。我总是犯错误 code.l:13:1: error: expected expression before '=' token yylval.name = strdup(yytext); ^ code.l:18:1: error: expected expression before '=' token yylval.name = strdup(yytext); ^ 我尝试了很多不同的事情,我认为这是

我想做一个解析器,它将表达式打印成计算步骤。当我编译代码时,我无法解决这些问题。我总是犯错误

code.l:13:1: error: expected expression before '=' token
  yylval.name = strdup(yytext);
 ^
code.l:18:1: error: expected expression before '=' token
  yylval.name = strdup(yytext);

 ^
我尝试了很多不同的事情,我认为这是一个问题,但没有成功

代码1

%{
#包括
#包括
#包括“分配表h”
%}
%%
" " ;
“\t”;
[a-zA-Z]+
{
yylval.name=strdup(yytext);
返回(ID);
}
[0-9]+
{
yylval.name=strdup(yytext);
返回(NUM);
}
[-+=()*/\n]
{
返回文本[0];
}
.
{
yyerror(“未知字符”);
}
%%
代码y

%{
#包括
内部温度=0;
%}
%起始列表
%联合
{
字符*名称;
}
%令牌ID
%令牌数
%类型列表statexpr
%左'+''-'
%左'*''/'
%左耳门
%%
名单:
|
列出统计数据'\n'
|
列表错误'\n'
{
耶罗克;
}
;
斯达:
expr
{
printf(“stat:t=(%s)\n:stat“,$1);
}
|
ID“=”表达式
{
printf(“统计:(%s)=(%s):统计“,$1,$3);
}
;
表达式:
“('expr')”
{
$$ = $2;
}
|
expr'*'expr
{
printf(“t=(%s)*(%s)”,$1,$3);
$$=“t”;
}
|
expr'/'expr
{
printf(“t=(%s)/(%s)”,$1,$3);
$$=“t”;
}
|
expr'+'expr
{
printf(“t=(%s)+(%s)”,$1,$3);
$$=“t”;
}
|
expr'-'expr
{
printf(“t=(%s)-(%s)”,$1,$3);
$$=“t”;
}
|
“-”前白蛋白的百分比
{
printf(“t=-(%s)”,2美元);
$$=“t”;
}
|
身份证件
{
$$ = $1;
}
|
全国矿工联盟
{
$$ = $1;
}
;
%%
main()
{
返回(yyparse());
}
YY错误
char*s;
{
fprintf(标准字符,“%s\n”,s);
}
yywrap()
{
申报表(1);
}
我不需要我的最终项目的解决方案,我只需要找到是什么导致了错误。任何想法都是有用的

编辑: Assignment.tab.h文件


#如果不包括YY_YY_分配选项卡
#定义YY_YY_分配_选项卡_H_包括在内
/*启用跟踪*/
#ifndef YYDEBUG
#定义调试0
#恩迪夫
#如果YYDEBUG
外部调试;
#恩迪夫
/*代币*/
#ifndef类型
#定义标记类型
/*将令牌放入符号表中,以便GDB和其他调试器
了解他们*/
枚举类型{
ID=258,
NUM=259,
乌米努斯=260
};
#恩迪夫
#如果!定义YYSTYPE&!已定义的YYSTYPE_已声明
typedef联合类型
{
/*yacc.c第2058行*/
#第10行“任务.y”
字符*名称;
/*yacc.c第2058行*/
#第67行“分配表h”
}YYSTYPE;
#定义YYSTYPE_是_平凡的1
#定义yystype yystype/*过时;将被撤回*/
#定义YYSTYPE_是否声明为1
#恩迪夫
外部的YYSTYPE yylval;
#ifdef YYPARSE_参数
#如果已定义uu STDC u| |已定义uu cplusplus
int-yyparse(void*yyparse_参数);
#否则
int-yyparse();
#恩迪夫
#否则/*!YYU参数*/
#如果已定义uu STDC u| |已定义uu cplusplus
int(void);
#否则
int-yyparse();
#恩迪夫
#endif/*!YYU参数*/
#endif/*!YY_YY_分配_选项卡_H_包括在内*/

lex规则中的操作必须与模式在同一行开始。比如说,你需要写作

[a-zA-Z]+  {
    yylval.name = strdup(yytext);
    return(ID);
    }
对于其价值,该要求在以下文件中明确说明:

flex输入的rules部分包含一系列表单规则:

pattern   action
其中,模式必须是非缩进的,并且操作必须在同一行上开始


据我所知,这一限制存在于所有的lex实现中,尽管结果有所不同。我引用Flex手册是因为我发现它比Posix描述更具可读性,而且它还描述了许多有用的Flex专用功能。

如果您查看生成的
lex.yy.c
文件,您最终会发现如下代码:

case 4:
YY_RULE_SETUP
#line 13 "code.l"
= strdup(yytext);
        YY_BREAK
这显然不是你想的。正如在他们的文章中所指出的,问题在于,操作的开始必须遵循与模式相同的路线

[a-zA-Z]+   {
            yylval.name = strdup(yytext);
            return(ID);
            }
Flex还提供了一个警告:

code.l:18: warning, rule cannot be matched
code.l:23: warning, rule cannot be matched

在编译生成的C代码之前,最好先修复类似的警告。

Assignment.tab.h中的内容是什么?它是否定义了
yylval
?根据@Jonathan Leffler的评论:您的
Assignment.tab.h
是否与
%{include“parser.h”相同…
?@JonathanLeffler它是由make自动生成的file@StephanLechner它是由makefile自动生成的,makefile是由prof.Don't post code等提供的。在评论中,它变成了问题。它起作用了。我甚至不知道这一点,花了一整天的时间在它上面。非常感谢你!!!!!!!!!这些警告是因为,由于fle的一个怪癖x解析某些无效文件,在这两个“规则”中,“模式”都被视为
yylval.name
。Flex允许您在大括号内对规则进行分组(这仅在大括号组使用开始条件列表限定时才有用)。在大括号组中,它允许缩进规则。因此flex警告与编译错误的原因相同。