Строка flex/bison 25: синтаксическая ошибка в '' . последняя строка файла

Я пытаюсь скомпилировать гибкий проект, но я всегда получаю одну и ту же ошибку, я ищу во всех SO и пробую большинство решений, таких как использование токена <> и возвращаю 1 или 0, или вызываю yywrap()... но без удачи

И я не вижу, где ошибка, у меня есть 84 предупреждения о сдвигах / сокращении конфликтов, но я мог бы быть проблемой.

Это токены.

%option yylineno

%{
 #include <string>
 #include <iostream>
 #include <vector>
 using namespace std ;
 #include "parser.hpp" 

 extern "C" int yywrap() { return(1); }
 #define TOKEN(t) processtoken(t, string(yytext, yyleng))

 void processtoken (int t, string id) {
   cout << t << " <" << id << ">" << endl ;
 }

%}

%option nounput

%%

programa                                TOKEN(RPROGRAM);
procedimiento                           TOKEN(RPROC);
variables                               TOKEN(RVAR);
si                                      TOKEN(RIF);
entonces                                TOKEN(RTHEN);
repetir                                 TOKEN(RREPEAT);
hasta                                   TOKEN(RUNTIL);
siempre                                 TOKEN(RALWAYS);
salir                                   TOKEN(RSALIR);
leer                                    TOKEN(RREAD);
escribir_linea                          TOKEN(RWRITE);
in                                      TOKEN(RIN);
out                                     TOKEN(ROUT);
entero                                  TOKEN(RENTERO);
real                                    TOKEN(RREAL);


[a-zA-Z](_?[a-zA-Z0-9])*                TOKEN(TID); 
\$[a-zA-Z](\-{0,1}[a-zA-Z0-9])*\-?      TOKEN(TID);
\$[a-zA-Z](\_{0,2}[a-zA-Z0-9])*         TOKEN(TID);
\(\*([^*]|\*+[^*)])*\*+\)               ; 

[ \t\n]                                 ;
[0-9]+\.[0-9]*                          TOKEN(TDOUBLE);
[0-9]+                                  TOKEN(TINTEGER); 
[0-9]+\.[0-9]+([eE][-+]?[0-9]+)?        TOKEN(TREAL);

"="                                     TOKEN(TASSIG);
"=="                                    TOKEN(TEQUAL);
">"                                     TOKEN(TCGT);
">="                                    TOKEN(TCGE);
"<"                                     TOKEN(TCLT);
"<="                                    TOKEN(TCLE);
"+"                                     TOKEN(TPLUS);
"-"                                     TOKEN(TMINUS);
"*"                                     TOKEN(TMUL);
"/"                                     TOKEN(TDIV);
"/="                                    TOKEN(TCNE);
"("                                     TOKEN(TLPAREN);
")"                                     TOKEN(TRPAREN);
"{"                                     TOKEN(TLBRACE);
"}"                                     TOKEN(TRBRACE);
","                                     TOKEN(TCOMMA);
":"                                     TOKEN(TCOLON);
";"                                     TOKEN(TSEMIC);

.                                       { cout << "Token desconocido: " << yytext << endl; yyterminate();}

%%

И это parser.y:

%{
   #include <stdio.h>
   #include <iostream>
   #include <vector>
   #include <string>
   using namespace std; 

   extern int yylex();
   extern int yylineno;
   extern char *yytext;
   string tab = "\t" ;
   void yyerror (const char *msg) {
     printf("line %d: %s at '%s'\n", yylineno, msg, yytext) ;
   }


%}

%union {
    string  *str ; 
}

%token <str> RPROGRAM RPROC RVAR RIF RTHEN RREPEAT RUNTIL
%token <str> RALWAYS RSALIR RREAD RWRITE RENTERO RREAL
%token <str> RIN ROUT

%token <str> TID TDOUBLE TREAL TINTEGER

%token <str> TASSIG TEQUAL TCGT TCGE TCLT TCLE TCNE
%token <str> TPLUS TMINUS TMUL TDIV
%token <str> TLPAREN TRPAREN TLBRACE TRBRACE TCOMMA TCOLON TSEMIC

%type <str> programa
%type <str> declaraciones
%type <str> lista_de_ident
%type <str> resto_lista_id
%type <str> tipo
%type <str> decl_de_subprogs
%type <str> decl_de_subprograma
%type <str> argumentos
%type <str> lista_de_param
%type <str> clase_par
%type <str> resto_lis_de_param
%type <str> lista_de_sentencias
%type <str> sentencia
%type <str> variable
%type <str> expresion

%left TPLUS TMINUS TMUL TDIV

%start programa 

%%

programa :  RPROGRAM TID
        declaraciones
        decl_de_subprogs
        TLBRACE lista_de_sentencias TRBRACE
        ;


declaraciones : RVAR lista_de_ident TCOLON tipo TSEMIC declaraciones
        | {}
        ;

lista_de_ident : TID resto_lista_id
        ;

resto_lista_id : TCOMMA TID resto_lista_id
        | {}
        ;

tipo : RENTERO | RREAL
        ;

decl_de_subprogs : decl_de_subprograma decl_de_subprogs
        | {}
        ;

decl_de_subprograma : RPROC TID argumentos declaraciones
                    TLBRACE lista_de_sentencias TRBRACE
        ;

argumentos : TLPAREN lista_de_param TRPAREN
        | {}
        ;

lista_de_param : lista_de_ident TCOLON clase_par tipo resto_lis_de_param
        ;

clase_par : RIN | ROUT | RIN ROUT
        ;

resto_lis_de_param : TSEMIC lista_de_ident TCOLON clase_par tipo resto_lis_de_param
        | {}
        ;

lista_de_sentencias : sentencia lista_de_sentencias
        | {}
        ;

sentencia : variable TASSIG expresion TSEMIC
        | RIF expresion RTHEN TLBRACE lista_de_sentencias TRBRACE
        | RREPEAT TLBRACE lista_de_sentencias TRBRACE RUNTIL expresion TSEMIC
        | RREPEAT RALWAYS TLBRACE lista_de_sentencias TRBRACE
        | RSALIR RIF expresion
        | RREAD TLPAREN variable TRPAREN TSEMIC
        | RWRITE TLPAREN expresion TRPAREN TSEMIC
        ;

variable : TID
        ;

expresion : expresion TEQUAL expresion
        | expresion TCGT expresion
        | expresion TCLT expresion
        | expresion TCGE expresion
        | expresion TCLE expresion
        | expresion TCNE expresion
        | expresion TPLUS expresion
        | expresion TMINUS expresion
        | expresion TMUL expresion
        | expresion TDIV expresion
        | TID 
        | TINTEGER
        | TREAL
        | TLPAREN expresion TRPAREN
        ;

И тестовая программа, которую я использую, чтобы опробовать все токены, следующая:

programa ejemplo
    variables a,b,c : entero;
    variables d,e : real;
(* esto es un comentario *)

procedimiento sumar (x,y: in entero; resul: in out entero) 
    variables aux:entero;
    {
        repetir {
            aux=x; 
            resul=y;
            aux = aux - 1;
            resul = resul+1;
        } hasta aux /= 0;
    }

{
    leer(a); leer(b);
    d= 1/b;
    e= 1/a;
    sumar(a,b,c); (* los que hagan llamadas a procedimientos *)
    c= c*(c*d)+e;
    escribir_linea(c*c);
}

Я всегда получаю в последней строке ошибку: строка 25: синтаксическая ошибка в '', но я не знаю, что это значит, потому что у меня есть токен для пробелов, токен EOF не работает, я пробовал с << EOF >> {yywrap();} но это не заканчивается.

1 ответ

Решение

Нигде в определении сканера вы никогда не вернете токен анализатору. Таким образом, единственный токен, который когда-либо увидит парсер, это токен END, автоматически возвращаемый flex, когда он видит EOF.

Но ваша грамматика не принимает пустой ввод; он настаивает на том, чтобы первый токен на входе был programa (например). Поэтому, естественно, когда он видит EOF, он сообщает об синтаксической ошибке.

Когда EOF обнаружен, текст токена отсутствует, поэтому yytext не будет действительным (Это может быть даже NULL, поэтому его определенно не следует использовать.) В целом, это не очень хорошая идея использовать yytext вне действия лексера, и его особенное использование в yyerror вызывает неопределенное поведение (хотя вы будете время от времени видеть его в примерах бизонов).

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