编译原理丨第十三周 ——1000. 输入输出LL(1)语法分析程序

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
 Copy sample input to clipboard
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 
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<<"    "<








你可能感兴趣的:(编译原理)