0

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が役に立たないと言っているのはなぜですか?

今、シフト/リデュースとリデュース/リデュースはどれくらい悪いのだろうかと思っています。

ええと、手がかりが必要です。

4

2 に答える 2

1

一言で言えば、シフト/リデュースとリデュース/リデュースの競合を解決したいのです。コンフリクトとは、パーサー ジェネレーターが、特定の (あいまいな) 入力が与えられた場合に、どのプロダクションを適用したいのかがわからないことを示す方法です。

「役に立たない」とは、非終端記号を適用できる可能な入力がないというバイソンの言い方だと思いますexpr2

あなたの文法に関するいくつかの観察: (1) あなたの式の非終端記号には、 の規則がないようですidentifier。あなたの文法を読むと、「a + 2」は有効な表現ではありません。(2) 文の区切り記号がないのが気になります。それは間違いではありませんが、あいまいさの可能性をもたらしていると思います。おそらく、それは解析している言語の制約です。

考えられる戦略: 単項演算子機能 ( expr2) を一時的に削除し、残りのパーサーを機能させる。次に、その機能を再度追加します。

于 2012-06-19T14:52:18.520 に答える
1

再帰的な を含まないan の生成は存在しないため、ルールexpr2を縮小することはできません。つまり、(有限の)入力が an に一致することはありません。expr2expr2expr2

あなたはおそらくexpr2: identifier生産を行うことを意図していました-それを追加するとuseless rule警告は消えますが、まだいくつかのシフト/削減および削減/競合が解決されません。

于 2012-06-19T18:59:31.677 に答える