编译原理实验文法的判断

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

文法类型的判断和推导序列的生成

目录

一、实验名称 (2)

二、实验目的 (2)

三、实验原理 (2)

1、文法G定义为四元组(Vn,Vt,P,S) (2)

2、文法类型的判断 (2)

四、实验思路 (2)

1、接受产生式 (3)

2、文法类型的判断 (3)

3、将文法以四元组形式输出 (4)

五、实验小结 (4)

1、文法类型的判断条件 (4)

2、产生式的存储问题 (5)

3、文法以四元组形式输出问题 (5)

六、附件 (5)

1、源代码 (5)

2、运行结果截图 (10)

一、实验名称

文法类型的判断和推导序列的生成

二、实验目的

输入:一组任意的文法规则和任意符号串。

输出:相应的Chomsky文法类型和推导。

三、实验原理

1、文法G定义为四元组(Vn,Vt,P,S)

其中Vn为非终结符(或语法实体,或变量)集:Vt为终结符集;P为规则(α->β)的集合,α∈(Vn∪Vt)*且至少包含一个非终结符,β∈(Vn∪Vt)*;Vn,Vt和P是非空有穷集。S称作识别符或开始符,它是一个非终结符,至少要在一条规则中作为左部出现。

2、文法类型的判断

a.设G=(Vn,Vt,P,S)为一文法,若P中的每一个产生式α->β均满足

|β|>=|α|,仅仅S->ε除外,则文法G是1型或上下文有关的。

b.设G=(Vn,Vt,P,S),若P中的每一个产生式α->β满足: α是一个非终结符,β∈(Vn∪Vt)*,则此文法称为2型的或上下文无关的。

c. 设G=(Vn,Vt,P,S),若P中的每一个产生式的形式都是A->αB或A->α,其中A和B都是终结符,α∈Vt*,则G是3型文法或正规文法。

四、实验思路

本实验采取C++来完成,用大写字母A到Z表示非终结符,小写字符a到z 表示终结符。

实验流程图

1、接受产生式

首先建立一个结构体siyuanzu,其成员有非终结符集合数组Vn,终结符集合数组Vt以及产生式集合数组rule,通过函数input来接受从键盘输入的产生式,并且存储于string类字符串数组rule中。函数input实现接受产生式功能的思路为:先确定要输入的产生式数目n,用for循环实现产生式的存储。

2、文法类型的判断

函数Grammer实现判断文法类型的功能并且输出文法的类型。其实现功能的思路为:

a.对rule数组中每一个产生式进行判断,以“->”中的“-”作为判断条件,将产生式分为左部和右部分别计算左部和右部的长度。若youb小于左部则不是1型文法。输出0型文法;若右部大于或等于左部,则继续判断。

b.判断文法是否为2型文法,经过a步骤的执行,若文法为1型文法,只需

在此基础上判断文法的左部是否只有一个非终结符。通过判断条件

zuo==1&&'A'<=a.rule[i][zuo-1]&&a.rule[i][zuo-1]<='Z'确定是否为2型文法,若不满足判断条件则为1型文法,进行输出,若满足则继续判断。

c.判断文法是否为3型文法,经过b步骤的执行,若文法为2型文法,只需在此基础上判断文法的右部是否为αB或α形式或者是Bα或α形式。通过判断条件一

((you==2)&&(a.rule[i][num+1]>='a')&&(a.rule[i][num+1]<='z')&&(a.rule[i][num+2]>=' A')&&(a.rule[i][num+2]<='Z'))||((you==1)&&(a.rule[i][num+1]>='a')&&(a.rule[i][num +1]<='z'))判断是否满足αB或α形式,通过判断条件二

((you==2)&&(a.rule[i][num+1]>='A')&&(a.rule[i][num+1]<='Z')&&(a.rule[i][num+2]>=' a')&&(a.rule[i][num+2]<='z'))||((you==1)&&(a.rule[i][num+1]>='a')&&(a.rule[i][num+ 1]<='z'))判断是否满足Bα或α形式。若所有产生式同时满足判断条件一或者同时满足判断条件二,则为3型文法进行输出。否则为2型文法进行输出。

3、将文法以四元组形式输出

函数output实现输出文法四元组形式的功能。具体思路为:

a.将存放产生式的string类数组rule一分为二,用x数组存放rule中所有的大写字母即非终结符,用y数组存放rule中所有的小写字母即终结符。

b.用双重for循环给x和y数组中重复的字符标记,重复的字符全部赋值为“!”

c.将x数组中非“!”元素赋值给非终结符集Vn,将y数组中非“!”元素赋值给终结符集Vt。

d.按照格式分别输出非终结符集Vn,终结符集Vt,产生式P以及开始符S。

五、实验小结

我运用C++解决了此次实验的文法类型判断的问题,在实际解决问题的过程中,主要遇到了以下几个问题:

1、文法类型的判断条件

《编译原理》书本上给出了几类文法类型的定义,但是在实际的解决问题过程中,需要将书本上给的判断条件转换为C++语言中的判断条件,这需要对文法

类型的定义有很好的理解。我通过判断产生式右部是否大于等于左部确定1型文法,在此基础上判断产生式左部是否为一个非终结符确定2型文法,最后在2

型文法的基础上判断产生式是否全部满足αB或α形式或者是Bα或α形式确定3型文法。最终解决了文法类型判断条件的问题。

2、产生式的存储问题

实验要求最少输入五条产生式,我最初是选择用C语言解决存储问题,但是发现C语言中对于字符串的处理不够灵活,于是选择了C++来解决。C++中可以用string类型来定义字符串数组,并且可以通过length函数求每个字符串的长度,这样给每条产生式的判断都带来了极大的便捷。

3、文法以四元组形式输出问题

实验需要输出文法的四元组,即需要输出非终结符集Vn,终结符集Vt,产生式P以及开始符S,由于我将产生式存储在string类数组rule中,因此,需要将rule中的元素分为两类,大写字母为非终结符,小写字母为终结符。但是分好类的数组存在元素重复的问题,我通过一个双重for循环给重复元素标记为“!”,再将非“!”元素赋值给字符数组Vn和Vt,解决了元素重复问题。最后需要安排一下输出的格式即解决了这个问题。

通过本次实验,我深入的了解了文法类型的判断,对于文法类型的判断也更加的熟练。同时,对于文法的四元组的定义更加的熟悉,并且对于运用C++解决编译原理的问题有了一定的基础。

六、附件

1、源代码

#include

#include

using namespace std;

struct siyuanzu

{

char Vn[50];

char Vt[50];

string rule[20];

};

相关文档
最新文档