私は個人的な娯楽のためにCのような文法に取り組んできました。しかし、私はシフト/削減の競合に遭遇しており、それらは解決できると確信しています。
今のところ、私のexpressions
見た目は、簡略化された形式で、アクションが取り除かれています。
%left '+' '-'
%%
expr
: NUMBER
| IDENTIFIER
| expr '+' expr
| expr '-' expr
/* other operators like '*', '/', etc. */
| expr '(' expr ')' /* function call */
%%
ただし、これにより、shift / reduceの競合が発生します。パーサーは、括弧の処理方法について確信が持てません。私の言うことから-v
、のような表現が括弧にexpr '+' expr '('
還元expr '+' expr
されるべきか、expr
それともシフトされるべきかは不明です。
もちろん、かっこをずらして欲しいです。foo % bar(4)
で終わるべきではありません(foo % bar)(4)
。しかし、私は%prec
その意味のディレクティブを使用して成功していません。ルールを追加%left FUNCALL
したり%prec FUNCALL
、ルールを追加したりしても、変更はありません。
シフト/リデュースに遭遇したときにBisonのLALRパーサーが進むデフォルトのパスはシフトであり、問題%expect
を回避するために使用できることを私は知っています。ただし、式ごとに1つの競合が生成され、そのリストを変更する必要がある場合は、宣言も変更する必要があります。これは、私にはかなり醜い解決策のように見えます。その上、あなたの賢い子供たちの一人がその問題の解決策を持っていると確信しています。%expect
私の目標は、上記のルールと同様のルールを作成することです。Bisonは'('
、関数呼び出しルールからfromに遭遇するたびに、shift / reduceの競合なしに、括弧をシフトしていることを認識します。ちなみに、ディレクティブの使用法は%prec
次のとおりです。間違っている場合は、修正できます。シフト/削減の競合があります。
%left '+' '-'
%left FUNCALL
%%
expr
: NUMBER
| IDENTIFIER
| expr '+' expr
| expr '-' expr
/* other operators like '*', '/', etc. */
| expr '(' expr ')' %prec FUNCALL /* function call */
%%