簡體   English   中英

在Bison中是否需要對語法進行左分解?

[英]Is left-factoring of grammar necessary in Bison?

我正在使用野牛做一個解析器。 我只是想問一問,在野牛中使用語法時是否仍然需要左語法。 我嘗試給野牛一個非左偏語法,它沒有給出任何警告或錯誤,它也接受了我給解析器提供的示例語法,但是我擔心解析器可能在每個輸入中都不准確。

左因子分解是如何消除語法中的LL沖突。 由於Bison使用LALR,因此在左遞歸或任何其他LL沖突方面都沒有問題(事實上,最好使用左遞歸,因為它可以最大程度地減少堆棧需求),因此左因數分解既不是必需的,也不是理想的。

請注意,左因子分解不會破壞任何內容-野牛可以處理左因子分解的語法以及非左因子分解的語法,但是解析左因子分解的語法可能需要更多資源(內存),因此通常, 別。

編輯

您似乎對LL-vs-LR解析的工作方式以及語法結構如何影響兩者感到困惑。

LL解析是自上而下的-您僅從解析堆棧上的開始符號開始,然后在每一步中,將堆棧頂部的非終結符替換為該非終結符的某些規則右側的符號。 當堆棧頂部有一個終端時,它必須與輸入的下一個標記匹配,因此您將其彈出並使用輸入。 目標是消耗所有輸入並最終得到一個空堆棧。

LR解析是自下而上的-從一個空的堆棧開始,然后在每一步中,您都將一個令牌從輸入中復制到堆棧中(使用它),或者在堆棧頂部替換與該符號相對應的一系列符號某些規則的右側,並在規則的左側使用單個符號。 目標是消耗所有輸入並僅在堆棧上保留開始符號。

因此,對於同一個非終結符,以右側相同符號開頭的不同規則是LL解析的一個大問題-您可以用任一規則中的符號替換該非終結符,並匹配接下來的幾個輸入標記,因此您需要更多前瞻才能知道該怎么做。 但是對於LR解析,這沒有問題-您只需將令牌從輸入中移動(移動)到堆棧,然后當您到達后面的令牌時,您就可以確定匹配的右側。

LR解析往往會遇到在右側以相同令牌結尾的規則而不是以相同令牌開頭規則的問題。 在John Levine的書中的示例中,有規則“ cart_animal :: = HORSE”和“ work_animal :: = HORSE”,因此,在移動HORSE符號后,可以將其減小(替換)為“ cart_animal”或“ work_animal” 。 由於上下文允許后跟“ AND”標記,因此當下一個標記為“ AND”時,您將遇到減少/減少(LR)沖突。

事實上,情況正好相反。 LALR(1)解析器生成器生成的解析器不僅支持左遞歸,而且它們實際上在左遞歸方面更有效 具有諷刺意味的是,您可能必須從語法中重構出正確的遞歸。

權利遞歸工程; 但是,它會延遲還原,從而導致解析堆棧空間與要解析的遞歸構造的大小成比例。

例如,構建如下的Lisp樣式列表:

list : item { $$ = cons($1, nil); }
     | item list { $$ = cons($1, $2); }

表示解析器堆棧與列表的長度成正比。 在到達最右邊的item之前,不會進行還原,然后進行一系列的還原,通過一系列的cons調用從右到左構建列表。

在開始解析數據(而不是代碼)之前,數據可能會變大,您可能不會遇到此問題。

如果為左遞歸修改此列表,則可以在恆定數量的解析器堆棧中構建列表,因為該操作將是“隨手可得”。

list : item        { $$ = cons($1, nil); }
     | list item   { $$ = append($1, cons($2, nil)); }

(現在存在append搜索列表尾部的性能問題;針對該問題,存在各種與解析無關的解決方案。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM