课程名称 编译原理程序设计 班级
实验日期 2012.5.16
课程实验报告
姓名
实验名称
实验目的:
学号
实验成绩
实验二:语法分析器
实
验
目
的
及
要
求
实
验
环
境
实
验
内
容
算
法
描
述
及
利用算符优先分析法通过设计、编制、调试一个表达式文法的
语法分析程序,加深对算符优先分析法原理的理解。
实验要求:
通过定义数组和结构体作为具有一定意义或关系的表或栈,存
放 FIRSTVT、LASTVT、算符优先关系表的元素。
构造出 FIRSTVT 表和 LASTVT 表以及算符优先关系表。可以根
据构造的优先关系表对输入的任意符号串进行分析,判断是否为本
文法的句子。结果显示到 DOS 界面上。
Visual C++ 6.0
Windows xp
使用算符优先分析算法分析所输入的文法:
例如 :(1)输入文法为:
E → E+T | T
T → T*F | F
P → (E) | i
程序输出所有非终结符的 FIRSTVT 和 LASTVT 集,构造出算符优先
分析表。
(2)输入符号串
1、.如果输入符号串为文法句子,显示分析步骤,包括分析栈中
的内容、当前符号、以及移近或规约动作;
2、如果输入符号串不是文法句子,则指示错误,不符合文法。
一、 算符优先分析算法流程图如下:
1
实
验
步
骤
二、主流程图如下:
2
N/n
开始
输入文法规则数
输入文法规则
算符优先文法?
Y/y
转化后的文法:
调用 FIRSTVT(char c)和
LASTVT(char c)函数
输出非终结符 FIRSTVT
LASTVT 集
调 用 创建 文 法 优先
关系表函数 table()
输出算符优先分析表
输入符号串
调 用 deal() 函 数 对
输入串进行分析
符合所输入文法?
Y/y
调 用 print(int
k,char *s)函数
j,int
输出符号串分析过程
结束
3
N/n
提示错误
调试过程中出现的错误如下:
一、 头文件中出现的错误:
调
试
过
程
及
实
验
结
果
在 table()函数中漏写以下语句,
for(i=0;i"后的转化文法,用于
最后的规约)
二、主函数中出现的错误:
(1)一开始主函数中变量名没有与头文件函数中的变量名没有
统一,造成错误。统一变量名后错误消失。
(2)开始时写的主函数中没有调用 table()函数,没有创建出相应
的优先关系表。编写过程中函数多而杂,容易漏写函数,应该写出
大体流程,按流程调用函数一般不会出错。
实验结果截图如下:
(1)无错误输入的运行结果截图:
4
(2)有错误输入的运行结果截图:
1)
5
2)
3)
6
总
结
附
录
本次上机实验是语法分析器,相对来来说不是很容易的,它的
要求比较高,要将编译原理中所学的很多知识联系起来,并且要有
比较良好的编程能力。 一开始看到题目时没什么头绪,理不清思路,
不知道怎样把算符优先分析法应用到语法分析中。对算符优先分析
法的算法也不是很熟悉,也不知道怎样写入程序中解决实际问题。
通过看书以及上网查阅相关资料,首先要根据文法计算每个非终结
符的 FIRSTVT 和 LASTVT 集,再构造表达式文法的优先关系表。根
据表来判断所输入的文法输入符号串是否符合文法。按照这个想法,
开始有了大概的规划,然后照着这个想法去做,终于做好了。
构造算符优先关系表,算符优先关系表是一个二维数组,用来
存放任意两个终结符之间的优先关系。首先构造表头,通过扫描所
有产生式将终结符不重复的存放在一个一维数组中并置为优先关系
表的行和列,并将优先关系表其他内容全部初始化为空。接着遍历
所有产生式,找出任意两个终结符之间存在的关系(可以没有关系),
并判断任意两终结符是否至多存在一种优先关系,如发现优先关系
表不为空,则证明该文法不是算符优先文法,否则,将相应的关系
填入到相应的行列对应的单元中。
本次实验我们是两个同学一起完成的,主函数由同学完成,而
头文件中的函数由同学完成。吸取上次实验的教训,我们学会了更
好的合作,一开始就一起探究讨论,并统一变量名,提高了编程效
率,避免了很多不必要的错误。通过本次课程设计,不仅加强了我
们对编译原理的认识,掌握了很多知识,更加让我们明白了动手能
力和团队合作的重要性。 在未来学习的道路上, 应该继续发扬这
种精神, 将实践和合作进行到底!
头文件源程序如下:
#include "stdio.h"
#include "stdlib.h"
char StRule[10][30];
char analysis[20][10];
char relation[20][20];
char symbol[100];
char EO[20];
char input[100];
char firstvt[10][10];
char lastvt[10][10];
int flagf[10]={0};
FIRSTVT 集是否已求出
int flagl[10]={0};
LASTVT 集是否已求出
int r;
int r1;
int m,N,n;
7
//存储文法规则
//用于输入串的分析
//算符优先关系
//模拟符号栈 symbol
//文法终结符集
//文法输入符号串
//文法非终结符 FIRSTVT 集
//文法非终结符 LASTVT 集
//标志第 i 个非终结符的
//标志第 i 个非终结符的
//文法规则个数
//转化后文法规则个数
int judgeEO(char c);
int xiabiao(char c);
的下标
void FIRSTVT(char c);
集
void LASTVT(char c);
集
void table();
//判断字符 c 是否是终极符
//求字符 c 在算符优先关系表中
//求非终结符 c 的 FIRSTVT
//求非终结符 c 的 LASTVT
//创建文法优先关系表
void FIRSTVT(char c)
{
//求 FIRSTVT 集
int i,j,k,m,n;
for(i=0;i