Ошибка "что-то не структура или объединение" при компиляции очень простых файлов Lex/Yacc
Я искал ответы на свой вопрос, но никто не решает мою проблему.
Это мой действительно простой файл 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".
Спасибо.
1 ответ
Почему вы должны $2.t0
а также $4.cm
вместо просто $2
а также $4
?
%type <t0> OPERADORA
Заявление говорит Bison, что OPERADORA
значение переносится в t0
член союза, поэтому выражение, которое Bison использует для замены $2
в конечном коде, сгенерированном для ServicioSMS
определение действия будет автоматически ссылаться на это t0
член. Ваш $2.t0
поэтому будет в конечном итоге как <union>.t0.t0
что является ошибкой Вы должны увидеть это, если изучите lex.yy.c
файл, который был произведен Bison.
Аналогично для $4.cm
, который в конечном итоге как <union>.cm.cm
Еще одна ошибка.
Итак, удалите эти посторонние .t0
а также .cm
суффиксы в файле Bison ServicioSMS
определение действия, а затем запустить новую сборку.