直接輸入根據己知文法構造的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;
}
}
輸入:
輸出:
希望能幫到你哦。
看完點波關注哦~