找不到" 2规则永不减少"和"冲突:2班/减"在yacc文件中

时间:2014-06-25 02:42:40

标签: bison yacc context-free-grammar

当我尝试“编译”我的yacc文件时,我似乎无法找到上述错误。我希望有人可以指出这些问题并让我知道我需要做些什么来纠正这个问题。我已经列出了我的文件:

%token Identifier Int Real_Num And Array
%token Begin Boolean Div Do Else
%token End False For Goto If
%token Imply Integer Label Not Or
%token Own Procedure Real Step String
%token Then True Until Value While
%token Plus Minus Mult Divide Less
%token LessEq Great GreatEq Eq NotEq
%token Comma Colon Semi LParan RParan
%token LBrak RBrak Assign

%{

%}

%start program

%%

program
        : block
        ;

block
        : Begin optdecls stmts End
        ;

optdecls
        : /* empty */
        | decl Comma optdecls
        ;

decl
        : vardecl
        | arraydecl
        ;

vardecl
        : type idlist
        ;

type
        : Real
        | Integer
        | Boolean
        ;

idlist
        : Identifier
        | Identifier Comma idlist
        ;

arraydecl
        : Array arraylist
        | type Array arraylist
        ;

arraylist
        : arrayseg
        | arrayseg Comma arraylist
        ;

arrayseg
        : Identifier LBrak a_expr Colon a_expr RBrak

stmts
        : stmt
        | stmt Semi stmts
        ;

stmt
        : u_stmt
        | if_stmt
        | for_stmt
        ;

u_stmt
        : assign
        | dummy
        | block
        ;

assign
        : var Assign expr
        | var Assign assign
        ;

dummy
        : /* empty */
        ;

for_stmt
        : For var Assign a_expr Step a_expr Until a_expr Do stmt
        ;

if_stmt
        : If expr Then u_stmt
        | If expr Then u_stmt Else stmt
        | If expr Then for_stmt
        ;

var
        : Identifier
        | Identifier LBrak a_expr RBrak
        ;

factor
        : Int
        | Real_Num
        | var
        | LParan expr RParan
        ;

term
        : factor
        | term Mult factor
        | term Divide factor
        | term Div factor
        ;

sum
        : term
        | Plus term
        | Minus term
        | sum Plus term
        | sum Minus term
        ;

brel
        : sum
        | True
        | False
        | sum relation sum
        ;

relation
        : Less
        | LessEq
        | Great
        | GreatEq
        | Eq
        | NotEq
        ;

bsecond
        : brel
        | Not brel
        ;

bfactor
        : bsecond
        | bfactor And bsecond
        ;

bterm
        : bfactor
        | bterm Or bfactor
        ;

expr
        : bterm
        | If expr Then bterm Else expr
        ;

a_expr
        : sum
        | If expr Then sum Else a_expr
        ;

%%

对于长篇帖子感到抱歉,但我相信编码的所有代码都是相关的。谢谢你的帮助。

1 个答案:

答案 0 :(得分:3)

使用-v选项bison,这将生成一个.output文件,其中包含有关所有状态和冲突的信息。在你的语法中,这会在状态16和30中产生冲突。

州16是:

state 16

   15 arraylist: arrayseg .
   16          | arrayseg . Comma arraylist

    Comma  shift, and go to state 34

    Comma  [reduce using rule 15 (arraylist)]

这告诉您,在看到arrayseg之后,为了解析更多arraylist,或者是否应该减少arraylist,我们不知道是否要移动逗号并允许逗号成为允许在arraylist之后使用逗号的其他规则(例如optdecls)的一部分。

州30是:

state 30

   11 idlist: Identifier .
   12       | Identifier . Comma idlist

    Comma  shift, and go to state 59

    Comma  [reduce using rule 11 (idlist)]

这基本上是一回事。

基本问题是你的语法描述了逗号分隔的包含逗号分隔列表的事物列表,所以它需要更多的先行来确定逗号是属于内部列表还是外部列表。

也许你应该在decls之间有Semi而不是Comma