编译原理实验Sicily--LR(K) 语法分析程序

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值