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

来源:互联网 发布:手柄键盘映射软件 编辑:程序博客网 时间:2024/06/06 05:39

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
E6  E A T B F D9 + - * / ( ) x y z 131  E TA2  A +TA3  A -TA4  A k5  T FB6  B *FB7  B /FB8  B k9  F (E)10 F D11 D x12 D y13 D z251  E ( 12  E x 13  E y 14  E z 15  A + 26  A - 37  A ) 48  A # 49  T ( 510 T x 511 T y 512 T z 513 B + 814 B - 815 B * 616 B / 717 B ) 818 B # 819 F ( 920 F x 1021 F y 1022 F z 1023 D x 1124 D y 1225 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;}                                 








原创粉丝点击