我一直在寻找问题的答案,但没有人能解决我的问题。
这是我非常简单的Yacc文件:
%{
#include <stdio.h>
#include "y.tab.h"
int clientesVodafone = 0;
int clientesMovistar = 0;
float sumaVodafone = 0.0;
float sumaMovistar = 0.0;
%}
%union {
int t0;
float cm;
};
%token NUMEROTELEFONO OPERADORA SERVICIO COSTEMENSAJE
%type <t0> OPERADORA
%type <cm> COSTEMENSAJE
%start fichero
%%
ServicioSMS: NUMEROTELEFONO OPERADORA SERVICIO COSTEMENSAJE {
if ($2.t0 == 0) {
clientesMovistar++;
sumaMovistar += $4.cm;
} else {
clientesVodafone++;
sumaVodafone += $4.cm;
}
}
fichero: ServicioSMS
fichero: fichero ServicioSMS
%%
int main(void) {
yyparse();
printf("%i clientes de VODAFONE con coste %f euros.",
clientesVodafone, sumaVodafone);
printf("%i clientes de MOVISTAR con coste %f euros.",
clientesMovistar, sumaMovistar);
}
这是我的 Lex 文件:
%{
#include <stdio.h>
#include "y.tab.h"
%}
%%
6[0-9]{8} {return NUMEROTELEFONO;}
MOVISTAR {yylval.t0 = 0; return OPERADORA;}
VODAFONE {yylval.t0 = 1; return OPERADORA;}
[0-9]+s {return SERVICIO;}
[0-9]*.[0-9]+ {yylval.cm = atof(yytext); return COSTEMENSAJE;}
%%
当我编译时,我收到著名的错误消息:"错误:在不是结构或联合的东西中请求成员't0'"。我也得到了成员"cm"的相同错误。它们与 yyparse() 相关联,在以下行中:
if ($2.t0 == 0) {
clientesMovistar++;
sumaMovistar += $4.cm;
} else {
clientesVodafone++;
sumaVodafone += $4.cm;
}
我使用Bison和Flex编译:"bison -d -y example.y","flex example.l"和"gcc lex.yy.c y.tab.c -ll -lm"。
谢谢。
为什么你有$2.t0
和$4.cm
,而不仅仅是$2
和$4
?
%type <t0> OPERADORA
语句告诉 Bison,OPERADORA
值在联合的t0
成员中携带,因此 Bison 用于替换$2
的表达式将在为ServicioSMS
动作定义生成的最终代码中自动引用该t0
成员。 因此,您的$2.t0
最终将变为<union>.t0.t0
这是一个错误。 如果您检查 Bison 生成的lex.yy.c
文件,您应该能够看到这一点。
同样,对于$4.cm
,最终将<union>.cm.cm
,另一个错误。
因此,删除 Bison 文件的ServicioSMS
操作定义中那些无关.t0
和.cm
后缀,然后运行全新构建。