一起使用Flex和Bison

时间:2015-12-28 14:40:54

标签: bison flex-lexer lex

首先,我必须明确表示我是关于弹性和野牛编程的初学者。

我正在尝试编写识别特定声明部分的代码。它的语法和逻辑可以通过flex和bison代码来理解,我在下面提到:

%{
#include <stdio.h>
%}
[ \t\n]+                { /* Ignore all whitespace */ }
var                     { return VAR; }
real                    { return REAL; }
boolean                 { return BOOLEAN; }
integer                 { return INTEGER; }
char                    { return CHAR; }
[a-zA-Z][a-zA-Z0-9_]*   { return VAR_NAME; }
.                       { return yytext[0]; }
%%
program : VAR typedecls ;
typedecls : typedecl | typedecls typedecl ;
typedecl : varlist ':' var_type ';' ;
varlist : VAR_NAME | varlist ',' VAR_NAME ;
var_type : REAL | BOOLEAN | INTEGER | CHAR ;
%%
main( argc, argv )
int argc;
char **argv;
{
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
yylex();
}

问题在于编译。在终端上编译时,我得到以下几行错误:

enter image description here

我的代码出了什么问题?如何修复错误?

我期待着阅读你的答案!

1 个答案:

答案 0 :(得分:2)

您误读了使用这些工具的说明!

需要两个不同的文件,而不是一个。

诸如exercise4.l之类的文件是flex的输入,它定义了从 lexemes tokens 的映射,而exercise4.y将是输入到bison定义语法标记的顺序。要同时使用这两个工具,我们必须使用flex指令将lex.yy.c(在本例中为#include "lex.yy.x")的输出与bison语法相结合;使用{{1}声明令牌声明。)

根据您的示例,我们可以将其重新分解为两个文件:

<强> exercise4.l

%token

<强> exercise4.y

%%
[ \t\n]+                { /* Ignore all whitespace */ }
var                     { return VAR; }
real                    { return REAL; }
boolean                 { return BOOLEAN; }
integer                 { return INTEGER; }
char                    { return CHAR; }
[a-zA-Z][a-zA-Z0-9_]*   { return VAR_NAME; }
.                       { return yytext[0]; }
%%

我们现在可以将这些与以下命令行操作结合起来:

%{
#include <stdio.h>    
%}
%token VAR VAR_NAME REAL BOOLEAN INTEGER CHAR
%%
program : VAR typedecls ;
typedecls : typedecl | typedecls typedecl ;
typedecl : varlist ':' var_type ';' ;
varlist : VAR_NAME | varlist ',' VAR_NAME ;
var_type : REAL | BOOLEAN | INTEGER | CHAR ;
%%
main( argc, argv )
int argc;
char **argv;
{
extern FILE *yyin;
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
/* yylex(); */
yyparse();
}
yyerror(char *s)  
{  
 printf("\nError\n");  
}
#include "lex.yy.c"

并测试生成的解析器:

C:\Users\Brian>flex exercise4.l    
C:\Users\Brian>bison exercise4.y    
C:\Users\Brian>gcc -o exercise4.exe exercise4.tab.c -lfl