flex 和 bison 的问题
problems with flex and bison
我正在尝试在 flex 和 bison 中创建一个编译器,但不幸的是我发现了一些问题。
当我尝试编译时,编译器给我这些类型的错误:
flex.lex.c:286:37: error: expected ‘)’ before ‘->’ token
#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
flex.lex.c:139:19: note: in expansion of macro ‘YY_CURRENT_BUFFER_LVALUE’ #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
dichiarazioni.h:2:12: note: in expansion of macro ‘yylineno’
extern int yylineno; /* from lexer */
flex.lex.c:134:17: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘->’ token #define yyin yyg->yyin_r
dichiarazioni.h:5:14: note: in expansion of macro ‘yyin’
extern FILE *yyin;
make: *** [<incorporato>: flex.lex.o] Error 1
然后我给你看我程序文件的三个部分(flex.l bison.y 和 dichiarazioni.h)。
flex.l:
%option header-file="flex.lex.h"
%option reentrant bison-bridge
%{
#include "bison.tab.h"
#include "dichiarazioni.h"
%}
%%
"char" { yylval->fn = 10; return TYPE; }
"int" { yylval->fn = 11; return TYPE; }
"if"|"IF" { return IF; }
"else"|"ELSE" { return ELSE; }
"inc" { yylval->fn = 24; return OPERATORE; }
"dec" { yylval->fn = 25; return OPERATORE; }
"set" { yylval->fn = 26; return OPERATORE; }
etc etc
%%
bison.y:
%{
#include <stdio.h>
#include <stdlib.h>
%}
%{
#include "flex.lex.h"
#include "dichiarazioni.h"
%}
%define api.value.type {union YYSTYPE}
%token NUMBER
%token <fn> TYPE
%token SEMI
%token ALPHA
%token ELIF
%token <fn> CMP
%token <fn> OPERATORE
%token <fn> PRINT
.......
%type <fn> term NUMBER
%type <op> operazioni
%type <c> ALPHA string
.....
%start main
%%
string: ALPHA
;
.....
%%
dichiarazioni.h:
extern int yylineno; /* from lexer */
void yyerror(char *s, ...);
extern int yyparse();
extern FILE *yyin;
//extern int yylex();
union YYSTYPE{
int fn;
char* c;
struct operazioni* op;
....
};
如果你想使用可重入词法分析器,你需要仔细阅读 sections of the manual,其中描述了对 API 的更改。特别是,yyin
和yylineno
都不是全局变量,yylex
的原型也不是yylex(void)
。此外,flex 使用预处理器宏,因此在可重入词法分析器中,您仍然可以引用 yyin
和其他标准变量,就好像它们是全局变量一样。但是在 flex 操作之外,您必须将可重入访问器和 setter 函数与扫描仪上下文 object.
一起使用
您还需要在程序的某处创建和初始化扫描器 object,并将其作为额外参数传递给解析器。在不创建循环 header 依赖关系的情况下完成此操作有点棘手;您可以查看 this answer 以获得解决此问题的详细建议方法。 (但请先阅读手册:-))
此外,我建议让 bison 为 YYSTYPE
生成 union
声明,而不是使用 %union
在自己的 header 文件中自己生成声明在语法文件中声明。但也许我只是 old-fashioned。 :-)
您正在使用 %option bison-bridge
而没有在 bison 解析器中使用 %pure-parser
,这将不起作用 -- bison-bridge
用于连接(非标准)可重入 API 被野牛的 %pure-parser
选项使用。
从 .l 文件中删除 %option bison-bridge
或将 %pure-parser
添加到 .y 文件中。如果您选择后者,您还需要更改您的 .h 文件(yyerror/yyparse 更改,yyin 和 yylineno 消失)。
我正在尝试在 flex 和 bison 中创建一个编译器,但不幸的是我发现了一些问题。
当我尝试编译时,编译器给我这些类型的错误:
flex.lex.c:286:37: error: expected ‘)’ before ‘->’ token
#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
flex.lex.c:139:19: note: in expansion of macro ‘YY_CURRENT_BUFFER_LVALUE’ #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
dichiarazioni.h:2:12: note: in expansion of macro ‘yylineno’
extern int yylineno; /* from lexer */
flex.lex.c:134:17: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘->’ token #define yyin yyg->yyin_r
dichiarazioni.h:5:14: note: in expansion of macro ‘yyin’
extern FILE *yyin;
make: *** [<incorporato>: flex.lex.o] Error 1
然后我给你看我程序文件的三个部分(flex.l bison.y 和 dichiarazioni.h)。
flex.l:
%option header-file="flex.lex.h"
%option reentrant bison-bridge
%{
#include "bison.tab.h"
#include "dichiarazioni.h"
%}
%%
"char" { yylval->fn = 10; return TYPE; }
"int" { yylval->fn = 11; return TYPE; }
"if"|"IF" { return IF; }
"else"|"ELSE" { return ELSE; }
"inc" { yylval->fn = 24; return OPERATORE; }
"dec" { yylval->fn = 25; return OPERATORE; }
"set" { yylval->fn = 26; return OPERATORE; }
etc etc
%%
bison.y:
%{
#include <stdio.h>
#include <stdlib.h>
%}
%{
#include "flex.lex.h"
#include "dichiarazioni.h"
%}
%define api.value.type {union YYSTYPE}
%token NUMBER
%token <fn> TYPE
%token SEMI
%token ALPHA
%token ELIF
%token <fn> CMP
%token <fn> OPERATORE
%token <fn> PRINT
.......
%type <fn> term NUMBER
%type <op> operazioni
%type <c> ALPHA string
.....
%start main
%%
string: ALPHA
;
.....
%%
dichiarazioni.h:
extern int yylineno; /* from lexer */
void yyerror(char *s, ...);
extern int yyparse();
extern FILE *yyin;
//extern int yylex();
union YYSTYPE{
int fn;
char* c;
struct operazioni* op;
....
};
如果你想使用可重入词法分析器,你需要仔细阅读 sections of the manual,其中描述了对 API 的更改。特别是,yyin
和yylineno
都不是全局变量,yylex
的原型也不是yylex(void)
。此外,flex 使用预处理器宏,因此在可重入词法分析器中,您仍然可以引用 yyin
和其他标准变量,就好像它们是全局变量一样。但是在 flex 操作之外,您必须将可重入访问器和 setter 函数与扫描仪上下文 object.
您还需要在程序的某处创建和初始化扫描器 object,并将其作为额外参数传递给解析器。在不创建循环 header 依赖关系的情况下完成此操作有点棘手;您可以查看 this answer 以获得解决此问题的详细建议方法。 (但请先阅读手册:-))
此外,我建议让 bison 为 YYSTYPE
生成 union
声明,而不是使用 %union
在自己的 header 文件中自己生成声明在语法文件中声明。但也许我只是 old-fashioned。 :-)
您正在使用 %option bison-bridge
而没有在 bison 解析器中使用 %pure-parser
,这将不起作用 -- bison-bridge
用于连接(非标准)可重入 API 被野牛的 %pure-parser
选项使用。
从 .l 文件中删除 %option bison-bridge
或将 %pure-parser
添加到 .y 文件中。如果您选择后者,您还需要更改您的 .h 文件(yyerror/yyparse 更改,yyin 和 yylineno 消失)。