3-1. 构造上下文无关文法用以产生:
(a) 有相同数目的0 和1 的所有0, 1 符号串。
(b) {a1a2…anan…a2a1|ai∈{0,1}, 1≤ i ≤n}。
(a)解题思路:L(G) ={},
,
P: S->0S1|, G={{S},{0,1},P,S}
(b)
P:S->0S0|1S1|, G={{S},{0,1},P,S}
3-2. 有以下文法:G = ({S,B,C},{a,b,c},P, S),其中:P:
1)S → aSBC | abC,
2)CB → BC,
3)bB → bb,
4)bC → bc,
5)cC → cc,
求L(G)=?
一步步推导可得L(G) ={},
,
3-3. 设文法G 由如下规则定义:
S → AB A → Aa|bB
B → a|Sb
给出下列句子形式的派生树:
(1) baabaab (2) bBABb
(1)
(2)
3-4. 写一个程序模拟一个确定性的PDA。
#-------------------------------------------------------------------------------
# Name: PDA
# Purpose:
#
# Author: nkenen
#
# Created: 18/02/2020
# Copyright: (c) postgres 2020
# Licence: <your licence>
#-------------------------------------------------------------------------------
#构造下推自动器PDA
#确定性和非确定由规则确定和非确定来确定
#当转移时确定只有一个状态为确定性,否则为非确定性
import random
#PDA的栈
class Stack(object):
def __init__(self):
self.list = []
def is_empty(self):
return self.list == []
def push(self,item):
self.list.append(item)
def pop(self):
if self.is_empty():
return
else:
return self.list.pop()
def top(self):
if self.is_empty():
return
else:
return self.list[-1]
#PDA的跳转规则,由两个列表映射
class Rule(object):
def __init__(self):
self.input3p = []#输入条件
self.output2p = []#输出规则
def copy(self,other_rule):
self.input3p = list(other_rule.input3p)
self.output2p = list(other_rule.output2p)
def append(self,lsti,lsto):
self.input3p.append(lsti)#增加条件
self.output2p.append(lsto)#与之对应增加输出规则
def out(self,lst):
index = 0
index = self.input3p.index(lst)#找到对应规则定位
return self.output2p[index]#输出映射规则
def clear(self):
self.input3p.clear()
self.output2p.clear()
#PDA结构
class PDA(object):
def __init__(self,Input,sigma,Q,Gamma,Belta,q0,z0,F):
self.Input = Input
self.Sigma =sigma
self.Q = Q
self.Gamma = Gamma
self.rule = Rule()
self.rule.copy(Belta)
self.stack = Stack()
self.q0 = q0
self.z0 = z0
self.F = F
def ruleappend(self,qi,ai,zi,qo,zo):
self.rule.append(qi,ai,zi,qo,zo)
#下一次跳转条件
def nextrule(self,lst):
#(qo,zo)
return self.rule.out(lst)
#该函数为本次PDA的对应操作函数
#若为不同的规则不同的输入字符串需要修改
def PushDownString(self):
q = self.q0
zi = None
zo = self.z0
for i in range(len(self.Input)+1):
if q == 1:
if zi == self.stack.top():
self.stack.pop()
zi = self.stack.top()
elif q == 0 and zo != None:
self.stack.push(zo)
zi = None
print(self.Input[i:],q,self.stack.list)
if i < len(self.Input):
[q,zo] = self.nextrule([q,self.Input[i],zi])
else:
self.stack.pop()
class Lanug(object):
def __init__(self,Gamma):
self.string = 'c'
self.Gamma = Gamma
def create(self,len,num):
w = ''
for _ in range(len):
i = random.randint(0,num)
w += self.Gamma[i]
return w+self.string+w[::-1]
#该程序只是模拟一个确定性pda题目的解题步骤
#就是课程ppt上的一个例题,算不算模拟了PDA我也不知道
def main():
sigma = ['a','b','c']
Q = [0,1]
Gamma = {'A','B'}
Belta = Rule()
q0 = 0
z0 = '#'
F = {1}
L_creater = Lanug(['a','b','c'])
Input = L_creater.create(20,1)
Belta.append([0,'a',None],[0,'A'])
Belta.append([0,'b',None],[0,'B'])
Belta.append([0,'c',None],[1,None])
Belta.append([1,'a','A'],[1,None])
Belta.append([1,'b','B'],[1,None])
pda = PDA(Input,sigma,Q,Gamma,Belta,q0,z0,F)
pda.PushDownString()
pass
if __name__ == '__main__':
main()
3-5. 写一个程序以正则文法G 作为输入,构造G 相应的有限自动机。
#-------------------------------------------------------------------------------
# Name: NFA
# Purpose:
#
# Author: nkenen
#
# Created: 18/02/2020
# Copyright: (c) postgres 2020
# Licence: <your licence>
#-------------------------------------------------------------------------------
class Reggram(object):
def __init__(self,Vn=[],Vt=[],P={},S=None):
self.Vn = Vn
self.Vt = Vt
self.P = P
self.S = S
#打印函数
def Print(self):
print("正则文法G:")
print("VN =",self.Vn)
print("VT =",self.Vt)
print("P =",self.P)
print("S =",self.S)
class Delta(object):
def __init__(self):
self.inputp = []
self.outputp = []
def copy(self,other_delta):
self.inputp = list(other_delta.inputp)
self.outputp = list(other_delta.outputp)
def append(self,lsti,lsto):
self.inputp.append(lsti)
self.outputp.append(lsto)
#映射的状态空间增值
def varappend(self,lst,input):
index = 0
index = self.inputp.index(lst)
self.outputp[index].append(input)
def out(self,lst):
index = 0
index = self.inputp.index(lst)
return self.outputp[index]
def clear(self):
self.inputp.clear()
self.outputp.clear()
def Print(self):
for i in range(len(self.inputp)):
print("δ",self.inputp[i],"=",self.outputp[i])
#注意:DFA与NFA区别在于转移规则是否对应唯一状态
#在程序我就直接用的NFA标注,感觉DFA就是NFA一种特殊情况
class NFA(object):
def __init__(self,Sigma=[],Q=[],delta=Delta(),q0=None,F=[]):
self.Sigma = Sigma
self.Q = Q
self.delta=delta
self.q0=q0
self.F=F
#将文法转换成自动机的函数
#根据转化规则
def gramtonfa(self,G=Reggram()):
self.Sigma = list(G.Vt)
self.Q = list(G.Vn)
self.Q.append('T')
self.q0 = 'S'
if None in G.P['S']:
self.F.append('S')
self.F.append('T')
else:
self.F.append('T')
for vn in G.Vn:
if len(vn) ==1:
for vt in G.Vt:
flag = 1
self.delta.append([vn,vt],[])
for i in G.P[vn]:
if i!= None and len(i) == 1:
if i[0] == vt:
if flag == 1:
self.delta.varappend([vn,vt],'T')
flag = 0
elif i!= None and len(i) > 1:
if i[0] == vt:
if i[1] in G.Vn:
self.delta.varappend([vn,vt],i[1])
for vt in G.Vt:
self.delta.append(['T',vt],[])
def Print(self):
print("正则文法G相应的有限自动机M:")
print("∑ =",self.Sigma)
print("Q =",self.Q)
self.delta.Print()
print("q0 =",self.q0)
print("F =",self.F)
def main():
#第三张ppt的正则转化例题
G = Reggram(['S','B'],['a','b'],{'S':['aB'],'B':['bS','aB','a']},'S')
G.Print()
M = NFA()
M.gramtonfa(G)
M.Print()
pass
if __name__ == '__main__':
main()