#include<iostream>
#include<map>
#include<stack>
#include<regex>
#include<string>
using namespace std;
// LL 分析表的每一个单元
struct LLTableUnit{
string vaule; // 逆串
char CR; //CR == C 时 表示 继续读下一符号 , CR == R 时 表示 重读当前符号
//CR == E 时 表示 Error , CR == S 时 表示 Success
};
LLTableUnit lltable[9][9];
map<char, int> row_c2n,col_c2n;
map<int ,char> row_n2c,col_n2c;
//初始化
void init(){
for(int i=0;i<9;i++)
for(int j=0;j<9;j++){
lltable[i][j].CR = 'E';
lltable[i][j].vaule = "";
}
//map映射 字母和对应数组中的位置
row_c2n['i'] = 0; row_c2n['+'] = 1; row_c2n['-'] = 2; row_c2n['*'] = 3;
row_c2n['/'] = 4; row_c2n['('] = 5; row_c2n[')'] = 6; row_c2n['^'] = 7; row_c2n['#'] = 8;
col_c2n['E'] = 0; col_c2n['e'] = 1; col_c2n['T'] = 2; col_c2n['t'] = 3; col_c2n['F'] = 4;
col_c2n['f'] = 5; col_c2n['P'] = 6; col_c2n[')'] = 7; col_c2n['#'] = 8;
//LL(1)文法 的分析表
lltable[0][0].vaule = "eT"; lltable[0][0].CR = 'R'; lltable[0][5].vaule = "eT"; lltable[0][5].CR = 'R';
lltable[1][1].vaule = "eT"; lltable[1][1].CR = 'C'; lltable[1][2].vaule = "eT"; lltable[1][2].CR = 'C';
lltable[1][6].vaule = ""; lltable[1][6].CR = 'R'; lltable[1][8].vaule = ""; lltable[1][8].CR = 'R';
lltable[2][0].vaule = "tF"; lltable[2][0].CR = 'R'; lltable[2][5].vaule = "tF"; lltable[2][5].CR = 'R';
lltable[3][1].vaule = ""; lltable[3][1].CR = 'R'; lltable[3][2].vaule = ""; lltable[3][2].CR = 'R';
lltable[3][3].vaule = "tF"; lltable[3][3].CR = 'C'; lltable[3][4].vaule = "tF"; lltable[3][4].CR = 'C';
lltable[3][6].vaule = ""; lltable[3][6].CR = 'R'; lltable[3][8].vaule = ""; lltable[3][8].CR = 'R';
lltable[4][0].vaule = "fP"; lltable[4][0].CR = 'R'; lltable[4][5].vaule = "fP"; lltable[4][5].CR = 'R';
lltable[5][1].vaule = ""; lltable[5][1].CR = 'R'; lltable[5][2].vaule = ""; lltable[5][2].CR = 'R';
lltable[5][3].vaule = ""; lltable[5][3].CR = 'R'; lltable[5][4].vaule = ""; lltable[5][4].CR = 'R';
lltable[5][6].vaule = ""; lltable[5][6].CR = 'R'; lltable[5][7].vaule = "fP"; lltable[5][7].CR = 'C';
lltable[5][8].vaule = ""; lltable[5][8].CR = 'R';
lltable[6][0].vaule = ""; lltable[6][0].CR = 'C'; lltable[6][5].vaule = ")E"; lltable[6][5].CR = 'C';
lltable[7][6].vaule = ""; lltable[7][6].CR = 'C'; lltable[8][8].vaule = ""; lltable[8][8].CR = 'S';
}
void read(stack<char> &sys,stack<char> &in){
sys.push('#');
sys.push('E');
in.push('#');
string tmp;
while(1){
cout<<"please input : ";
cin>>tmp;
if(regex_match(tmp,regex("(i|\\+|\\^|-|\\*|\\/|\\(|\\))+"))) //输入字符串的合法性检验
break;
cout<<"ILLEGAL INPUT!"<<endl;
}
for(int i = tmp.length()-1;i>=0;i--){
in.push(tmp[i]);
}
}
void print_stack(stack<char> s,stack<char> t){
char a[100];
int i = 0;
cout<<" ";
while(!s.empty()){
a[i++] = s.top();
s.pop();
}
int x = 24-i;
for(i--;i>=0;i--)
cout<<a[i];
cout<<" ";
while(x>=0){
x--;
cout<<" ";
}
while(!t.empty()){
cout<<t.top();
t.pop();
x++;
}
x = 24 - x;
cout<<" ";
while(x>=0){
x--;
cout<<" ";
}
}
int solve(stack<char> &sys,stack<char> &in){
cout<<" 分析栈 预留栈 动作"<<endl;
while( !sys.empty() && ( !in.empty() )){
print_stack(sys,in);
char op ,inch,sysch;
string v;
inch = in.top(); //获取匹配串的栈顶字符
sysch = sys.top(); //获取分析串的栈顶字符
sys.pop();
op = lltable[col_c2n[sysch]][row_c2n[inch]].CR ;
v = lltable[col_c2n[sysch]][row_c2n[inch]].vaule;
if(v=="")
cout<<"ε";
else
cout<<v;
cout<<"/"<<op<<endl;
if(op == 'R' || op == 'C'){
for(int i=0;i<v.length();i++){
sys.push(v[i]);
}
if(op == 'C'){
in.pop();
}
}else if(op=='E'){
return 0;
}else if(op=='S'){
return 1;
}
}
}
int main(){
init();
while(1){
stack<char> sys,in;
read(sys,in);
if(solve(sys,in)){
cout<<"SUCCESS"<<endl;
}else{
cout<<"ERROR"<<endl;
}
}
return 0;
}