Ошибка "что-то не структура или объединение" при компиляции очень простых файлов 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 определение действия, а затем запустить новую сборку.

Другие вопросы по тегам