【编译原理】用C++编程实现LL(1)语法分析器

【问题描述】

给定以下文法G[E]:

E->TE′

E′->+TE′| ε \varepsilon ε

T ->FT′

T′->*FT′| ε \varepsilon ε

F -> a | (E)

构建LL(1)预测分析表,并用C++编程实现LL(1)语法分析器

【输入形式】

一个句子

【输出形式】

若句子语法正确,输出"Syntax analysis is right"

若语法语法错误,输出"Error on syntax analysis"

注:输出不包括引号

【样例输入】

a+a*a

【样例输出】

Syntax analysis is right

【样例说明】
【评分标准】

根据通过的测试数据个数评分

思路

最重要的是构造分析表
发现题目所给的文法跟课本上的文法相似,预测分析表已给出。所以只需要选择好恰当的数据结构用来存储非终结符集、终结符集、预测分析表。
在该实验中我使用了Vector来存储Vt和Vn,用vector 类型的数组即vector predict[10];来二维的存储预测分析表。用map<char, int> 进行终结符集、非终结符集的映射,这样做的目的是为了用字母索引下标。完成好上述数据结构后,用栈结构来模拟文法分析过程即可。

#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <stack>
using namespace std;


vector<char> C;

vector<string> predict[10];

map<char, int> Vt2num; // 非终结符映射成数字下标。
map<char, int> Vn2num; // 终结符映射成数字下标,通过访问字符即可得到对应的数。

vector<char> Vt = {
    
    'E','M','T','N','F' };
vector<char> Vn = {
    
     'a','+','*','(',')','#' };

stack<char> s;

void PredictTable()
{
    
    
    int k = 0;
    for (vector<char>::iterator it = Vt.begin();it != Vt.end(); it++)
    {
    
    
        Vt2num.insert(pair<char,int>(*it, k));
        k++;
    }
    k = 0;
    for (vector<char>::iterator it = Vn.begin();it != Vn.end(); it++)
    {
    
    
        Vn2num.insert(pair<char, int>(*it, k));
        k++;
    }
    for (int i = 0;i < 5;i++)
    {
    
    
        for (int j = 0;j < 6;j++)
        {
    
    
            predict[i].push_back("NULL");
        }
    }
    // E' -> M
    // T' -> N
    predict[0][0] = "TM";
    predict[0][3] = "TM";
    predict[1][1] = "+TM";
    predict[1][4] = "0";
    predict[1][5] = "0";
    predict[2][0] = "FN";
    predict[2][3] = "FN";
    predict[3][1] = "0";
    predict[3][2] = "*FN";
    predict[3][4] = "0";
    predict[3][5] = "0";
    predict[4][0] = "a";
    predict[4][3] = "(E)";
}



int main()
{
    
    
    string str;
    cin >> str;
    str += '#';
    s.push('#');
    s.push('E');
    //int n = str.length();
    PredictTable();
    int i = 0;
    while(1)
    {
    
    
        char ch = s.top();
        int flag = 0;
        //栈顶是终结符
        for(vector<char>::iterator it = Vn.begin(); it!=Vn.end(); it++)
            if ((*it) == ch)
            {
    
    
                if (str[i] == '#' && ch == '#')
                {
    
    
                   cout << "Syntax analysis is right";
                   return 0;
                }
                if (str[i] == ch)
                {
    
    
                   s.pop();
                   i++;
                   flag = 1;
                   break;
                }
                else
                {
    
    
                   cout << "Error on syntax analysis";
                   return 0;
                }
            }

        //栈顶是非终结符
        //找到下标,入栈
        if (flag == 1) 
            continue;
        int num1 = Vt2num[ch];
        int num2 = Vn2num[str[i]];
        s.pop();
        if (predict[num1][num2] == "NULL")
        {
    
    
            cout << "Error on syntax analysis";
            return 0;
        }
        int len = predict[num1][num2].length();
        for (int k = len - 1;k >= 0; k--)
        {
    
    
            if (predict[num1][num2][k] == '0')
                continue;
            s.push(predict[num1][num2][k]);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44795952/article/details/110964015
今日推荐