递归的好写,但是字符串切分还是不擅长,这里我都是分情况if else了,因为E' id这种我想写一个函数来切分和入栈,不怎么会。
先这样,回去再练练字符串的题目,还有词频统计之类的。
这里分析表是自己算出来然后用二维string存的,看了看网上有自动生成和去左递归的,很麻烦。
#include<bits/stdc++.h>
using namespace std;
string table[5][6];//store the rules
map<string,int> col,row;//store the indexes's transformation from word to integar
string aim;//the sentence to be processed
stack<string> S;//the stack of storing terminal and unterminal in the process
void init()
{
string col_word[6]={"id","+","*","(",")","$"};
string row_word[5]={"E","E'","T","T'","F"};
int index=0;
while(index<6){
col.insert(pair<string,int>(col_word[index],index));
index++;
}
index=0;
while(index<5){
row.insert(pair<string,int>(row_word[index],index));
index++;
}
//下面是分析表的存储 没有的地方记为false 空记为empty
//好沙雕的写法,服了我自己
//妈的还不对,干啥啥不行,bug一层层
table[row["E"]][col["id"]]="TE'";
table[row["E"]][col["("]]="TE'";
table[row["E'"]][col["+"]]="+TE'";
table[row["E'"]][col[")"]]="empty";
table[row["E'"]][col["$"]]="empty";
table[row["T"]][col["id"]]="FT'";
table[row["T"]][col["("]]="FT'";
table[row["T'"]][col["+"]]="empty";
table[row["T'"]][col["*"]]="*FT'";
table[row["T'"]][col[")"]]="empty";
table[row["T'"]][col["$"]]="empty";
table[row["F"]][col["id"]]="id";
table[row["F"]][col["("]]="(E)";
for(int i=0;i<5;i++)
for(int j=0;j<6;j++)
if(table[i][j]=="")
table[i][j]="false";
}
bool read()
{
cin>>aim;
S.push("$");//initiate the stack
S.push("E");
return true;
}
bool LL_1()
{
//这里注意两个地方要切分字符串,读入规则的时候要分开,读输入字符的时候要分开
//输入字符读完要切开 string.substr()
while(S.top()!="$")
{
string top_stack=S.top();
S.pop();
int index=0;
for(index=0;index<aim.length();index++)
{
if(aim[index]=='i') index=2;
else index=1;
break;
}
string top_input=aim.substr(0,index);//从输入串的最前面取一个符号
cout<<"栈顶:"<<top_stack<<" 输入最前:"<<top_input<<endl;
if(top_stack==top_input)//如果栈里最前面的和输入串里最前面的匹配,输入串消去它,栈中移出
aim=aim.substr(index),cout<<"匹配"<<top_stack<<endl<<endl;
else if(table[row[top_stack]][col[top_input]]=="empty")
cout<<"匹配"<<top_stack<<"->"<<"empty"<<endl;
else if(table[row[top_stack]][col[top_input]]=="false")
cout<<"出错\n";
else//先输出规则,读出规则中的符号,反向压栈
{
cout<<top_stack<<"->"<<table[row[top_stack]][col[top_input]]<<endl<<endl;
stack<string> tep;//先压入这个栈再读入S
int flag=0;
for(int i=0;i<table[row[top_stack]][col[top_input]].length();i++)
{
if(table[row[top_stack]][col[top_input]][i]=='i')
i++,tep.push("id");
else if(table[row[top_stack]][col[top_input]][i]=='E' && table[row[top_stack]][col[top_input]][i+1]=='\'')
i++,tep.push("E'");
else if(table[row[top_stack]][col[top_input]][i]=='T' && table[row[top_stack]][col[top_input]][i+1]=='\'')
i++,tep.push("T'");
else
{
string t=" ";
t[0]=table[row[top_stack]][col[top_input]][i];
tep.push(t);
}
}
while(tep.size())
{
string t=tep.top();
tep.pop();
S.push(t);
}
}
}
return true;
}
int main()
{
init();
read();
if(LL_1())
cout<<"success analysis";
else
cout<<"failed, maybe it's wrong";
return 0;
}
转载:https://blog.csdn.net/qq_37410469/article/details/102491458
查看评论