环境:windows 11 编译器:devc++ 5.11
注意,实验有借鉴部分!!!!
一.实验目的与要求
1.使用C、C++完成任务的程序编写;
2.使用实验所提供的模板撰写实验报告,要求内容详实,有具体的设计描述、关键的 代码片段、及实验结果屏幕截图;
二.实验内容与方法
文法(Grammar)是描述高级语言语法结构的重要工具。定义任意的文法G,需要完成 对其四元组(V,T,P,S)的定义(课本P33)。在该实验中,请制定文法文件的具体组 织形式、编程完成对文法文件的读取、并完成对文法的分类。该实验具体包含以下两个 任务:
1.任务一:文法的定义及读取 现规定文法由Grammar.txt文件保存,请制定文法文件的具体存储格式。如文法 G={{S,A,B,C}, {a,b,c}, {S->ABC,A->a,B->b,C->c}, S}在Grammar.txt文件中可由以下方 式描述并存储:
--------------------------------------------------
S,A,B,C
a,b,c
S->ABC,A->a,B->b,C->c
S
--------------------------------------------------
文法的文本形式可根据自己需要自由定义,在此基础上,编程实现对任意文法文件的读 取。 2. 任务二:文法的分类 根据Chomsky的文法体系分类(课本P40),文法分为四大种类。请在任务一的基础 上,编程实现对Grammar.txt中存储的文法进行分类,自动判断其所属类别。例如任务 一中所给出的文法G应被判定为2型文法,即上下文无关文法。请设计分类方法,并设 计四类不同的测试文法测试分类结果的正确性。 每类文法最少两个案例,每个文法最 少有四个产生式。需要有文法包含ε为终结符。
下面是文法的定义:
0型文法
想要判断一个文法是否为0型文法,只需要判断左侧非空即可。
1型文法
首先1型文法必须是0型文法
1型文法除了α→εα→ε这一个特例外,其他情况都满足ββ的长度大于αα的长度
2型文法
首先2型文法必须是1型文法
2型文法左边必须是一个非终结字符
3型文法
首先3型文法必须是2型文法
3型文法必须是线性文法
先判断是不是3型文法
三.实验步骤与过程
实验一:
首先创建txt文件Grammar.txt文件内部有:
G={{S,A,B,C}, {a,b,c}, {S->ABC,A->a,B->b,C->c}
已经有的文法。
然后编写程序读这个txt文件,其中afile是输入文件,bfile文件是输出文件。
这里先做两个判断:判断是否有文件:
之后开始一行一行读取afile的字符串
字符串读取完成之后,开始进行括号的匹配:
左右括号匹配计数之后,进行分析:
循环对应每个括号,之后读出括号之中的字符串并输出到新的数组之中:
之后开始拼接字符串
拼接字符串完成之后,在新的txt文件中进行输出:
结果图:
第二题:
先进行初始化
VT的对应的符号进行统计下标位置的操作。
下面是先记录大于号和逗号下标的记录:
下标记录完成之后,统计在大于号的逗号之间的位置,方便之后分离vn和vt
然后将分离好的vt读入容器中:
注意判断当有“|”的时候,要将它去掉,防止后面影响判断。
然后可以选择将vt输出为字符串。
之后就是vn的分离操作
先记录“-”减号的位置
在已经知道“,”逗号的前提下,可以分离出vn然后将其加入容器
之后选择将vn合成为字符串
然后就可以进行文法分析了。
定义一个结构体:
下面是文法的定义:
0型文法
想要判断一个文法是否为0型文法,只需要判断左侧非空即可。
1型文法
首先1型文法必须是0型文法
1型文法除了α→εα→ε这一个特例外,其他情况都满足ββ的长度大于αα的长度
2型文法
首先2型文法必须是1型文法
2型文法左边必须是一个非终结字符
3型文法
首先3型文法必须是2型文法
3型文法必须是线性文法
先判断是不是3型文法
3型文法的函数在下:
判断的时候要同时判断是不是其他的文法
判断的时候,需要注意以产生式对应字母的是不是在A与Z之间和产生式左右长度等条件进行判断
然后是2型文法的函数:
2型文法注意判断产生式左右长度和字母的位置
然后是1型文法的函数:
1型文法注意判断产生式左右长度,字母的范围
然后是0型文法的函数:
全部完成之后就可以关闭文件了,其中bfile是输出文件
所有运行截图:
初始:
中:
结果: