首先,我必须明确表示我是关于弹性和野牛编程的初学者。
我正在尝试编写识别特定声明部分的代码。它的语法和逻辑可以通过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();
}
问题在于编译。在终端上编译时,我得到以下几行错误:
我的代码出了什么问题?如何修复错误?
我期待着阅读你的答案!
答案 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