0

私は次のパーサー文法を持っています(これは小さなサンプルです):

expr:
        ident assignop expr
        {
            $$ = new NAssignment(new NAssignmentIdentifier(*$1), $2, *$3);
        } |
        STAR expr %prec IDEREF
        {
            $$ = new NDereferenceOperator(*$2);
        } |
        STAR expr assignop expr %prec IDEREF
        {
            $$ = new NAssignment(new NAssignmentDereference(*$2), $3, *$4);
        } |
        ... ;

...

assignop:
        ASSIGN_EQUAL |
        ASSIGN_ADD |
        ASSIGN_SUBTRACT |
        ASSIGN_MULTIPLY |
        ASSIGN_DIVIDE ;

今、私は次の行のいずれかを解析しようとしています:

*0x8000 = 0x7000;
*mem = 0x7000;

ただし、Bisonは引き続き「* mem」を確認し、「STAR expr」ルールを減らし、「STARexprassignop...」が一致するかどうかを確認するための先読みを実行しません。私がバイソンを理解している限り、それはこの先読みをしているはずです。私の最も近い推測は、%precが先読みまたはそのような奇妙なものをオフにしているということですが、なぜそうなるのかわかりません(prec値は同等であるため)。

この場合、先読みを実行するにはどうすればよいですか?

編集:

'STARexpr'に遭遇したときに入る状態は次のとおりです。

state 45

   28 expr: STAR expr .
   29     | STAR expr . assignop expr
   35     | expr . binaryop expr

    $default  reduce using rule 28 (expr)

    assignop  go to state 81
    binaryop  go to state 79

したがって、assignopを選択できるのに$ defaultを選択する理由がわかりません(この場合、parser.yファイル内のルールの順序は、どちらを選択するかに影響しないことに注意してください。assignopを並べ替えてみました。標準の「STARexpr」より上)。

4

2 に答える 2

0

これは、が、などよりも優先度が高い場合に発生しIDREFます。具体的には、この場合、(優先順位が適用される前の)rawパーサーを使用すると、ルールとさまざまなXXXトークンの間でshift/reduceの競合が発生します。あなたが持っている優先順位ルールは、reduceを支持してすべての競合を解決します。ASSIGN_EQUALASSIGN_ADDexpr: STAR exprASSIGN_

状態はassignopgotoであり、shiftまたはreduceではないため、先読みやトークン処理にはまったく関与しません。gotosは、トークンがシフトされ、後で問題の非終端記号に縮小された後にのみ発生します。

于 2012-04-09T01:40:38.043 に答える
0

私はこの問題を次のように別のルール「deref」を作成することで解決することになりました。

deref:
        STAR ident
        {
            $$ = new NDereferenceOperator(*$<ident>2);
        } |
        STAR numeric
        {
            $$ = new NDereferenceOperator(*$2);
        } |
        STAR CURVED_OPEN expr CURVED_CLOSE
        {
            $$ = new NDereferenceOperator(*$3);
        } |
        deref assignop expr
        {
            if ($1->cType == "expression-dereference") // We can't accept NAssignments as the deref in this case.
                $$ = new NAssignment(new NAssignmentDereference(((NDereferenceOperator*)$1)->expr), $2, *$3);
            else
                throw new CompilerException("Unable to apply dereferencing assignment operation to non-dereference operator based LHS.");
        } ;

'expr'の両方のルールを単一の'deref'に置き換えます。

于 2012-04-09T05:32:48.957 に答える