删除wan文件,加入syntax的测试代码
This commit is contained in:
parent
7b0fb55e00
commit
4f28299032
@ -491,3 +491,7 @@ class Syntax:
|
||||
self.__grammar_tree = grammar_tree
|
||||
|
||||
return True
|
||||
if __name__ == '__main__':
|
||||
obj = LL1Generator()
|
||||
obj.compile()
|
||||
obj.show_me_what_you_got("LL1Table_id.csv",show_by_id=True)
|
237
syntax/wan.py
237
syntax/wan.py
@ -1,237 +0,0 @@
|
||||
import csv
|
||||
|
||||
from rule import *
|
||||
class LL1Generator:
|
||||
def __init__(self):
|
||||
self.NTS = [_ for _ in non_terminal_sign_type]
|
||||
self.NTS_sz = len(self.NTS)
|
||||
self.NTSmp = {_:idx for idx,_ in enumerate(self.NTS)}
|
||||
self.TS = [_ for _ in terminal_sign_type]
|
||||
self.TS_sz = len(self.TS)
|
||||
self.TSmp = {_:idx for idx,_ in enumerate(self.TS)}
|
||||
self.tb = [[None for __ in range(self.TS_sz)] for _ in range(self.NTS_sz)]
|
||||
self.firsts = [set() for _ in range(self.NTS_sz)]
|
||||
self.follows = [set() for _ in range(self.NTS_sz)]
|
||||
self.first_debug = False
|
||||
self.first_debug_cnt = 0
|
||||
self.follow_debug = False
|
||||
self.follow_debug_cnt = 0
|
||||
def compile(self):
|
||||
self.calculate_firsts()
|
||||
self.calculate_follows()
|
||||
success = self.gen_tb()
|
||||
|
||||
return success
|
||||
def print_firsts(self):
|
||||
for idx,_ in enumerate(self.firsts):
|
||||
print(f"{self.NTS[idx]}:")
|
||||
print(self.firsts[idx])
|
||||
|
||||
def print_follows(self):
|
||||
for idx,_ in enumerate(self.follows):
|
||||
print(f"{self.NTS[idx]}:")
|
||||
print(self.follows[idx])
|
||||
|
||||
def is_TS(self,item):
|
||||
return self.TSmp.get(item) is not None
|
||||
|
||||
def is_NTS(self,item):
|
||||
return self.NTSmp.get(item) is not None
|
||||
|
||||
def first_set(self,tp):
|
||||
return self.firsts[self.NTSmp.get(tp)]
|
||||
|
||||
def first_insert(self,l,item):
|
||||
or_sz = len(self.first_set(l))
|
||||
self.first_set(l).add(item)
|
||||
return or_sz < len(self.first_set(l))
|
||||
|
||||
def follow_set(self,tp):
|
||||
return self.follows[self.NTSmp.get(tp)]
|
||||
|
||||
def follow_insert(self,l,item):
|
||||
or_sz = len(self.follow_set(l))
|
||||
self.follow_set(l).add(item)
|
||||
return or_sz < len(self.follow_set(l))
|
||||
|
||||
def l_r_scan(self,lst):
|
||||
l = set()
|
||||
if len(lst) == 0:
|
||||
l.add('empty')
|
||||
|
||||
for idx,_ in enumerate(lst):
|
||||
f = False
|
||||
if self.is_TS(_):
|
||||
l.add(_)
|
||||
else:
|
||||
for __ in self.first_set(_):
|
||||
if __ =='empty':
|
||||
f =True
|
||||
if __ != 'empty' or (__ =='empty' and idx==len(lst)-1):
|
||||
l.add(__)
|
||||
if not f:
|
||||
break
|
||||
return l
|
||||
|
||||
def calculate_firsts(self):
|
||||
f = True
|
||||
while f:
|
||||
f = False
|
||||
for _ in productions:
|
||||
l = _.left.type
|
||||
r = [__.type for __ in _.right]
|
||||
if len(r)==0:
|
||||
if self.first_insert(l,'empty'):
|
||||
if self.first_debug:
|
||||
self.first_debug_cnt+=1
|
||||
print(f"第{self.first_debug_cnt}次推导: {l}->{' '.join(r)} : 添加empty")
|
||||
f = True
|
||||
elif self.is_TS(r[0]):
|
||||
if self.first_insert(l,r[0]):
|
||||
if self.first_debug:
|
||||
self.first_debug_cnt+=1
|
||||
print(f"第{self.first_debug_cnt}次推导: {l}->{' '.join(r)} : 添加{r[0]}")
|
||||
f = True
|
||||
else:
|
||||
# 此时就是非终结符了
|
||||
# 将所有该非终结符的first集元素加入到左部的first集
|
||||
for _ in self.first_set(r[0]):
|
||||
if self.first_insert(l,_):
|
||||
if self.first_debug:
|
||||
self.first_debug_cnt += 1
|
||||
print(f"第{self.first_debug_cnt}次推导 : {l}->{' '.join(r)} : 添加{_}")
|
||||
f = True
|
||||
for i in range(0,len(r)):
|
||||
# 如果是非终结符
|
||||
if self.is_NTS(r[i]):
|
||||
# 如果该非终结符的first里有空
|
||||
if 'empty' in self.first_set(r[i]):
|
||||
# 如果是最后一个
|
||||
if i == len(r)-1:
|
||||
if self.first_insert(l,'empty'):
|
||||
if self.first_debug:
|
||||
self.first_debug_cnt += 1
|
||||
print(f"第{self.first_debug_cnt}次推导 : {l}->{' '.join(r)} : 添加empty")
|
||||
|
||||
f = True
|
||||
else:
|
||||
# 下一个是终结符
|
||||
if self.is_TS(r[i+1]):
|
||||
if self.first_insert(l,r[i+1]):
|
||||
if self.first_debug:
|
||||
self.first_debug_cnt += 1
|
||||
print(f"第{self.first_debug_cnt}次推导 : {l}->{' '.join(r)} : 添加{r[i+1]}")
|
||||
|
||||
f = True
|
||||
# 下一个为非终结符
|
||||
elif self.is_NTS(r[i+1]):
|
||||
for _ in self.first_set(r[i+1]):
|
||||
if self.first_insert(l,_):
|
||||
if self.first_debug:
|
||||
self.first_debug_cnt += 1
|
||||
print(
|
||||
f"第{self.first_debug_cnt}次推导 : {l}->{' '.join(r)} : 添加{_}")
|
||||
|
||||
f = True
|
||||
else:
|
||||
print("error: TS/NTS type.")
|
||||
else:
|
||||
break
|
||||
else:
|
||||
break
|
||||
|
||||
def calculate_follows(self):
|
||||
f = True
|
||||
while f:
|
||||
f = False
|
||||
for _ in productions:
|
||||
l = _.left.type
|
||||
r= [__.type for __ in _.right]
|
||||
if l == 'program':
|
||||
if self.follow_insert(l,'pound'):
|
||||
if self.follow_debug:
|
||||
self.follow_debug_cnt +=1
|
||||
print(f"第{self.follow_debug_cnt}次推导:{l} -> {' '.join(r)} , {l} add pound")
|
||||
f = True
|
||||
for i in range(0,len(r)):
|
||||
if self.is_NTS(r[i]):
|
||||
if i == len(r)-1:
|
||||
for _ in self.follow_set(l):
|
||||
if self.follow_insert(r[i],_):
|
||||
if self.follow_debug:
|
||||
self.follow_debug_cnt += 1
|
||||
print(f"第{self.follow_debug_cnt}次推导:{l} -> {' '.join(r)} , {r[i]} add {_}")
|
||||
f = True
|
||||
else:
|
||||
empty_find = False
|
||||
for __ in self.l_r_scan(r[i+1:]):
|
||||
if __=='empty':
|
||||
empty_find = True
|
||||
elif self.follow_insert(r[i],__):
|
||||
if self.follow_debug:
|
||||
self.follow_debug_cnt += 1
|
||||
print(f"第{self.follow_debug_cnt}次推导:{l} -> {' '.join(r)} , {r[i]} add {__}")
|
||||
f = True
|
||||
if empty_find:
|
||||
for _ in self.follow_set(l):
|
||||
if self.follow_insert(r[i],_):
|
||||
if self.follow_debug:
|
||||
self.follow_debug_cnt += 1
|
||||
print(
|
||||
f"第{self.follow_debug_cnt}次推导:{l} -> {' '.join(r)} , {r[i]} add {l}")
|
||||
f = True
|
||||
def select(self,l):
|
||||
f = False
|
||||
for _ in self.l_r_scan(l):
|
||||
if _ =='empty':
|
||||
f= True
|
||||
break
|
||||
if f:
|
||||
return
|
||||
else:
|
||||
return
|
||||
|
||||
def insert_tb(self,_,r):
|
||||
if self.tb[self.NTSmp[_.left.type]][self.TSmp[r]] != None and self.tb[self.NTSmp[_.left.type]][self.TSmp[r]] != _:
|
||||
print(f"wa :{_.l.type}->{[__.type for __ in _.r]} : {r}")
|
||||
self.tb[self.NTSmp[_.left.type]][self.TSmp[r]] = _
|
||||
|
||||
def gen_tb(self):
|
||||
for _ in productions:
|
||||
l = _.left.type
|
||||
r = [_.type for _ in _.right]
|
||||
|
||||
empty_find = False
|
||||
for __ in self.l_r_scan(r):
|
||||
if __ =='empty':
|
||||
empty_find = True
|
||||
else:
|
||||
self.insert_tb(_,__)
|
||||
if empty_find:
|
||||
for __ in self.follow_set(l):
|
||||
self.insert_tb(_,__)
|
||||
def get_production(self,row,col):
|
||||
return self.tb[self.NTSmp[row][col]]
|
||||
|
||||
def show_me_what_you_got(self,file,show_by_id=False):
|
||||
|
||||
l = ['NTS\\TS']
|
||||
for _ in self.TS:
|
||||
l.append(_)
|
||||
ll = [l]
|
||||
for idx,_ in enumerate(self.tb):
|
||||
l = [self.NTS[idx]]
|
||||
for __ in _:
|
||||
if __ != None:
|
||||
l.append(__.str[int(show_by_id)])
|
||||
else:
|
||||
l.append(' ')
|
||||
ll.append(l)
|
||||
with open(file,'w',newline='')as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerows(ll)
|
||||
|
||||
|
||||
obj = LL1Generator()
|
||||
obj.compile()
|
||||
obj.show_me_what_you_got("LL1Table_id.csv",show_by_id=True)
|
Loading…
Reference in New Issue
Block a user