【编译原理】实验二 语法分析器设计与实现

实验类型: 设计性   实验学时:4   实验要求:必修

一、实验目的

编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

二、实验内容

利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

2.1 待分析的简单语言的语法

用扩充的BNF范式表示如下:

【编译原理】实验二 语法分析器设计与实现_第1张图片

 

2.2 实验要求说明

输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。

例如:

    输入  begin a:=9; x:=2*3; b:=a+x end #

    输出  success!

    输入  x:=a+b*c end #

    输出  error

三、仪器设备

计算机,C++6.0软件环境。

四、所需耗材

五、实验原理、方法和手段

语法分析程序的算法思想

(1)主程序示意图如图5-1所示。

【编译原理】实验二 语法分析器设计与实现_第2张图片

(2)递归下降分析程序示意图如图5-2所示。

(3)语句串分析过程示意图如图5-3所示。

【编译原理】实验二 语法分析器设计与实现_第3张图片

(4)statement语句分析程序流程如图5-4、5-5、5-6、5-7所示。

【编译原理】实验二 语法分析器设计与实现_第4张图片

六、实验步骤

阅读实验说明,做好实验准备,然后进行编辑调试。

七、实验结果处理

演示结果并保存相关文件。

八、实验注意事项

注意数据输入格式,单词的匹配规则。

九、预习与思考题

预习:阅读课本相关内容,分析相关算法设计思想,熟悉VC++6.0使用方式。

思考题:类C语言程序的语法分析。

十、实验报告要求

1、实验报告中应包括相关操作步骤和程序代码。

2.书写实验报告时要结构合理,层次分明,在分析描述的时候,需要注意语言的流畅。

准备工作

【编译原理】实验二 语法分析器设计与实现_第5张图片

代码

#include
#include
#include
#include 
using namespace std;
//自定义定义两个改变字体颜色函数
void SetFontRed(){
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
} 
void SetFontWhite(){
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
}
/*词法分析器*/
#define MAXROW 100//源代码的最大行数
#define MAXTABLE 1000//符号表和常数表最大存储范围 
string ReservedWordList[6]={"begin","if","then","while","do","end"};//关键字表 
//声明全局变量 
string ScanBuffer[MAXROW];//扫描缓冲区,定义为字符串数组
struct SymbolTable{
	int code;
	string symbol;
}ST[MAXTABLE];//符号表 
struct ConstantTable{
	int code;
	int constant;
}CT[MAXTABLE];//常数表
int STi=0,CTi=0;//符号表和常数表指示器
struct Word{
	int code;
	string symbol;
	int constant;
}word;
int row=0,col=0;//搜索指示器,row指行,col指列 
int endrow;
char ch;//搜索指示器指示的当前字符 
string strToken;//当前字符串 
//声明全局函数 
void Input();//子程序过程,将源代码输入进扫描缓冲区 
void GetChar();//子过程程序,将下一输入字符读到ch中,搜索指示器前移一字符位置 
void GetDel();//子程序过程,检查ch中的字符是否为分隔符。若是,则调用GetChar直至ch中进入一个非分隔符(delimiters->分隔符) 
void Concat();//子程序过程,,将ch中的字符连接到strToken之后 
bool IsLetter();//布尔函数过程,判断ch中的字符是否为字母 
bool IsDigit();//布尔函数构成,判断ch中的字符是否为数字 
int Reserve();//整型函数过程,对strToken中的字符串查找保留字表,若它是一个保留字则返回它的编码,否则返回0值(假定0不是保留字的编码)
void Retract();//子程序过程,将搜索指示器回调一个字符位置,将ch置为空白字符 
int InsertID();//整型函数过程,将strToken中的标识符插入符号表,返回符号表指针 
int InsertConst();//整型函数过程,将strToken中的常数插入常数表,返回常数表指针
void LexicalAnalyzerProcError();//子程序过程,词法分析出错,提示错误信息 
//定义函数
void Input(){
	int op;
	cout<<"请输入数字选择输入格式"<>op;
	int i=0;
	char c;//输入流中的当前字符 
	if(op==1){
		while((c=cin.get())!=EOF){
			ScanBuffer[i].push_back(c);
			if(c=='\n') i++;
		}
		endrow=--i;
	}
	else{
		fstream in;
		in.open("test.txt",ios::in);
		while(in.peek()!=EOF){
			c=in.get();
			ScanBuffer[i].push_back(c);
			if(c=='\n') i++;
		}
		endrow=--i;
	}
} 
void GetChar(){
	ch=ScanBuffer[row][col];
	col++;
} 
void GetDel(){
	while(ch=='\n'){
		row++;
		col=0;
		GetChar();
	} 
	while(ch==' '||ch=='\t') GetChar();
}
void Concat(){
	strToken.push_back(ch);
}
bool IsLetter(){
	return isalpha(ch);
}
bool IsDigit(){
	return isdigit(ch);
}
int Reserve(){
	int i;
	for(i=0;i<6;i++)
		if(ReservedWordList[i]==strToken) return i+1;
	return 10; 
}
void Retract(){
	col--;
	ch='\0'; 
}
void LexicalAnalyzerProcError(){
	SetFontRed();
	cout<<"[Error]"<'){
				word.code=21;
				word.symbol="<>";
				return word;
				//return (21,-);
				//cout<<"(21,<>)"<'){
			GetChar();
			if(ch=='='){
				word.code=24;
				word.symbol=">=";
				return word;
				//return (24,-);
				//cout<<"(24,>=)"<)"<	   21
do	        5	   <=	   22
end	        6	   >	   23
id	        10	   >=	   24
num	        11	   =	   25
+	        13	   ;	   26
-	        14	   (	   27
*	        15	   )	   28
/	        16	   #	   0
*/ 
void P(){
	if(SYM.code==1){
		ADVANCE();
		S();
		if(SYM.code==6){
			ADVANCE();
			if(SYM.code==0){
				cout<<"语法正确"<

 

你可能感兴趣的:(编译原理)