Description
输入开始符号,非终结符,终结符,产生式,LL(1)分析表
输出LL(1)分析表
G[E]:E →E+T | E-T | T
T →T*F | T/F | F
F →(E) | D
D →x | y | z
消除左递归G1[E]:
E →TA
A →+TA | -TA | e
T →FB
B →*FB | /FB | e
F →(E) | D
D →x | y | z
Input
输入开始符号;
非终结符个数,非终结符,空格符分隔;
终结符个数,终结符,空格符分隔;
产生式的个数,各产生式的序号,产生式的左边和右边符号,空格符分隔;
LL(1)分析表中的产生式个数,序号,行符号,列符号,产生式编号,空格符分隔;
Output
第一行:空,安终结符循序输出终结符,结束符‘#’,每个符号占5格;
其余行:非终结符符号,各对应终结符的产生式的右边,每个符号占5格;
Sample Input
E 6 E A T B F D 9 + - * / ( ) x y z 13 1 E TA 2 A +TA 3 A -TA 4 A k 5 T FB 6 B *FB 7 B /FB 8 B k 9 F (E) 10 F D 11 D x 12 D y 13 D z 25 1 E ( 1 2 E x 1 3 E y 1 4 E z 1 5 A + 2 6 A - 3 7 A ) 4 8 A # 4 9 T ( 5 10 T x 5 11 T y 5 12 T z 5 13 B + 8 14 B - 8 15 B * 6 16 B / 7 17 B ) 8 18 B # 8 19 F ( 9 20 F x 10 21 F y 10 22 F z 10 23 D x 11 24 D y 12 25 D z 13
Sample Output
+ - * / ( ) x y z # E TA TA TA TA A +TA -TA k k T FB FB FB FB B k k *FB /FB k k F (E) D D D D x y z
题目解析:只要逻辑清晰就可以做了
// Problem#: 20908
// Submission#: 5220424
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <iostream>
using namespace std;
string start = "";
int temp;
struct
{
int count;
string sign[30];
string LL[30][30];
} non_terminal_sign = {0};//非终结符号
struct
{
int count;
string sign[30];
} terminal_sign = {0};//终结符号
struct
{
int count;
string left[30];
string right[30];
} production = {0};//产生式
struct
{
int count;
string row[30];
string col[30];
int pro_num[30];
} LL_table = {0};//LL分析表中的产生式
int main()
{
cin>>start;
cin>>non_terminal_sign.count;
for(int i = 0; i < non_terminal_sign.count; ++i)
cin>>non_terminal_sign.sign[i];
cin>>terminal_sign.count;
for(int i = 0; i < terminal_sign.count; ++i)
cin>>terminal_sign.sign[i];
cin>>production.count;
for(int i = 0; i < production.count; ++i)
cin>>temp>>production.left[i]>>production.right[i];
cin>>LL_table.count;
for(int i = 0; i < LL_table.count; ++i)
cin>>temp>>LL_table.row[i]>>LL_table.col[i]>>LL_table.pro_num[i];
terminal_sign.sign[terminal_sign.count++] = "#";//do not forget "#"
int tmp_row = 0;
int tmp_col = 0;
for(int i = 0; i < LL_table.count; ++i)
{
//find the non terminal sign
for(tmp_row = 0;tmp_row < non_terminal_sign.count && non_terminal_sign.sign[tmp_row] != LL_table.row[i];tmp_row++);
//find the terminal sign
for(tmp_col = 0;tmp_col < terminal_sign.count && terminal_sign.sign[tmp_col] != LL_table.col[i];tmp_col++);
//find the right in the production
non_terminal_sign.LL[tmp_row][tmp_col] = production.right[LL_table.pro_num[i] - 1];
}
//first row is the terminal sign
cout<<" ";
for(int i = 0;i < terminal_sign.count;++i)
cout<<" "<<terminal_sign.sign[i];
cout<<endl;
for(int i = 0;i < non_terminal_sign.count;++i)
{
for(int k = 0;k < 5 - non_terminal_sign.sign[i].size();++k)
cout<<" ";
cout<<non_terminal_sign.sign[i];
for(int j = 0;j < terminal_sign.count; ++j)
{
for(int k = 0;k < 5 - non_terminal_sign.LL[i][j].size();++k)
cout<<" ";
cout<<non_terminal_sign.LL[i][j];
}
cout<<endl;
}
return 0;
}