#include "iostream"
#include "string"
#include "stack"
#include "list"
using namespace std;
#define empty 100
#define acc 0
#define error 1000
int get(char temp);
int getGOTO(char temp);
int main()
{
//定义action表,正数表示移进项目,负数表示规约项目
//i第0列,+第1列,*第二列,(第三列,)第四列,#第五列
int action[12][6] = { {5,empty,empty,4,empty,empty,},
{ empty,6,empty,empty,empty,acc,},
{empty,-2,7,empty,-2,-2,},
{empty,-4,-4,empty,-4,-4,},
{5,empty,empty,4,empty,empty,},
{empty,-6,-6,empty,-6,-6,},
{5,empty,empty,4,empty,empty,},
{5,empty,empty,4,empty,empty,},
{empty,6,empty,empty,11,empty,},
{empty,-1,7,empty,-1,-1,},
{empty,-3,-3,empty,-3,-3,},
{empty,-5,-5,empty,-5,-5} };
//定义GOTO表,第0列表示E,第1列表示T,第二列表示F
int GOTO[12][3] = { {1,2,3,},
{empty,empty,empty,},
{empty,empty,empty,},
{empty,empty,empty,},
{8,2,3,},
{empty,empty,empty,},
{empty,9,3,},
{empty,empty,10,},
{ empty,empty,empty,},
{ empty,empty,empty,},
{empty,empty,empty,},
{empty,empty,empty,},
};
cout << "请输入字符串" << endl;
string a;
cin >> a;
list state;//状态栈,list只从前面插入数据,模仿栈
state.push_front(0);//把0压栈
list character;//符号栈
character.push_front('#');//把#压栈
list str;//输入串栈
str.push_front('#');//把#压栈
for (int i = a.length() - 1; i >= 0; i--)
{
str.push_front(a[i]);//把输入串入栈
}
//输出初始状态
cout << "状态 符号 输入串 " << endl;
cout << 0 << " " << "#" << " " << a + "#" << endl;
while(str.size()>=1){
int tempstate = state.front();//获得状态栈栈顶元素
//cout << "栈顶元素" << tempstate << endl;
char tempstr = str.front();//获得输入串栈顶元素
int cha = get(tempstr);//将i,+,*,(,),#转为对应的列号
if (cha == 1000)
{
cout << "不能接收" << endl;
break;
}
// cout << cha << endl;
int tempAction = action[tempstate][cha];
// cout << tempAction << endl;
if (tempAction > 0)//表明是移进项目
{
state.push_front(tempAction);
character.push_front(tempstr);
str.pop_front();
//输出状态栈
for (list::reverse_iterator i = state.rbegin(); i != state.rend(); i++)
cout << *i;
for (int k = state.size(); k < 6; k++)
cout << " ";
cout << " ";
//输出符号栈
for (list::reverse_iterator i = character.rbegin(); i != character.rend(); i++)
cout << *i;
for (int k = character.size(); k < 5; k++)
cout << " ";
cout << " ";
//输出输入串
for (list::iterator i = str.begin(); i != str.end(); i++)
cout << *i;
cout << endl;
}
else if (tempAction < 0)//表明是规约项目
{
//规约项目则要弹出状态栈元素,输入串元素不弹出,符串栈元素进行规约
state.pop_front();
//对于符号栈
switch (tempAction)
{
case -1://E->E+T
{
character.pop_front();
character.pop_front();
character.pop_front();
character.push_front('E');
}
break;
case -2://E->T
{
character.pop_front();
character.push_front('E');
}
break;
case -3://T->T*F
{
character.pop_front();
character.pop_front();
character.pop_front();
character.push_front('T');
}
break;
case -4://T->F
{
character.pop_front();
character.push_front('T');
}
break;
case -5://F->(E)
{
character.pop_front();
character.pop_front();
character.pop_front();
character.push_front('F');
}
break;
case -6://F->i
{
character.pop_front();
character.push_front('F');
}
break;
}
int statelength = state.size();//状态栈元素个数
int characterlength = character.size();//符号栈元素个数
if (statelength > characterlength)
{
int l1 = statelength - characterlength;//二者的差
for (int j = 0; j < l1; j++)
{
state.pop_front();//弹出多余的状态元素,让状态栈与符号栈平衡
}
}
else if (statelength < characterlength)
{
int l = state.front();//得到状态栈的栈顶元素
char l2 = character.front();//得到符号栈栈顶元素
int l3 = 0;
if (l2 == 'E')
l3 = 0;
else if (l2 == 'T')
l3 = 1;
else if (l2 == 'F')
l3 = 2;
else {
cout << "不能接收哟" << endl;
break;
}
int l4 = GOTO[l][l3];
state.push_front(l4);//入栈
}
//输出状态栈
for (list::reverse_iterator i = state.rbegin(); i != state.rend(); i++)
cout << *i;
for (int k = state.size(); k < 6; k++)
cout << " ";
cout << " ";
//输出符号栈
for (list::reverse_iterator i = character.rbegin(); i != character.rend(); i++)
cout << *i;
for (int k = character.size(); k < 5; k++)
cout << " ";
cout << " ";
//输出输入串
for (list::iterator i = str.begin(); i != str.end(); i++)
cout << *i;
cout << endl;
}
else if (tempAction == 0)//表明accept
{
cout << "accept" << endl;
break;
}
}
system("pause");
return 0;
}
//对于i,+,*,(,),#转为对应的列号
int get(char temp)
{
if (temp == 'i')
return 0;
else if (temp == '+')
return 1;
else if (temp == '*')
return 2;
else if (temp == '(')
return 3;
else if (temp == ')')
return 4;
else if (temp == '#')
return 5;
else
return error;
}