[英]Looking for advice on making this BNF grammar suitable for LL(1) parsing (left factoring)
我正在做一個解析項目,該項目對Perl的正則表達式使用了此語法的改編版本http://www.cs.sfu.ca/~cameron/Teaching/384/99-3/regexp-plg.html 。 我已經出於我自己的目的簡化了該語法,例如(請注意,因為“ |”是一個標記,所以我使用逗號“”,因此給定的非終結符是單獨產生的):
<RE> := <union>, <simple>
<union> := <RE> | <simple>
<simple> := <concat>, <basic>
<concat> := <simple><basic>
<basic> := <zero>, <one>, <onezero>, <elem>
<zero> := <elem>*
<one> := <elem>+
<onezero> := <elem>?
<elem> := <group>, <any>, <literal>, <class>
<group> := (<RE>)
<class> := [<items>]
<items> := <item>, <item><items>
<item> := <range>, <literal>
我想編寫一個LL(1)解析器來處理此語法,並且對於LL(1)解析器, <items>
具有一些歧義。 為了解決這個問題,我可以通過添加一個新的非終結符<X>
來對它們進行左分解,如下所示:
<items> := <item><X>
<X> := <items>, epsilon
但是我想知道的是,是否可以在<items>
翻轉第二個產品的順序,如下所示:
<items> := <item>, <items><item>
並避免添加新的非終結符? 看起來這並沒有破壞任何東西,畢竟這個生產的全部目的是允許任意數量的連續<item>
符號,並且如果我們顛倒順序,我們仍然會得到它。 我是否缺少某些東西,還是在這種情況下簡單地顛倒順序就可以達到與左因子分解相同的目標?
您要解決的問題是
items → item
items → item items
不是左撇子; 兩種生產都從item
開始。
您建議的修復
items → item
items → items item
並不能真正幫助(不管啟動item
仍然可以啟動或者生產items
),但更重要的是,它是左遞歸的,這是禁止的為LL語法。
原則上,“ new non-terminal”是正確的解決方案,但是在遞歸下降解析器中,您可能會執行以下操作:
def items():
list = [ item() ]
while couldStart(item, lookahead):
list.append(item())
return list
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.