0

私はBisonを初めて使用し、長い間連結などの配列とルールを作成しようとしてきましたが、ここでシフト削減が発生する理由とそれを解決する方法がわかりません:

arr:
  T_OPEN expr       {$$ = (void *)(new vector<int>());((vector<int>*)$$)->push_back($2);}
| arr ',' expr      {((vector<int>*)($1))->push_back($3);}
| arr T_CLOSE       {}
| arr '@' arr       {/*will add it later*/}

T_OPEN は "[" で、T_CLOSE は "]" です。@ は、2 つの配列を連結することになっています。arr は void* 型です。一部 :

arr '@' arr

シフト削減競合を引き起こします。どんな解決策も大歓迎です

4

1 に答える 1

4

のようなプロダクション

arr: arr '@' arr;

それらはあいまいであるため、常に shift-reduce 競合が発生します。ソースに 2 つの@演算子があるとします。

...1 @ ...2 @ ...3

これは次のように解析されるはずですか:

arr1: ...1 @ ...2
arr2: ...3
arr3: arr1 @ arr2

また

arr1: ...1
arr2: ...2 @ ...3
arr3: arr1 @ arr2

言い換えれば、@左に関連付けますか、それとも右に関連付けますか? 文法が特定されていないので、あいまいです。

これを解決する一般的な方法は、優先順位宣言 (bash のマニュアルを参照) を使用することですが、文法で直接記述することもできます (以下を参照)。

ただし、@演​​算子を脇に置いても、あなたの文法は本当にあなたが望むことをしません。まず、基本的な配列リテラルは次の文法に従うことをお勧めします: [注 1]

arr: '[' expr_list ']'    { $$ = $2; }
   | '[' ']'              { $$ = new std::vector<int>; }
expr_list
   : expr                 { $$ = new std::vector<int>; $$->push_back($1); }
   | expr_list ',' expr   { $1->push_back($3); }

そして、連結式を定義できます。

arr_concat
   : arr
   | arr_concat '@' arr   { std::copy($3->begin(), $3->end,
                                      std::back_inserter(*$1));
                            delete $3; // Note 2
                          }

上記の生成は の結合性について明示的であることに注意してください@。あいまいさはありえません。


ノート:

  1. ここで、型の 1 つが であるセマンティック ユニオンを宣言したと仮定します。std::vector<int>*これらのvoid*キャストはすべて見苦しく、安全ではないからです。次のようになります。

    %union {
       std::vector<int>*   array_pointer;
       // ...
    }
    %type <array_pointer> arr expr_list arr_concat
    %%
    
  2. deleteメモリリークを避けるために必要ですが、どこで行うかは、メモリ管理へのアプローチによって異なります。残念なことに、実際のベクトルではなくベクトルへのポインターを保持することを決定すると (この場合、削減ごとにベクトルをコピーするのはばかげているため、選択の余地はほとんどありません)、メモリ管理を担当することになります。セマンティック値が他のセマンティック値に組み込まれたらすぐにセマンティック値を削除するのは簡単な解決策ですが、割り当てられたオブジェクトへのポインターの他のコピーに注意する必要があることを意味します。割り当てられた各オブジェクトへのポインターが 1 つだけになるように注意している場合は、即時deleteにそのトリックが実行されます。それ以外の場合は、おそらく参照カウントに基づいた、ある種のガベージ コレクションが必要になります。

于 2015-11-29T22:26:21.160 に答える