第1章 LR解析過程
LR解析過程
1.1 LR解析過程
這篇章節主要幫你瞭解LR分析的過程。
關於詞法分析部分我們採用ply的lexer進行分析,文法分析部分我們自己來完成。
LR中的技術名詞
首先我們瞭解一下文法分析中涉及到的技術名詞。
歸約 Reduction (complexity) : 在自底向上語法分析器中,利用A->ß的語法分析樹上邊緣種的ß替代A,從而縮減語法樹上邊緣的做法。
移動 shift
從左像右移動,每移動一步,呼叫GOTO,然後使用Closure計算。
state 為分析器的狀態。分析器每做一個動作都會從一個狀態轉換到另一個狀態。每個狀態包括shift和redure
Action 和 GOTO 表中包含了 分為Shift和redure兩種動作,shift是移進動作,redure是歸約動作,在ply中Action表包含了所有終結符的動作集合,GOTO表裡麵包含了所有非終結符的動作集合。
解析過程
下面是解析過程的圖記。
由圖可以看出LR的歸約過程是從左向右讀取,從右向左歸約。這一節我們先簡單瞭解這些,下面一節會深入一點講訴歸約的BNF如何構建更適合LALR解析器.
參考書籍和內容
- ”LR parser - From Wikipedia, the free encyclopedia” http://en.wikipedia.org/wiki/LR_parser
- "編譯器設計(第2版) 人民郵電出版社"
1.2 LR編寫grammar中的問題和解決方法
上一節,簡單敘述了LR解析過程(使用ply),下面說一下關於BNF的典型衝突如何在LR中解決。
這章節主要講解如何避免Conflicts
Conflicts一般分為2種錯誤
shift/reduce錯誤
這種錯誤是因為 分析器在這種情況下不知道是歸約還是移進導致的。
redure/redure錯誤
這種錯誤是因為,解析器在解析棧中規則時發現有多個規則可以進行歸約。rejected rule
會指出跟哪個rule衝突
我們首先舉個例子。
例子1
文法如下: 這是一個簡單的解析
"<><><><>"
"<>"
""
class classnam {}
def p_start(p):
'''
start : typeArguments
'''
def p_typeArguments(p):
'''
typeArguments : typeArgument
| typeArguments typeArgument
'''
def p_typeArgument(p):
'''
typeArgument : LESS MORE
| empty
'''
def p_empty( p ):
'''empty : '''
這是產生的錯誤。
WARNING:
WARNING: Conflicts:
WARNING:
WARNING: shift/reduce conflict for LESS in state 0 resolved as shift
WARNING: shift/reduce conflict for LESS in state 2 resolved as shift
WARNING: reduce/reduce conflict in state 2 resolved using rule (start -> typeArguments)
WARNING: rejected rule (empty -> <empty>) in state 2
那麼下面看看如何來解決這個問題。
def p_start(p):
'''
start : typeArguments
| empty
'''
def p_typeArguments(p):
'''
typeArguments : typeArgument
| typeArguments typeArgument
'''
def p_typeArgument(p):
'''
typeArgument : LESS MORE
'''
def p_empty( p ):
'''empty : '''
這個問題出現在
def p_typeArgument(p):
'''
typeArgument : LESS MORE
| empty
'''
身上,因為empty比較特殊可以告訴yacc可以reduce,因為結束了。而LESS還需要shift.
而在 typeArgument 身上也出現了一個問題就是到底 typeArgument是redure成empty還是 LESS MORE形式。
例子2
def p_start(p):
'''
start : typeArguments
'''
def p_typeArguments(p):
'''
typeArguments : typeArgument
| typeArguments typeArgument
'''
def p_typeArgument(p):
'''
typeArgument : LESS MORE
| list
'''
def p_list(p):
'''
list : LESS MORE
'''
def p_empty( p ):
'''empty : '''
這個問題比較是比較典型的redure衝突
出現在 typeArgument和list的衝突上。
WARNING:
WARNING: Conflicts:
WARNING:
WARNING: reduce/reduce conflict in state 7 resolved using rule (typeArgument -> LESS MORE)
WARNING: rejected rule (list -> LESS MORE) in state 7
WARNING: Rule (list -> LESS MORE) is never reduced
這種情況就是因為在一個規則樹中出現了兩個同樣的規則在同一個裡面。
例子3
這個例子算是一個較為經典的shift/redure的問題。
expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression
| LPAREN expression RPAREN
| NUMBER
如果我們不只用優先順序來定義,那麼我們可以如下方法解決優先順序別的問題:
def p_start(p):
'''
start : expression
'''
def p_expression(p):
'''
expression : multExpression
| expression PLUS multExpression
| expression MINUS multExpression
'''
def p_multExpression(p):
'''
multExpression : subExpression
| multExpression TIMES subExpression
| multExpression DIVIDE subExpression
'''
def p_subExpression(p):
'''
subExpression : LPAREN expression RPAREN
| primary
'''
def p_primary(p):
'''
primary : NUMBER
'''
在java中也可以使用如上方法來定義一個expression來完成整個expression樹的解析過程。因為過於複雜,所以這裡不就寫了,有興趣的可以看java 7 lanaguage
上面3個例子都比較典型,基本能把大部分書寫LR文法的時候遇到的問題解決掉。
下一章,我們講解一下LR的演算法是如何構建的,並寫一個稍微簡單些解析器和表構建演算法來學習一下。
1.0 LR技術簡介
1.0 LR技術簡介
相關文章
- 第3步: 域名解析伺服器的過程(DNS)伺服器DNS
- DNS解析過程原理DNS
- SQL 解析的過程SQL
- 域名解析過程
- DNS域名解析過程DNS
- docker 容器中解析 PHP 過程DockerPHP
- MapReduce 執行全過程解析
- DNS的原理和解析過程DNS
- OpenPose訓練過程解析(2)
- 轉:DNS解析過程詳解DNS
- 網路 - DNS解析過程原理DNS
- mysql儲存過程案例解析MySql儲存過程
- DNS解析全過程及原理DNS
- Socket和TCP連線過程解析TCP
- go dns解析過程及調優GoDNS
- JVM系列(三):JVM建立過程解析JVM
- 軟體測試面試過程解析面試
- openGauss核心:SQL解析過程分析SQL
- Android啟動過程深入解析Android
- 解讀JSP的解析過程JS
- select 語句的解析過程
- 【數理知識】第2章-Poisson 過程-《隨機過程》方兆本隨機
- JVM 深入學習:Java 解析 Class 檔案過程解析JVMJava
- Laravel 從 $request 到 $response 的過程解析Laravel
- 從Chrome原始碼看DNS解析過程Chrome原始碼DNS
- 中介軟體的引數解析過程
- TypeScript 裡的 module 解析過程 - Module ResolutionTypeScript
- 瀏覽器EventLoop執行過程解析瀏覽器OOP
- Dubbo服務呼叫過程原始碼解析④原始碼
- 以太坊啟動過程原始碼解析原始碼
- Dubbo中暴露服務的過程解析
- HDFS讀寫過程解析(R1)
- Lucene原始碼解析--搜尋過程<二>原始碼
- 解析實時的DB time過程分析
- Oracle-解析啟動的全過程Oracle
- Tomcat啟動過程(二):EndPoint解析Tomcat
- Universal-Image-Loader原始碼解解析---display過程 + 獲取bitmap過程原始碼
- 《編譯原理》LR 分析法與構造 LR(1) 分析表的步驟 - 例題解析編譯原理