Mec*_*c45 1 parsing bison flex-lexer
所以我是 flex 和 bison 的新手,我正在尝试构建一个简单的类似 C 的词法和句法分析器,但是我遇到了这些错误,而且我无法真正从中得出结论。自动生成的文件生成的错误表明 y.tab.c 和 lex.yy.c 中存在标记重新定义
这是文件:test.l
%{
#include <stdio.h>
#include <string.h>
#include "y.tab.h"
int yylex();
void yyerror(const char *s);
%}
%%
"program" { return PROGRAM ; }
"function" { return FUNCTION ; }
"integer" { return INTEGER ; }
"boolean" { return BOOLEAN ; }
"if" { return IF ; }
"else" { return ELSE ; }
"end" { return END ; }
"or" { return OR ; }
"and" { return AND ; }
"div" { return DIV ; }
"mod" { return MOD ; }
"not" { return NOT ; }
"(" { return LPARENTHESIS ; }
")" { return RPARENTHESIS ; }
";" { return SEMI ; }
"," { return COMA ; }
"<=" { return LESSEQ ; }
">=" { return GREATEREQ ; }
"+" { return PLUS ; }
"-" { return MINUS ; }
"*" { return MUL ; }
"=" { return EQUAL ; }
"!>" { return NEQUAL ; }
"<" { return LESS ; }
">" { return GREATER ; }
":=" { return ASSIGN ; }
"true" { return TRUE ; }
"false" { return FALSE ; }
"{" { return LCURLYBRAKET ; }
"}" { return RCURLYBRAKET ; }
"void" { return VOID; }
%%
int main(int argc, char* argv)
{
int token;
while ((token = yylex()) != 0)
{
printf("Token: %d\n", token);
}
return 0;
}
void yyerror(const char *s)
{
printf("yyerror has: %s", s);
}
Run Code Online (Sandbox Code Playgroud)
测试2.y
%token PROGRAM
%token FUNCTION
%token EXTERN
%token LPARENTHESIS
%token RPARENTHESIS
%token LCURLYBRAKET
%token RCURLYBRAKET
%token SEMI
%token COMA
%token VOID
%token INTEGER
%token BOOLEAN
%token STRING
%token INTCONST
%token CHARCONST
%token BEGIN
%token END
%token IF
%token ELSE
%token RETURN
%token TRUE
%token FALSE
%token ID
%right ASSIGN
%left OR AND
%left EQUAL NEQUAL
%left GREATER GREATEREQ LESS LESSEQ
%left NOT
%left MINUS PLUS
%left DIV MOD MUL
//%start program
%%
program : ext_decl head def com;
ext_decl : | ext_proto ext_decl;
ext_proto : EXTERN func_proto;
head : VOID ID LPARENTHESIS RPARENTHESIS;
def : | definition def;
definition : def_var | def_func | func_proto;
def_var : data_type var_list;
data_type : INTEGER | BOOLEAN | STRING;
var_list : ID dummy_ex;
dummy_ex : | COMA ID dummy_ex;
def_func : head_func def com;
func_proto : head_func SEMI;
head_func : func_type ID LPARENTHESIS dummy RPARENTHESIS;
dummy : | std_par_list;
func_type : INTEGER | BOOLEAN | VOID;
std_par_list : typical_par dummy_par;
dummy_par : | COMA typical_par dummy_par;
typical_par : data_type dummy_amb ID;
dummy_amb : | AND;
com : BEGIN dummy_com END;
dummy_com : | command dummy_com;
command : simple_com COMA | structured_com | complex_com;
complex_com : LCURLYBRAKET dummy_com RCURLYBRAKET;
structured_com : if_com;
simple_com : assign | func_call | return_com | null_com;
if_com : IF LPARENTHESIS gen_ex RPARENTHESIS command dummy_else;
dummy_else : | else_clause;
else_clause : ELSE command;
assign : ID ASSIGN gen_ex;
func_call : ID LPARENTHESIS dummy_true_par RPARENTHESIS;
dummy_true_par : | gen_ex COMA gen_ex dummy_true_par;
return_com : RETURN dummy_ret;
dummy_ret : | gen_ex;
null_com : ;
gen_ex : gen_term dummy_term;
dummy_term : | OR OR gen_term dummy_term;
gen_term : gen_factor dummy_factor;
dummy_factor : | AND AND gen_factor dummy_factor;
gen_factor : dummy_not gen_first_factor;
dummy_not : | NOT;
gen_first_factor : simple_ex dummy_compare;
dummy_compare : | compare_sect;
compare_sect : comp_op simple_ex;
comp_op : EQUAL | NEQUAL | LESS | GREATER | LESSEQ | GREATEREQ;
simple_ex : simple_term dummy_s;
dummy_s : | choice simple_term dummy_s;
choice : PLUS | MINUS;
simple_term : simple_factor dummy_t;
dummy_t : | choice2 simple_factor dummy_t;
choice2 : MUL | DIV | MOD;
simple_factor : choice simple_first_term;
simple_first_term : ID | const | func_call | LPARENTHESIS gen_ex RPARENTHESIS;
const : INTCONST | CHARCONST | TRUE | FALSE;
%%
Run Code Online (Sandbox Code Playgroud)
这是我用来运行它们的脚本。制作
flex test.l
bison -y -d test2.y
gcc y.tab.c lex.yy.c
Run Code Online (Sandbox Code Playgroud)
& 这是错误:
PS我知道存在一些冲突,但我真的不认为它们与我迄今为止遇到的错误有任何关系。如果我错了请纠正我。
谢谢你的时间。
令牌BEGIN在内部转换为宏(例如 \n #define BEGIN 273)\n在 Flex 中已经有一个宏“BEGIN”来切换启动条件。
所以你会得到一个重新定义错误。解决方案更改 BEGIN 令牌的名称。
\n\n为了避免警告,您可以在 bison 的开头声明函数yylex和\。yyerror
%{\nint yylex();\nvoid yyerror(char* s);\n%}\nRun Code Online (Sandbox Code Playgroud)\n\n要消除shift-reduce和reduce-reduce冲突,\n必须分析语法。\nbison -v f.y尝试创建一个y.output包含有关冲突和 LaLR 自动机的一些信息的文件。\n一个初步提示:左递归产生式通常会\n减少 LR 冲突的数量。示例:在
var_list : ID dummy_ex;\ndummy_ex : | COMA ID dummy_ex\nRun Code Online (Sandbox Code Playgroud)\n\n尝试dummy_ex : | dummy_ex COMA ID\甚至更好,减少“虚拟...”\xe2\x98\xba
var_list : ID\n | var_list \',\' ID \nRun Code Online (Sandbox Code Playgroud)\n\n您当前的主要功能只是测试 lex-analyzer。这对于起点可能有用。在最后,您需要将其替换为 main\nin 野牛调用yyparse()
| 归档时间: |
|
| 查看次数: |
1974 次 |
| 最近记录: |