Description
输入开始符号,非终结符,终结符,产生式
输出LR(k)优先分析过程
以拓广算术表达式G[A]: 为例
A→E
E→E+T | T
T→T*F | F
F→(E) | a
Input
非终结符个数,非终结符,空格符分隔;
终结符个数,终结符,空格符分隔;
产生式的个数,各产生式的序号,产生式的左边和右边符号,空格符分隔;
状态数,ACTION列数,GOTO列数,空格符分隔;
状态,ACTION矩阵(k 0 表示空 A 0 表示接收),GOTO矩阵(0表示 空),空格符分隔;
输入分析字符串,#结束
Output
用“ & ”分隔,左边表示栈底到栈顶符号;右边表示尚未分析的字符串。
Sample InputCopy
A
4 E T F A
6 a + * ( ) #
7
0 A E
1 E E+T
2 E T
3 T T*F
4 T F
5 F (E)
6 F a
12 6 3
0 s 5 k 0 k 0 s 4 k 0 k 0 1 2 3
1 k 0 s 6 k 0 k 0 k 0 A 0 0 0 0
2 k 0 r 2 s 7 k 0 r 2 r 2 0 0 0
3 k 0 r 4 r 4 k 0 r 4 r 4 0 0 0
4 s 5 k 0 k 0 s 4 k 0 k 0 8 2 3
5 k 0 r 6 r 6 k 0 r 6 r 6 0 0 0
6 s 5 k 0 k 0 s 4 k 0 k 0 0 9 3
7 s 5 k 0 k 0 s 4 k 0 k 0 0 0 10
8 k 0 s 6 k 0 k 0 s 11 k 0 0 0 0
9 k 0 r 1 s 7 k 0 r 1 r 1 0 0 0
10 k 0 r 3 r 3 k 0 r 3 r 3 0 0 0
11 k 0 r 5 r 5 k 0 r 5 r 5 0 0 0
(a+a)*a#
Sample OutputCopy
#0 & (a+a)*a#
#0(4 & a+a)*a#
#0(4a5 & +a)*a#
#0(4F3 & +a)*a#
#0(4T2 & +a)*a#
#0(4E8 & +a)*a#
#0(4E8+6 & a)*a#
#0(4E8+6a5 & )*a#
#0(4E8+6F3 & )*a#
#0(4E8+6T9 & )*a#
#0(4E8 & )*a#
#0(4E8)11 & *a#
#0F3 & *a#
#0T2 & *a#
#0T2*7 & a#
#0T2*7a5 & #
#0T2*7F10 & #
#0T2 & #
#0E1 & #
程序:
#include <iostream>
#include <map>
#include <string>
#include <string.h>
#include <iomanip>
#include <stack>
#include <cmath>
using namespace std;
int myatoi(const char* p) {
int length = strlen(p);
int res = 0;
for (int i = 0; i < strlen(p); i++) {
res *= 10;
res += (p[i] - '0');
}
return res;
}
string reverseString(string s) {
string res;
for(int i = s.size() - 1; i >= 0; i--) res += s[i];
return res;
}
struct Production {
int n;
string left;
string right;
};
int main(){
char S;
cin >> S;
int nonterminal_num;
cin >> nonterminal_num;
string nonterminal[nonterminal_num];
map<string, int> mapping;
for (int i = 0; i < nonterminal_num; i++) {
cin >> nonterminal[i];
}
int terminal_num;
cin >> terminal_num;
string terminal[terminal_num];
for (int i = 0; i < terminal_num; i++) {
cin >> terminal[i];
mapping.insert(make_pair(terminal[i],i));
}
for (int i = 0; i < nonterminal_num; i++)
mapping.insert(make_pair(nonterminal[i], i + terminal_num));
int production_num;
cin >> production_num;
Production production[production_num];
for (int i = 0; i < production_num; i++)
cin >> production[i].n >> production[i].left >> production[i].right;
int row_size;
cin >> row_size;
int action_column_size;
cin >> action_column_size;
int goto_column_size;
cin >> goto_column_size;
string table[row_size][action_column_size + goto_column_size];
int dummy;
for (int i = 0; i < row_size; i++) {
cin >> dummy;
string front, back;
for (int j = 0; j < action_column_size; j++) {
cin >> front >> back;
table[i][j] = front + back;
}
for (int j = action_column_size; j < action_column_size + goto_column_size; j++) {
cin >> table[i][j];
}
}
string str;
cin >> str;
stack<string> stk;
int cursor = 0;
stk.push("#");
stk.push("0");
cout << "#0 & " << str << endl;
while (true) {
int row = myatoi(stk.top().c_str());
char *p = new char;
strncpy(p, &str[cursor], 1);
p[1]='\0';
string col = p;
int column = mapping[col];
delete p;
string res = table[row][column];
bool flag=false;
a: if(res[0] == 's') {
char *p = new char;
strncpy(p, &str[cursor], 1);
p[1]='\0';
string col = p;
stk.push(col);
cursor++;
delete p;
stk.push(res.substr(1, res.size() - 1));
}
else if (res[0] == 'r') {
int pop_num = production[myatoi(res.substr(1,res.size()-1).data())].right.size() * 2;
while(pop_num--) stk.pop();
int row = myatoi(stk.top().c_str());
int column = mapping[production[myatoi(res.substr(1,res.size()-1).data())].left];
stk.push(production[myatoi(res.substr(1,res.size()-1).data())].left);
res = table[row][column];
stk.push(res);
flag = true;
goto a;
}
else if (res[0] >= '0' && res[0] <= '9') {
int row = myatoi(stk.top().c_str());
char *p = new char;
strncpy(p, &str[cursor], 1);
p[1]='\0';
string col = p;
int column = mapping[col];
res = table[row][column];
}
else if (res[0] == 'A') {
break;
}
else break;
stack<string> copy = stk;
string reverse, out;
while(!copy.empty()) {
string alan;
if (copy.top().size() > 1)
alan = reverseString(copy.top());
else alan = copy.top();
reverse+=alan;
copy.pop();
}
out=reverseString(reverse);
cout << out << " & " << str.substr(cursor, str.size() - cursor) << endl ;
}
return 0;
}