⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 源代码.cpp

📁 本文件主要是针对编译原理的语法分析和语义分析
💻 CPP
字号:
#include<iostream>
#include <iomanip>
using namespace std;

int q=1;//控制分析栈的栈顶,定义为全局变量
int i=0;//控制输入待分析的字符
int x;//记录查询到的非终结符的数字代码
int y;//记录查询到的终结符的数字代码

void print(int m);//声明函数

//存储待分析的句子
char sentence[20];

//构建预测分析表,元素为规则的数字代码
int pat[4][7]={//predict analytical table(预测分析表的缩写)
	{0,0,0,0,0,0,0},//为了使下标从1开始,多添了一行,一列(数组下标从0开始)
	{0,1,2,3,0,0,0},//0 代表无规则
	{0,4,4,4,0,0,0},//1:S-a; 2:S-b 3:S-(T)  4:T-SU 5:U-,SU 6:U-ε
	{0,0,0,0,6,5,0}
};

//分析栈
char as[20]={'#','S'};//analysis stack

//文法规则
struct rules{
	int n;//记录规则的字符数
	char rule[5];//规则
}ruletable[7]={
	{0,'$'},//无用,占位
	{1,'a'},
	{1,'b'},
	{3,"(T)"},
	{2,"SU"},
	{3,",SU"},
	{1,'$'}//$代表 ε
};

//根据规则填写分析栈
void fill(int p){
	int w;//控制填表次数
	int j=ruletable[p].n;//记录规则中,字符的个数
	int m=j;
	if(ruletable[p].rule[j-1]!='$'){//不是空规则
		for(w=0;w<m;w++){//由规则中字符的个数决定填表的次数
		as[q]=ruletable[p].rule[j-1];//倒序写入
		q++;//准备填写分析栈下一个
		j--;//填写下一个规则字符
		}
		q--;//每次填写完毕,q++,最后一次也是,应修正,以指示栈顶
		print(i);//打印分析栈
	}
	
	else{
		q--;//空规则,不写入分析栈,但栈顶需要回缩一个字符
		print(i);//打印分析栈
	}
		
}

//打印分析过程,包括分析栈,待分析字符
void print(int m){
	int n,j;
	for(n=0;n<q+1;n++){
		cout<<as[n];//输出当前分析栈中的字符
	}
	cout<<setw(5);
	for(j=m;j<20;j++){
		cout<<sentence[j];//输出待分析的字符
	}
	cout<<endl;//回车换行
}

//非终结符与数字代码间的对应
char table1[4]={'$','S','T','U'};

//终结符与数字代码间的对应
char table2[7]={'$','a','b','(',')',',','#'};//#为句子的结束符

//判断栈顶字符是否为终结符
int judge(char m){
	int i;
	int j=0;//0 代表未找到,为非终结符
	for(i=1;i<6;i++){
		if(table2[i]==m){//找到
			j=1;//m是终结符
			break;//退出
		}					
	}
	return(j);//若是非终结符,j保持原值
}

//报错函数
void error(){
	cout<<"错误,不是合法的句子!"<<endl;
}

//查询非终结符的数字代码
void search1(char m){
	int i;
	for(i=1;i<4;i++){
		if(table1[i]==m){
			x=i;
			break;
		}
			
	}	
}

//查询终结符的数字代码
void search2(char m){
	int i;//
	for(i=1;i<6;i++){
		if(table2[i]==m){
			y=i;
			break;
		}
		
	}
	
}

void main(){
	//int i=0;//控制输入待分析的字符	
	int p;//记录查询预测分析表后,得到的规则的数字带代码
	char t,n;//t--句子中的字符; n--分析栈顶的字符
	cout<<"请输入要分析的句子,以#结束:"<<endl;
	cin>>sentence;//存储待分析的句子
	cout<<"分析栈和输入符号的变化如下:"<<endl;
	while(1){//条件不好确定,用break退出
		t=sentence[i];
		n=as[q];
		if(judge(n)==1){//n是终结符
			if(n==t){//匹配
				i++;//分析下一个字符
				q--;//消去匹配的栈顶字符
				print(i);//打印分析栈
			}
			else {//无法匹配,出错
				error();
				break;
			}
		}
		else{//n是非终结符,即分析栈已空
			if(n=='#'){//n是句末符号
				if(n==t){//分析到了句子的最后,即句子分析完毕
					cout<<"句子合法,接受!"<<endl;
					break;
				}
					

				else{//句子非法
					error();
					break;
				}
			}
			else{//n是非终结符
				search1(n);
				search2(t);				
				p=pat[x][y];//得到预测分析表中的规则的数字代码
				if(p!=0){//规则存在
					fill(p);
				}
				else{//无规则对应
					error();
					break;
				}

			}
		}
	}
	system("pause"); //窗口暂停,以显示结果
}
    



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -