解決できない LR(1) 競合のある文法があります。それでも、文法は明確であるべきです。(
最初に、、)
、{}
、 の5 つのトークンを使用した簡略化された文法で問題を示します。,
id
EBNF は次のようになります。
args = ( id ',' )*
expression = id
| '(' expression ')'
| '(' args ')' '{}'
文法は明確で、最大 2 つの先読みトークンが必要です。が(
シフトされると、次の 5 つの可能性しかありません。
(
→再発。)
→ のように縮小し'(' args ')'
ます。id
)
ない{}
→ として減らす'(' expression ')'
。id
)
{}
→'(' args ')' '{}'
id
,
'(' args ')' '{}'
→ (最終的に)として削減します。
単純な翻訳では、次の結果 (および競合)が得られます。
formal_arg: Ident
{}
formal_args: formal_arg Comma formal_args
| formal_arg
| /* nothing */
{}
primary: Ident
| LParen formal_args Curly
| LParen primary RParen
{}
そのため、文法では、決定する先読みの最大 3 つのトークンが必要です。LR(3) 文法は LR(1) 文法に変換できることを知っています。
ただし、この特定のケースで変換を行う方法がよくわかりません。上記の単純化された文法は、より大きなコード本体からの抜粋であることに注意してください。特に、 上記のすべてprimary
をタッチせずに変換することは可能ですか?expr