关于转移/减少警告的野牛

时间:2012-06-14 19:49:58

标签: bison lex

我写了一个flex / bison prog语言解析器。目前几乎已经完成(我相信已经完成,只需要处理语法错误)。在特定的类中,会出现一些奇怪的问题。

我相信问题出在解析器中。我停止阅读编译控制台,今天,我回到它并看到了一件坏事:

parser.y: conflicts: 801 shift/reduce, 237 reduce/reduce

之后,我重新开始构建解析器并读取结果,以便在完成后立即捕获问题。

input:
    | input expression { std::cout << $2; }
    ;

expression:
      expression comparing expression { $$ = new AExpOperation( $1, $2, $3 ); }
    | expr2 { $$ = $1; }
    | TNEW identifier TLBRACKET TRBRACKET { $$ = new AExpNewArray( NULL, $2 ); }
    | TLPAREN expression TRPAREN { $$ = new AExpParent( $2 ); }
    ;

expr2:
      TPLUS expr2 { $$ = $2; }
    | TMINUS expr2 { $$ = new AExpFastOp( $2, $1, true ); }
    | TBNOT expr2 { $$ = new AExpFastOp( $2, $1, true ); }
    | TNOT expr2 { $$ = new AExpFastOp( $2, $1, true ); }
    | expr2 TINCREMENT { $$ = new AExpFastOp( $1, $2, false ); }
    | TINCREMENT expr2 { $$ = new AExpFastOp( $2, $1, true ); }
    | expr2 TDECREMENT { $$ = new AExpFastOp( $1, $2, false ); }
    | TDECREMENT expr2 { $$ = new AExpFastOp( $2, $1, true ); }
    ;

comparing:
      TEQ | TNE | TLT | TLE | TGT | TGE | TPLUS | TMINUS | TDIVIDE | TMULT | TOR | TAND
    | TBXOR | TLSHIFT | TRSHIFT | TZFILL | TBOR | TBAND | TBNOT | TEQA | TNEA | TINSTANCEOF
    ;

identifier:
      TNUMBER { $$ = new AExpression( $1 ); }
    | TNAME { $$ = new AExpression( $1 ); }
    | TSTRING { $$ = new AExpression( $1 ); }
    | TFALSE { $$ = new AExpression( $1 ); }
    | TTRUE { $$ = new AExpression( $1 ); }
    | TNULL { $$ = new AExpression( $1 ); }
    | TTHIS { $$ = new AExpression( $1 ); }
    ;

只是这个小部分得到的错误让我不明白为什么:

parser.y: warning: 1 useless nonterminal and 9 useless rules
parser.y:40.25-29: warning: useless nonterminal: expr2
parser.y:69.11-28: warning: useless rule: expression: expr2
parser.y:75.11-34: warning: useless rule: expr2: TPLUS expr2
parser.y:76.11-63: warning: useless rule: expr2: TMINUS expr2
parser.y:77.11-62: warning: useless rule: expr2: TBNOT expr2
parser.y:78.11-61: warning: useless rule: expr2: TNOT expr2
parser.y:79.11-68: warning: useless rule: expr2: expr2 TINCREMENT
parser.y:80.11-67: warning: useless rule: expr2: TINCREMENT expr2
parser.y:81.11-68: warning: useless rule: expr2: expr2 TDECREMENT
parser.y:82.11-67: warning: useless rule: expr2: TDECREMENT expr2

为什么说TPLUS expr2没用,例如?

现在我想知道转移/减少和减少/减少多少坏?

好吧,我需要一个线索。

2 个答案:

答案 0 :(得分:1)

简而言之,您确实希望解决轮班/减少和减少/减少冲突的问题。冲突是解析器生成器的一种说法,即在给定特定(模糊)输入的情况下,它不知道您想要应用哪个生产。

我认为“无用”是野牛的说法,即没有可能应用非终端expr2的输入。

关于你的语法的一些观察:(1)你的表达非终端似乎缺少identifier的规则。我读你的语法的方式,“a + 2”不是一个有效的表达。 (2)缺乏陈述分隔符困扰我 - 这没有错,但我认为你正在引入歧义的机会。也许这是您要解析的语言的约束。

可能的策略:暂时删除一元运算符功能(expr2)并使解析器的其余部分工作;然后重新添加该功能。

答案 1 :(得分:1)

它告诉你,规则expr2永远不能减少,因为expr2没有生产不包含递归expr2,这意味着没有(有限)输入可以匹配expr2

你可能意味着有一个expr2: identifier产品 - 添加会使useless rule警告消失,但仍会留下一些转移/减少和减少/冲突才能得到解决。