第2章 實現一份LR(0)演算法
首先 我們寫一個前一節的例子3的文法的編譯器的翻譯器。
為了方便不懂python的讀者也能看懂程式碼的意思。我會增加大量的文字來介紹。
2.1 文法物件的定義
下面就是我們的文法物件:
grammar = {
'S' : [
RuleObject( ['S' , 'start'] )
],
'start' : [
RuleObject( ['start' ,'expression'] )
],
'expression' : [
RuleObject( ['expression','multExpression'] ),
RuleObject( ['expression','expression','PLUS','multExpression'] ),
RuleObject( ['expression','expression','DASH','multExpression'] )
],
'multExpression' : [
RuleObject( ['multExpression','subExpression' ] ),
RuleObject( ['multExpression','multExpression', 'MULT', 'subExpression'] ),
RuleObject( ['multExpression','multExpression', 'SLASH', 'subExpression'] )
],
'subExpression' : [
RuleObject( ['subExpression','LPAREN', 'expression', 'RPAREN'] ) ,
RuleObject( ['subExpression','primary' ] )
],
'primary' : [ RuleObject(['primary','NON_INTEGER_3']) ]
}
2.2 終結符和非終結符
下面是文法grammar中出現的非終結符:
nonTerminals = ['start','expression','multExpression','subExpression','primary']
下面是文法grammar中出現的終結符:
terminals = ['PLUS','DASH','MULT','SLASH','LPAREN','RPAREN','NON_INTEGER_3']
2.3規則物件的實體
下面是一個規則物件的實體:
class RuleObject(object):
def __init__(self,Item):
self.position = 0
self.expressionName = Item[0]
self.item = Item[1:]
self.pr = list(self.item)
self.pr.insert(self.position,".")
def lrNext(self):
if self.position+1 > len(self.item) :
return False
else:
self.position += 1
self.pr = list(self.item)
self.pr.insert(self.position,".")
return True
def __str__(self):
if self.item:
return "%s -> %s" % (self.expressionName," ".join(self.pr))
else:
return "%s -> <empty>" % self.expressionName
def __repr__(self):
return "LRItem(%s)" % ( str(self) )
def lrCurrent(self):
if self.position >= len(self.item) : return None
return self.item[self.position]
def __eq__(self, other):
if other.__class__ is RuleObject :
if other.expressionName == self.expressionName:
if other.item == self.item:
return True
return False
else:
return False
首先我們先說明這個類裡面重新定義了物件轉換成str和
下面是一個規則列表物件
class RuleList(list):
def __contains__(self, item):
for x in self:
if item == x :
return True
return False
2.4 LR的演算法的重要概念
以下3個概念是實現LR(0)演算法的重要部分。
goto 主要負責移動,並分解具體的非終結符。
def lr0GOTO(I,X):
J = RuleList()
for i in I:
if i.lrCurrent() == X:
i.lrNext()
J.append(copy.deepcopy(i) )
return lr0Closure(J)
item 執行主要的分析工作。
def lr0Item(G):
C = collections.deque( [ lr0Closure(G['S']) ] );
p = copy.deepcopy(C)
while True:
x = C.pop()
sysum = {}
for i in x:
if i.lrCurrent() != None:
sysum[i.lrCurrent()] = None
if x not in p : p.append(x)
if sysum == {} :
continue
for s in sysum :
sub = lr0GOTO(copy.deepcopy(x),s)
if sub not in p : C.append(copy.deepcopy(sub))
if len(C) == 0 : break
closure 分析一個文法項,並提取其中的子項形成整體的包含項。
def lr0Closure(I):
O = collections.deque(I)
p = []
while True:
x = O.pop()
if x.lrCurrent() in nonTerminals and x.lrCurrent() != x.expressionName :
for y in grammar[x.lrCurrent()]:
O.appendleft(copy.deepcopy(y))
p.append(x)
if len(O) == 0 : break
return p
2.1 文法物件的定義
下面就是我們的文法物件:
grammar = {
'S' : [
RuleObject( ['S' , 'start'] )
],
'start' : [
RuleObject( ['start' ,'expression'] )
],
'expression' : [
RuleObject( ['expression','multExpression'] ),
RuleObject( ['expression','expression','PLUS','multExpression'] ),
RuleObject( ['expression','expression','DASH','multExpression'] )
],
'multExpression' : [
RuleObject( ['multExpression','subExpression' ] ),
RuleObject( ['multExpression','multExpression', 'MULT', 'subExpression'] ),
RuleObject( ['multExpression','multExpression', 'SLASH', 'subExpression'] )
],
'subExpression' : [
RuleObject( ['subExpression','LPAREN', 'expression', 'RPAREN'] ) ,
RuleObject( ['subExpression','primary' ] )
],
'primary' : [ RuleObject(['primary','NON_INTEGER_3']) ]
}
對於不瞭解python的讀者,我做以下解釋:{}為python的字典型別 比如 { 'S' : [] } 中的'S是字典的名字 ,[]是字典的內容,內容為一個陣列。
這一章節主要定義了一個文法的結構。如果是標準的文法表述,應該如下:
為了方便我在以下每條rule上增加一個;
做為一條規則的結束標準
---------------------------------
S : S start
start : expression
;
expression : multExpression
| expression PLUS multExpression
| expression DASH multExpression
;
multExpression : subExpression
| multExpression MULT subExpression
| multExpression SLASH subExpression
;
subExpression : LPAREN expression RPAREN
| primary
;
primary : NON_INTEGER_3
;
---------------------------------
上面的規則解釋就是有優先順序別的計算器解析程式,如果稍微增加一些程式碼就可以實現基本的帶有括號和優先順序的加減乘除功能。下一節將詳細講解上面的結構。
2.2 終結符和非終結符
下面是文法grammar中出現的非終結符:
nonTerminals = ['start','expression','multExpression','subExpression','primary']
下面是文法grammar中出現的終結符:
terminals = ['PLUS','DASH','MULT','SLASH','LPAREN','RPAREN','NON_INTEGER_3']
2.3規則物件的實體
下面是一個規則物件的實體:
class RuleObject(object):
def __init__(self,Item):
self.position = 0
self.expressionName = Item[0]
self.item = Item[1:]
self.pr = list(self.item)
self.pr.insert(self.position,".")
def lrNext(self):
if self.position+1 > len(self.item) :
return False
else:
self.position += 1
self.pr = list(self.item)
self.pr.insert(self.position,".")
return True
def __str__(self):
if self.item:
return "%s -> %s" % (self.expressionName," ".join(self.pr))
else:
return "%s -> <empty>" % self.expressionName
def __repr__(self):
return "LRItem(%s)" % ( str(self) )
def lrCurrent(self):
if self.position >= len(self.item) : return None
return self.item[self.position]
def __eq__(self, other):
if other.__class__ is RuleObject :
if other.expressionName == self.expressionName:
if other.item == self.item:
return True
return False
else:
return False
首先我們先說明這個類裡面重新定義了物件轉換成str和
下面是一個規則列表物件
class RuleList(list):
def __contains__(self, item):
for x in self:
if item == x :
return True
return False
2.4 LR的演算法的重要概念
以下3個概念是實現LR(0)演算法的重要部分。
goto 主要負責移動,並分解具體的非終結符。
def lr0GOTO(I,X):
J = RuleList()
for i in I:
if i.lrCurrent() == X:
i.lrNext()
J.append(copy.deepcopy(i) )
return lr0Closure(J)
item 執行主要的分析工作。
def lr0Item(G):
C = collections.deque( [ lr0Closure(G['S']) ] );
p = copy.deepcopy(C)
while True:
x = C.pop()
sysum = {}
for i in x:
if i.lrCurrent() != None:
sysum[i.lrCurrent()] = None
if x not in p : p.append(x)
if sysum == {} :
continue
for s in sysum :
sub = lr0GOTO(copy.deepcopy(x),s)
if sub not in p : C.append(copy.deepcopy(sub))
if len(C) == 0 : break
closure 分析一個文法項,並提取其中的子項形成整體的包含項。
def lr0Closure(I):
O = collections.deque(I)
p = []
while True:
x = O.pop()
if x.lrCurrent() in nonTerminals and x.lrCurrent() != x.expressionName :
for y in grammar[x.lrCurrent()]:
O.appendleft(copy.deepcopy(y))
p.append(x)
if len(O) == 0 : break
return p
2.5 不定點原理及其講解
2.5 不定點原理及其講解
2.6 主流的LR解釋生成器的演算法
2.6 主流的LR解釋生成器的演算法
相關文章
- 第1章 LR解析過程
- JAVA + LR實現apache流媒體的效能測試JavaApache
- PPO演算法動作機率出現[0,0,0,0,0,1]的問題演算法
- 《垃圾回收的演算法與實現》第2章GC標記-清除演算法演算法GC
- 分類演算法(1)-LR邏輯迴歸演算法邏輯迴歸
- 送你一份使用k近鄰演算法實現迴歸的實用指南(附程式碼、連結)演算法
- GBDT+LR原理和實戰
- 編譯原理上機作業4——LR(0)分析的DFA生成編譯原理
- 第2章 功能實現
- Java斐波那契數列的第n項(從0開始,第0項為0,第1項是1)。Java
- 從0到1實現PromisePromise
- vue 由0到1實現Vue
- 第 0 課 問候語
- 第0篇:學習資料結構和演算法的框架思維資料結構演算法框架
- micropather實現A*演算法演算法
- 演算法strstr實現演算法
- LFU演算法實現演算法
- ARC演算法實現演算法
- 第0周學習總結
- 第0章 基礎知識
- 從0實現一個webpack loaderWeb
- 從0到1實現VueUI庫思路VueUI
- 從0實現RBAC許可權模型模型
- 從0實現一個tiny-reduxRedux
- 從0實現一個tiny react(二)React
- 從0實現一個tiny react(一)React
- LR.Net快速配置效率實用首頁
- Go 實現雪花演算法Go演算法
- 排序演算法 Java實現排序演算法Java
- php演算法實現(一)PHP演算法
- 排序演算法Java實現排序演算法Java
- 雪花演算法的實現演算法
- golang洗牌演算法實現Golang演算法
- Mahout實現的演算法演算法
- java實現Bitmap演算法Java演算法
- KMP演算法 Java實現KMP演算法Java
- 演算法-排序演算法思想及實現演算法排序
- 第 0 天/第 1 天/第 2 天:雲時代的軟體生命週期