实现自底向上的分析(LR0可视化)
可视化界面
相关术语
项目
在文法产生式右部某个位置标有’ . '的产生式,称为文法的一个LR(0)项目。
- 形如 A一>.α 的项目称为初始项目;
- 形如 A->α.的项目称为归约项目(完整项目) ;
- 形如 A->α.Bβ 的项目称为待约项目(基本项目) B∈N;
- 形如 A->a.aB 的项目称为移进项目(基本项目) a∈T。
有效项目(忘了,活前缀应该是不能分割的小写字母合集)
项目A-β1.β2,对活前缀 γ= αβ1是有效的(存在规范推导 S =>*aAw => αβ1β2w)
若项目 A-β1.Bβ2,对活前缀 γ=η是有效的,且 B->.η是产生式,则项目 B->.η 对活前缀 γ= αβ1也是有效的
有效项目集,项目集规范族
文法G的某个活前缀γ的所有有效项目组成的集合,称为活前缀γ的LR(O)有效项目集。
文法G的所有有效项目集组成的集合,称为G的LR(O)项目集规范族。
项目闭包
设I是文法G的一个LR(0)项目集合,I的项目闭包closure(I)定义如下:
(1)I ∈ closure(I).
(2) 若项目A->α.Bβ ∈ closure(I),且B一>η 是G的产生式,则项目B->.η ∈ closure(I)。???
(3) closure(I)仅包含上述两条规则确定的LR(0)项目。
转移函数
若I是文法G的一个LR(0)项目集,X是G中的文法符号。
go(l, X) = closure(J) 其中J={ A -> aX .β | A -> a .Xβ ∈ l }
称函数go(I,X)为转移函数。
项目 A一ax.β 称为项目A -> α.Xβ后继
识别G的句柄的自动机
若文法G =( VT,VN, S,P),则识别G的句柄的自动机为
DFA M =(Σ=VT∪VN )
Q = G的LR(O)项目集规范族,
q0= closure( S’-.S ),
F=所有含归约项目的有效项目集组成的集合,
ε = go(,X) )。
识别活前缀的自动
若将所有状态视为终态,则识别活前缀的自动机DFA
M =(Σ=VT∪VN )
Q = G的LR(O)项目集规范族,
q0= closure( S’-.S ),
F=Q,
ε = go(,X) )。
定理
对于拓广文法G"的每一个活前缀 Y,它的有效项目集恰好是从识别 G活前缀的自动机的初态出发,经过y路径所到达的那个状态所代表的项目集合。
程序流程
获取扩广文法
def getWideGrammar():
global text_content, wideGrammar, table, pw
wideGrammar.clear()
table.clear()
ter.clear()
non_ter.clear()
pw.clear()
txt2.delete(1.0, END)
item1 = text_content[0]
s = item1.split(' ')
wideGrammar.append(s[0] + "' -> " + s[0])
for i in range(len(text_content) - 1):
item = text_content[i]
head = item.split(' ')[0]
for j in range(len(item) - 1):
if item[j] == '-' and item[j + 1] == '>':
tail = item[j + 2:]
group = tail.split('|')
for g in group:
wideGrammar.append(head + " -> " + g.strip())
count = 0
for item in wideGrammar:
txt2.insert(INSERT, str(count) + ' ' + item + "\n")
count += 1
txt2['state'] = DISABLED
for i in range(len(wideGrammar)):
wideGrammar[i] = wideGrammar[i].replace('ε', '')
print(wideGrammar)
togather(wideGrammar)
print(ter)
print(non_ter)
pw = addPoint(wideGrammar)
print(pw)
toTable(pw)
print(table)
求闭包
# 求闭包
def getClosure(core):
"""
:rtype: object
"""
global table
tem = []
for c in core:
tem.append(' '.join(c))
for c in core:
pos = c.index('.')
if pos != len(c) - 1 and c[pos + 1] in non_ter:
if c[