編譯原理——LR(0)分析器

        直接輸入根據己知文法構造的LR(0)分析表,對於輸入的文法和符號串,所編制的語法分析程序應能正確判斷此串是否爲文法的句子,並要求輸出分析過程。


#include<bits/stdc++.h>
using namespace std;
const string ERROR="出錯,該句子不被當前文法識別!";
const int MAX=100;	
int gone=0;	//步驟
int state[MAX];	//狀態棧
int statetop=-1; //狀態棧指針 
char sign[MAX]; //符號棧
int signtop=-1;	//符號棧指針
string s;	//輸入串
queue<char> sq;	//存放輸入串的隊列 
string ACTION[MAX][MAX];	//ACTION表 
int GOTO[MAX][MAX];		//GOTO表 
int sta;	//狀態數 
int vt;		//終結符數
int vn;		//非終結符數  
char c;		//暫存字符變量 
map<char,int> mpvt;	//映射ACTION表中終結符的列號 
map<char,int>::iterator vtit;	//遍歷vt列號的迭代器 
map<char,int> mpvn;	//映射GOTO表中非終結符的列號 
map<char,int>::iterator vnit;	//遍歷vn列號的迭代器 
int ms_num;	//產生式數 
string ms_str; //暫存產生式  
map<int,string> ms;	//保存產生式 
map<int,string>::iterator msit;	//訪問產生式映射  
int Action;		//保存從 Si中解析出的要移進的狀態
int whichms;	//保存從 ri中解析出的產生式編號 
int Goto;		//保存從 GOTO表中讀取的要轉向的狀態 
string thems;	//保存當前次歸約使用的產生式  

int FindSr(string s); 	//將 Si/ri中對應的狀態/產生式編號解析出來    
void inputx();	//輸入函數 
void outputx();	//輸出函數  
void terror();	//出錯處理 
void anysit();	//總控程序  
 
int main(){
	inputx();
	anysit();
	return 0;
}
int FindSr(string s){
	int num=0;
	int k;
	int L=s.length();
	for(int i=1;i<L;i++){
		k=s[i]-'0';
		for(int j=i;j<L-1;j++){
			k*=10;
		}
		num+=k;
	}
	if(s[0]=='S'){
		Action=num;
		return Action;
	}
	else{
		whichms=num;
		return whichms;
	}
	
}
void inputx(){
	cout<<"輸入文法的產生式的個數:";
	cin>>ms_num;
	cout<<"輸入文法的產生式:"<<endl;
	for(int i=1;i<=ms_num;i++){
		cin>>ms_str;
		ms[i]=ms_str;
	} 
	cout<<"輸入狀態數:";
	cin>>sta;
	cout<<"輸入終結符數:";
	cin>>vt;
	cout<<"依次輸入終結符:";
	for(int i=0;i<vt;i++){
		cin>>c;
		mpvt[c]=i;
	}
	cout<<"輸入ACTION表(以 <> 表示空):"<<endl;
	for(int i=0;i<sta;i++){
		for(int j=0;j<vt;j++){
			cin>>ACTION[i][j];
		}
	}
	cout<<"輸入非終結符數:";
	cin>>vn;
	cout<<"依次輸入非終結符:"; 
	for(int i=0;i<vn;i++){
		cin>>c;
		mpvn[c]=i;
	}
	cout<<"輸入GOTO表(以 -1 表示空):"<<endl;
	for(int i=0;i<sta;i++){
		for(int j=0;j<vn;j++){
			cin>>GOTO[i][j];
		}
	}
	cout<<"輸入要進行LR(0)分析的句子:";
	cin>>s;
	for(int i=0;i<s.length();i++){
		sq.push(s[i]);
	}
}
void outputx(){
	cout<<++gone<<"		";
	for(int i=0;i<=statetop;i++){
		cout<<state[i];
	}cout<<"		";
	for(int i=0;i<=signtop;i++){
		cout<<sign[i];
	}cout<<"		";
	int p=0;
	char x;
	while(p<sq.size()){
		x=sq.front();
		cout<<x;
		sq.pop();
		sq.push(x);
		p++;
	}
	cout<<"		";
}
void terror(){
	cout<<ERROR;
}
void anysit(){
	cout<<"對輸入串 "<<s<<" 的LR(0)分析過程:"<<endl; 
	cout<<"步驟		"<<"狀態棧		"<<"符號棧		"<<"輸入串		"<<"ACTION		"<<"GOTO		"<<"歸約使用的產生式"<<endl;
	state[++statetop]=0;
	sign[++signtop]='#';
	int x,y;char cc;string now;
	do{
		outputx();
		x=state[statetop];
		cc=sq.front();
		for(vtit=mpvt.begin();vtit!=mpvt.end();vtit++){
			if(vtit->first==cc){
				y=vtit->second;
				break;
			}
		}
		now=ACTION[x][y];
		if(now=="<>"){
			terror();
			cout<<"(ACTION表出錯)"<<endl; 
			break;
		}
		else if(now[0]=='S'){
			FindSr(now);
			cout<<now<<endl;
			state[++statetop]=Action;
			sign[++signtop]=cc;
			sq.pop(); 
		} 
		else if(now[0]=='r'){
			int p=FindSr(now);
			for(msit=ms.begin();msit!=ms.end();msit++){
				if(msit->first==p){
					thems=msit->second;
					break;
				}
			}
			for(int k=thems.length()-1;k>2;k--){
				if(sign[signtop]==thems[k]){
					signtop--;
					statetop--;
				}
			}
			sign[++signtop]=thems[0];
			x=state[statetop];
			cc=sign[signtop];
			for(vnit=mpvn.begin();vnit!=mpvn.end();vnit++){
				if(vnit->first==cc){
					y=vnit->second;
					break;
				}
			}
			Goto=GOTO[x][y];
			if(Goto==-1){
				terror();
				cout<<"(GOTO表出錯)"<<endl; 
				break;
			}
			cout<<now<<"		"<<Goto<<"		"<<thems<<endl;
			state[++statetop]=Goto;
		}
	}while(now!="acc");
	if(now=="acc"){
		cout<<now<<endl;
		cout<<"該句子被成功識別!"<<endl; 
	}
}

輸入:

輸出:

希望能幫到你哦。


看完點波關注哦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章