令牌重新定义? flex&野牛

时间:2016-06-24 09:14:59

标签: parsing bison flex-lexer

所以我不熟悉flex&野牛,我正在努力构建一个简单的C-like lexical&语法分析器,但我得到这些错误,我无法真正从它做出正面或反面。 自动生成的文件生成的错误表明在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);
}

test2.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;

%%

这是我用来运行它们的脚本。 使

flex test.l
bison -y -d test2.y 
gcc y.tab.c lex.yy.c

&安培;这是错误:

enter image description here

P.S。 我知道有一些冲突,但我真的认为他们没有想到我到目前为止所犯的错误。如果我错了,请纠正我。

感谢您的时间。

1 个答案:

答案 0 :(得分:3)

令牌BEGIN在内部被翻译为宏(例如 #define BEGIN 273) 在Flex中已经存在一个宏观&#34; BEGIN&#34;切换开始条件。

所以你得到了一个重新定义的错误。解决方案更改BEGIN令牌的名称。

要避免警告,您可以声明函数yylexyyerror 在野牛的开始。

%{
int yylex();
void yyerror(char* s);
%}

要删除shift-reducereduce-reduce冲突,请与您联系 必须分析语法。 尝试bison -v f.y创建一个y.output文件,其中包含有关冲突的一些信息以及LaLR自动机。 一个初步提示:左递归制作通常会减少 LR冲突的数量。示例:in

var_list   : ID dummy_ex;
dummy_ex   : | COMA ID dummy_ex

尝试dummy_ex : | dummy_ex COMA ID 甚至更好,减少假人......&#34; ☺

var_list   : ID
           | var_list ',' ID 

您当前的主要是测试lex-analyzer。这可能对起点有用。在决赛中你需要用main替​​换它 在野牛呼唤yyparse()