编译原理正规文法与有限自动机转换

截图不想放了,我累了。python代码是正确的

【实验名称】                正规文法与有限自动机的转换    

【实验目的】

 从文件打开,若文本内为正规文法,则转化为有限自动机,若是合法自动机,则转化为正规文法。

【实验原理】

 1.文法转自动机

(1)自动机的字母表与文法的终结符集相同。

(2)为文法中的每个非终结符生成自动机的一个状态,文法的开始符是S,自动机的开始状态S。

(3)增加一个新状态Z,作为自动机的终态。

(4)对文法中的形如A→aB的规则,构造自动机f(A,t)=B。

(5)对文法中形如A→t的产生式,构造自动机f(A,t)=Z。

-----------------------------------------------

2.自动机转文法

对自动机f(A,t)=B,可写成一个产生式:A→tB

对终止状态Z,增加一个产生式:Z→ε

【实验内容】

1.文法的分割(再上一次实验中也有)

#按照“|”语法分割

def splitgram(gram,K,W):

    length=len(gram)

    left=''

    index=0

    while index<length:

        gramindex=gram[index]

        lens=len(gramindex)

        if gramindex[0] not in K:

            K.append(gramindex[0])

            del gram[index]

            j=3

            while j<lens:

                if gramindex[j]!='|':

                    left=left+gramindex[j]

                if gramindex[j]=='|':

                    strs=gramindex[0]+'->'+left

                    gram.insert(index,strs)

                    left=''

                j=j+1

            if  left!='':

                strs=gramindex[0]+'->'+left

                gram.insert(index,strs)

                left=''

        index=index+1

        length=len(gram)


2.DFA的打印

def scangram(gram,K,W):

    Kindex=0

    Wdict=dict()

    print('对应的DFA如下:')

    while len(gram)>0:

        gram0=gram[0]

        if gram0[3] not in W:

            W.append(gram0[3])

        if len(gram0)==5:

            printres(gram0[0],gram0[3],gram0[4])

        else:

            if gram0[3] in Wdict:

                strs=Wdict[gram0[3]]

                printres(gram0[0],gram0[3],strs)

            else:

                strs=Klist[Kindex]

                Kindex=Kindex+1

                Wdict[gram0[3]]=strs

                printres(gram0[0],gram0[3],strs)

        del gram[0]


3.自动机转文法

def splitFA(FA,Vt,Vn):

    length=len(FA)

    index=0

    while index<length:

        FAindex=FA[index]

        if FAindex[2] not in Vt:

            Vt.append(FAindex[2])

        del FA[index]

        left=FAindex[2]

        right=FAindex[4]+FAindex[7]

        strs=left+'->'+right

        FA.insert(index,strs)

        index=index+1

        length=len(FA)


#这时候的FA实际上已经由上一步存储为文法了

def scanFA(FA,Vt,Vn):

    length=len(FA)

    index=0

    while index<length:

        FAindex=FA[index]

        if FAindex[3] not in Vn:

            Vn.append(FAindex[3])

        if len(FAindex)>4 and FAindex[4] not in Vt:

            strs=FAindex[0]+'->'+FAindex[3]

            del FA[index]

            FA.insert(index,strs)

        else:

            index=index+1

        length=len(FA)


4.合并文法中有相同终结符号的语句

def combineFA(FA):

    length=len(FA)

    indexi=0

    while indexi<length:

        FAKi=FA[indexi][0]

        lens=len(FA[indexi])-3

        strsi=''

        for i in range(lens):

           strsi=strsi+FA[indexi][3+i]

        indexj=0

        while indexj<length:

            FAKj=FA[indexj][0]

            if indexi!=indexj and FAKi==FAKj:

                lens=len(FA[indexj])-3

                strsj=''

                for j in range(lens):

                    strsj=strsj+FA[indexj][3+j]

                del FA[indexj]

                strs=FAKi+'->'+strsi+'|'+strsj

                del FA[indexi]

                FA.insert(indexi,strs)

                length=len(FA)

                lens=len(FA[indexi])-3

                strsi=''

                for i in range(lens):

                    strsi=strsi+FA[indexi][3+i]

            else:

                indexj=indexj+1

        indexi=indexi+1


5.打印


def printFA(FA,Vt,Vn):

    print('对应的左线性RG如下:')

    length=len(FA)

    for i in range(length):

        print(FA[i])

    print('其中终结符集Vt为:')

    print(Vt)

    print('其中非终结符集Vn为:')

    print(Vn)

【小结或讨论】

这次的实验和上课的要求还是有很多不一样的,上课的要求比较高,要求进行自动机的确定化,最小化。在实验中都使用了左线性文法,没有考虑比较困难的情况。核心内容就是两个部分的转换:一个是形如“A->aB”到“f(A,a)=B”的转换,另一个是自动机的读取转回为文法。

【实验截图】

[if !supportLists]1.  [endif]txt文件中的内容


[if !supportLists]2.  [endif]功能演示

[if !supportLists]3.  [endif]代码



# -*- coding:

utf-8 -*-

"""

Created on Sat

May 25 20:55:21 2019


@author: 培风

"""


'''

1.RG转FA

(1)M的字母表与G的终结符集相同。

(2)为G中的每个非终结符生成M的一个状态,G的开始符S是M的开始状态S。

(3)增加一个新状态Z,作为M的终态。

(4)对G中的形如A→tB的规则,构造M的一个转换函数f(A,t)=B。

(5)对G中形如A→t的产生式,构造M的一个转换函数f(A,t)=Z。

-----------------------------------------------

2.FA转RG

对转换函数f(A,t)=B,可写成一个产生式:A→tB

对可接受状态Z,增加一个产生式:Z→ε

'''


Klist=['A']


#按照“|”语法分割

def splitgram(gram,K,W):

    length=len(gram)

    left=''

    index=0

    while index<length:

        gramindex=gram[index]

        lens=len(gramindex)

        if gramindex[0] not in K:

            K.append(gramindex[0])

            del gram[index]

            j=3

            while j<lens:

                if gramindex[j]!='|':

                    left=left+gramindex[j]

                if gramindex[j]=='|':

                    strs=gramindex[0]+'->'+left

                    gram.insert(index,strs)

                    left=''

                j=j+1

            if  left!='':

                strs=gramindex[0]+'->'+left

                gram.insert(index,strs)

                left=''

        index=index+1

        length=len(gram)


#DFA打印为形如f(A,b)->B类型

def printres(X,Y,Z):

    print('f(%s,%s)=%s'%(X,Y,Z))


#字典存储打印DFA 

def scangram(gram,K,W):

    Kindex=0

    Wdict=dict()

    print('对应的DFA如下:')

    while len(gram)>0:

        gram0=gram[0]

        if gram0[3] not in W:

            W.append(gram0[3])

        if len(gram0)==5:

            printres(gram0[0],gram0[3],gram0[4])

        else:

            if gram0[3] in Wdict:

                strs=Wdict[gram0[3]]

                printres(gram0[0],gram0[3],strs)

            else:

                strs=Klist[Kindex]

                Kindex=Kindex+1

                Wdict[gram0[3]]=strs

                printres(gram0[0],gram0[3],strs)

        del gram[0]


#列表存储自动机“f(S,a)=A”               

def splitFA(FA,Vt,Vn):

    length=len(FA)

    index=0

    while index<length:

        FAindex=FA[index]

        if FAindex[2] not in Vt:

            Vt.append(FAindex[2])

        del FA[index]

        left=FAindex[2]

        right=FAindex[4]+FAindex[7]

        strs=left+'->'+right

        FA.insert(index,strs)

        index=index+1

        length=len(FA)


#这时候的FA实际上已经由上一步存储为文法了

def scanFA(FA,Vt,Vn):

    length=len(FA)

    index=0

    while index<length:

        FAindex=FA[index]

        if FAindex[3] not in Vn:

            Vn.append(FAindex[3])

        if len(FAindex)>4 and FAindex[4] not in Vt:

            strs=FAindex[0]+'->'+FAindex[3]

            del FA[index]

            FA.insert(index,strs)

        else:

            index=index+1

        length=len(FA)


#合并有相同非终结符的

def combineFA(FA):

    length=len(FA)

    indexi=0

    while indexi<length:

        FAKi=FA[indexi][0]

        lens=len(FA[indexi])-3

        strsi=''

        for i in range(lens):

           strsi=strsi+FA[indexi][3+i]

        indexj=0

        while indexj<length:

            FAKj=FA[indexj][0]

            if indexi!=indexj and FAKi==FAKj:

                lens=len(FA[indexj])-3

                strsj=''

                for j in range(lens):

                    strsj=strsj+FA[indexj][3+j]

                del FA[indexj]

                strs=FAKi+'->'+strsi+'|'+strsj

                del FA[indexi]

                FA.insert(indexi,strs)

                length=len(FA)

                lens=len(FA[indexi])-3

                strsi=''

                for i in range(lens):a

                    strsi=strsi+FA[indexi][3+i]

            else:

                indexj=indexj+1

        indexi=indexi+1


#打印自动机

def printFA(FA,Vt,Vn):

    print('对应的左线性RG如下:')

    length=len(FA)

    for i in range(length):

        print(FA[i])

    print('其中终结符集Vt为:')

    print(Vt)

    print('其中非终结符集Vn为:')

    print(Vn)


#功能选择:1.正规文法转自动机 2.自动机转正规文法

n=int(input('选择1.左线性RG转FA 2.FA转左线性RG\n'))

if n==1:

    fp=open('grammar.txt','r')

    print('读入的左线性正规文法为:')

    gram=[]

    while True:

        line=fp.readline()

        line=line.strip('\n')

        if line=='':

            break

        else:

            gram.append(line)

            print(line)

    K=[] #终结符

    W=[] #非终结符

    splitgram(gram,K,W)

    scangram(gram,K,W) #打印DFA

    print('其中终结符集K为:')

    print(K)

    print('其中非终结符集W为:')

    print(W)

elif n==2:

    fp=open('FA.txt','r')

    print('读入的FA为:')

    FA=[]

    while True:

        line=fp.readline()

        line=line.strip('\n')

        if line=='':

            break

        else:

            FA.append(line)

            print(line)

    Vt=[]

    Vn=[]

    splitFA(FA,Vt,Vn)

    scanFA(FA,Vt,Vn)

    combineFA(FA)

    printFA(FA,Vt,Vn)

else:

    print("输入无效")

你可能感兴趣的:(编译原理正规文法与有限自动机转换)