一起使用 Flex 和 Bison

Using Flex and Bison together

首先声明一下,对于flex和bison编程,我是初学者

我正在尝试编写识别特定声明部分的代码。它的语法和逻辑可以通过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();
}

问题出在编译上。在终端上编译时出现以下错误行:

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

期待看到您的回答!

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

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

exercise4.l 等文件是 flex 的输入,它定义了从 lexemestokens[=42= 的映射],exercise4.y 将是 bison 的输入,它定义 标记 语法 中的顺序。要一起使用这两个工具,我们必须将 flex 的输出(在本例中 lex.yy.c 与使用 #include "lex.yy.x" 指令的 bison 语法结合起来;标记用 %token声明。)

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

exercise4.l:

%%
[ \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]; }
%%

exercise4.y:

%{
#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

并测试生成的解析器:

C:\Users\Brian>.\exercise4
var a:integer;
^Z