我有一個LR(1)衝突的語法,我無法解決;但是,語法應該是明確的。我將首先用五個令牌簡化語法來演示問題:(
,)
,{}
,,
和id
。如何將此語法轉換爲LR(1)?
的EBNF是這樣的:
args = (id ',')*
expression = id
| '(' expression ')'
| '(' args ')' '{}'
語法是明確的,需要前瞻的最多兩個令牌。當(
移位時,只有五種可能性:
(
→重複。)
→減少爲'(' args ')'
。id
)
不是{}
→縮小爲'(' expression ')'
。id
)
{}
→降低作爲'(' args ')' '{}'
id
,
→降低作爲'(' args ')' '{}'
(最終)。
一個天真的翻譯產生以下結果(和conflicts):
formal_arg: Ident
{}
formal_args: formal_arg Comma formal_args
| formal_arg
| /* nothing */
{}
primary: Ident
| LParen formal_args Curly
| LParen primary RParen
{}
所以,語法要求先行決定的最多三個令牌。我知道一個LR(3)語法爲can be transformed LR(1)語法。
但是,我不太瞭解如何在這種特殊情況下進行轉換。請注意,上面的簡化語法是從larger body of code中提取的;特別是有可能變換primary
而不碰expr
以及上述所有內容?
事實上我剛剛得出了和你一樣的結論。然而,我的解析器生成器(menhir)具有更高階的規則,所以我可以讓它爲我做出咕嚕的工作。我可能會自己回答這個問題(如果它適用於我),抱歉不接受! – whitequark
最有趣的部分是我知道你鏈接到的問題的作者。 – whitequark
我剛剛與你的轉換一起工作,雖然需要一套奇怪的語法轉換。真棒。 – whitequark