私は bison を使用して C でパーサーを作成しています。これまでに試したすべての状況で正しく動作するように見えますが、2 項演算子 (単項 NOT 演算子の場合は 1 つ) で多数のシフト/リデュース警告が表示されます。良い)。
binary_op :
PLUS { }
| MINUS { }
| TIMES { }
| SLASH { }
| POWER { }
| AND { }
| OR { }
| LE { }
| LT { }
| GE { }
| GT { }
| EQ { }
| NE { }
| MOD { }
;
unary_op :
NOT { }
;
expr :
...
| unary_op expr { }
| expr binary_op expr { }
bison --verbose を使用して .y ファイルを実行すると、次のように表示されます。
state 51
11 set_existence: expr . IN set
12 | expr . NOT IN set
34 expr: expr . binary_op expr
34 | expr binary_op expr .
...
NOT shift, and go to state 26
AND shift, and go to state 27
OR shift, and go to state 28
....
NOT [reduce using rule 34 (expr)]
AND [reduce using rule 34 (expr)]
OR [reduce using rule 34 (expr)]
二項演算子を実際に解析する問題は見られませんが、とにかくシフト/削減の問題を解決する必要があるようです。競合がどこにあるのかわかりません - set_existence プロダクションは完全に無関係のようです。私の最善の推測 (暗闇でのショット) は、EQ が二項演算子 (等価比較) および代入 (たとえば、"foo = bar = baz;" が設定される) として使用されるという事実と関係がある可能性があるということです。 bar と baz が等しいかどうかに基づいて、foo を true/false に変換します)。等価比較を == ("foo = bar==baz;") に変更すると、パーサーは期待どおりに動作しますが、同じシフト/削減の競合が発生します。
編集:結合性が指定されています:
%left OR
%left AND
%left NOT
%left LT LE GT GE NE EQ
%left PLUS MINUS
%left TIMES MOD SLASH
%left POWER