flex/bison 第 25 行:'' 处的语法错误。文件的最后一行
flex/bison line 25: syntax error at '' . last line of the file
我正在尝试编译一个 flex proyect,但我总是遇到同样的错误,我在所有 SO 中搜索,并尝试了大多数解决方案,比如使用标记 <> 和 return 1 或 0,或调用 yywrap()... 但没有运气。
而且我没有看到错误在哪里,我有 84 个 shifts/reduce 冲突警告,但我认为这可能是问题所在。
这是tokens.l:
%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();} 但它没有完成。
在您的扫描器定义中,您从来没有return解析器的标记。因此,解析器看到的唯一标记是 END 标记,它在看到 EOF 时自动 return 由 flex 编辑。
但是你的语法不接受空输入;它坚持输入中的第一个标记是 programa
(例如)。所以很自然地当它看到EOF的时候,就会报语法错误。
检测到EOF时,没有token文本,所以yytext
无效。 (它甚至可能是 NULL,所以绝对不应该使用它。)总的来说,在词法分析器操作之外使用 yytext
并不是一个好主意,它在 [=13 中的特殊用途=] 调用未定义的行为(尽管您会不时在野牛示例中看到它)。
我正在尝试编译一个 flex proyect,但我总是遇到同样的错误,我在所有 SO 中搜索,并尝试了大多数解决方案,比如使用标记 <> 和 return 1 或 0,或调用 yywrap()... 但没有运气。
而且我没有看到错误在哪里,我有 84 个 shifts/reduce 冲突警告,但我认为这可能是问题所在。
这是tokens.l:
%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();} 但它没有完成。
在您的扫描器定义中,您从来没有return解析器的标记。因此,解析器看到的唯一标记是 END 标记,它在看到 EOF 时自动 return 由 flex 编辑。
但是你的语法不接受空输入;它坚持输入中的第一个标记是 programa
(例如)。所以很自然地当它看到EOF的时候,就会报语法错误。
检测到EOF时,没有token文本,所以yytext
无效。 (它甚至可能是 NULL,所以绝对不应该使用它。)总的来说,在词法分析器操作之外使用 yytext
并不是一个好主意,它在 [=13 中的特殊用途=] 调用未定义的行为(尽管您会不时在野牛示例中看到它)。