任何人都可以給我一個LL解析與LR解析的簡單例子嗎?LL和LR解析有什麼區別?
回答
在較高的層次上,LL解析和LR解析的區別在於LL解析器從開始符號開始,嘗試應用作品到達目標字符串,而LR解析器從目標字符串開始嘗試到達回到開始符號。
LL解析是從左到右,最左端的派生。也就是說,我們從左到右考慮輸入符號並嘗試構造最左邊的派生。這是通過從開始符號開始並反覆擴展最左端的非終結符,直到到達目標字符串。 LR解析是從左到右,最右邊的派生,這意味着我們從左到右掃描並嘗試構造最右邊的派生。解析器不斷挑選輸入的子字符串,並試圖將其反轉回非終結符。
在一個LL解析,解析器連續兩個動作之間進行選擇:
- 預測:基於最左邊的非終結符和若干前瞻令牌,選擇哪個產品應該被應用到更接近輸入字符串。
- 符合:匹配最左邊的猜測終端符號和輸入的最左端未消耗符號。
作爲一個例子,考慮到本語法:
- 小號→Ë
- Ë→ T +È
- Ë→Ť
- Ť→
int
然後鑑於串int + int + int
,一個LL(2)分析器(它使用先行的兩個標記)將如下分析該字符串:
Production Input Action
---------------------------------------------------------
S int + int + int Predict S -> E
E int + int + int Predict E -> T + E
T + E int + int + int Predict T -> int
int + E int + int + int Match int
+ E + int + int Match +
E int + int Predict E -> T + E
T + E int + int Predict T -> int
int + E int + int Match int
+ E + int Match +
E int Predict E -> T
T int Predict T -> int
int int Match int
Accept
請注意,在每一個步驟中,我們看一下在我們的生產中最左邊的符號。如果它是一個終端,我們匹配它,如果它是一個非終結符,我們通過選擇一個規則來預測它將會是什麼。
在一個LR語法分析器,有兩個動作:
- 移:輸入的下一個標記添加到考慮一個緩衝。
- 減少:通過反轉生產,將此緩衝區中的終端和非終止符的集合還原到某個非終結符。你提到
Workspace Input Action --------------------------------------------------------- int + int + int Shift int + int + int Reduce T -> int T + int + int Shift T + int + int Shift T + int + int Reduce T -> int T + T + int Shift T + T + int Shift T + T + int Reduce T -> int T + T + T Reduce E -> T T + T + E Reduce E -> T + E T + E Reduce E -> T + E E Reduce S -> E S Accept
兩個解析算法(LL和LR)是:
作爲一個例子,一個LR(1)解析器(與先行的一個令牌)可以如下分析該相同的字符串已知具有不同的特徵。LL解析器傾向於更容易手動編寫,但它們不如LR解析器強大,並且接受比LR解析器更小的一組語法。 LR語法分析器有很多種(LR(0),SLR(1),LALR(1),LR(1),IELR(1),GLR(0)等),並且功能更加強大。他們也往往有更復雜的幾乎總是由工具,如yacc
或bison
。 LL語法分析器也有很多種(包括LL(*),它被ANTLR
工具使用),儘管在實踐中LL(1)是使用最廣泛的。
作爲一個無恥的插件,如果您想了解關於LL和LR解析的更多信息,我剛剛完成了一門編譯器課程的教學,並在課程網站上有some handouts and lecture slides on parsing。如果你認爲它會有用,我會很樂意詳細說明它們中的任何一個。
Josh Haberman在他的文章LL and LR Parsing Demystified聲稱LL解析直接對應於Polish Notation,而LR對應於Reverse Polish Notation。 PN和RPN之間的差是遍歷方程的二進制樹的順序:
+ 1 * 2 3 // Polish (prefix) expression; pre-order traversal.
1 2 3 * + // Reverse Polish (postfix) expression; post-order traversal.
根據哈伯曼,這說明LL和LR語法分析器之間的主要區別在於:
LL和LR解析器如何操作的主要區別是LL解析器輸出解析樹的預遍歷,LR解析器輸出後序遍歷。
對於深入的解釋,例子和結論檢查哈伯曼的article。
- 1. LL(*)與PEG解析器:有什麼區別?
- 2. 識別LL和LR語法... NOT語法分析器
- 3. 「抽象解析樹」和「解析樹」有什麼區別?
- 4. LL解析器和AST之間的區別
- 5. 爲什麼所有LL(1)語法LR(1)?
- 6. LL和LR在CFG中的對比
- 7. 解析樹和抽象語法樹有什麼區別?
- 8. 谷歌的Json解析Gson庫:JsonElement和JsonObject有什麼區別?
- 9. 解析,閱讀和lexing有什麼區別?
- 10. 解析器和掃描儀有什麼區別?
- 11. 在進程中和解析進程中解析WPAD有什麼區別?
- 12. 有什麼區別`和$(Bash中有什麼區別?
- 13. LR(1)語法和運算符優先級語法有什麼區別?
- 14. 有什麼區別? :和||
- 15. &&和||有什麼區別?
- 16. 「/」和「/ *」有什麼區別?
- 17. 有什麼區別:。!和:r!?
- 18. ==和===有什麼區別?
- 19. Appender和〜有什麼區別?
- 20. $ @和$ *有什麼區別?
- 21. is和=有什麼區別?
- 22. #.00和#。##有什麼區別?
- 23. `==`和`is`有什麼區別?
- 24. '=='和'==='有什麼區別?
- 25. /和/#/有什麼區別?
- 26. | 0和~~有什麼區別?
- 27. `&`和`ref`有什麼區別?
- 28. ==和===有什麼區別?
- 29. ==和===有什麼區別?
- 30. `{}`和`[]`有什麼區別?
你的演講幻燈片是驚人的,很容易我看到最有趣的解釋:)這是真正引起興趣的事情。 – kizzx2 2011-08-11 14:57:58
謝謝大幻燈片 – Adi 2011-12-31 06:23:16
我也要評論幻燈片!現在通過所有的人。幫助很多!謝謝! – kornfridge 2013-05-29 20:16:57