LL(1)语法分析器 c++实现

来源:互联网 发布:松下多功能机软件 编辑:程序博客网 时间:2024/06/01 10:42

    • 结构
    • 记号和规定
    • 代码
      • Baseh
      • Basecpp
      • TableStackh
      • TableStackcpp
      • maincpp

结构

  • main.cpp包含了主函数的调用
  • Base.h和Base.cpp定义了类Base, 类Base用于存储产生式、符号表、FIRST集合FOLLOW集
  • TableStack.h和TableStack.cpp定义了类TableStack, 类TableStack继承了Base, 用于生成预测表和分析.

记号和规定

$表示空ε, #表示终止
大写字母为非终结符.
默认第一个产生式的左边那个非终结符就是开始符号
输入的产生式分开写(比如A->a|b, 要输入A->a和A->b才能处理)

代码

Base.h

#ifndef _BASE_H_#define _BASE_H_#include <iostream>#include <iomanip>#include <string>#include <vector>#include <set>using namespace std;struct node { // 产生式数据结构    char left;    string right;};class Base {protected:    int T;    node production[100]; // 产生式集    set<char> first_set[100];  // first集    set<char> follow_set[100];  // follow集    vector<char> terminalNoEmpty; // 去$(空)的终结符    vector<char> terminal;  // 终结符    vector<char> nonterminal;  // 非终结符public:    Base() :T(0){}    bool isNonterminal(char c);    int get_index(char target);  // 获得target在终结符集合中的下标    int get_nindex(char target);  // 获得target在非终结符集合中的下标    void get_first(char target);  // 得到first集合    void get_follow(char target);  // 得到follow集合    void inputAndSolve();  // 处理得到first和follow集    void displayFirstAndFollow();  // 显示First和Follow集};#endif 

Base.cpp

#include "Base.h"bool Base::isNonterminal(char c) {    if (c >= 'A' && c <= 'Z')        return true;    return false;}int Base::get_nindex(char target) {    for (int i = 0; i<nonterminal.size(); i++) {        if (target == nonterminal[i])            return i;    }    return -1;}int Base::get_index(char target) {    for (int i = 0; i<terminalNoEmpty.size(); i++) {        if (target == terminalNoEmpty[i])            return i;    }    return -1;}void Base::get_first(char target) {    int countEmpty = 0;    int isEmpty = 0;    int targetIndex = get_nindex(target);    for (int i = 0; i < T; i++) {        if (production[i].left == target) {  //匹配产生式左部            if (!isNonterminal(production[i].right[0])) {  //对于终结符,直接加入first                first_set[targetIndex].insert(production[i].right[0]);            }            else {                for (int j = 0; j < production[i].right.length(); j++) { // X->Y1..Yj..Yk是一个产生式                    if (!isNonterminal(production[i].right[j])) {  //Yj是终结符(不能产生空),FIRST(Yj)=Yj加入FIRST(X),不能继续迭代,结束                        first_set[targetIndex].insert(production[i].right[j]);                        break;                    }                    get_first(production[i].right[j]);//递归 先求出FIRST(Yj)                    //  cout<<"curr :"<<production[i].right[j];                    set<char>::iterator it;                     int YjIndex = get_nindex(production[i].right[j]);                    for (it = first_set[YjIndex].begin(); it != first_set[YjIndex].end(); it++) {                        if (*it == '$')  // 遍历查看FIRST(Yj)中是否含有'$'(能产生空)                            isEmpty = 1;                        else                            first_set[targetIndex].insert(*it);//将FIRST(Yj)中的非$就加入FIRST(X)                    }                    if (isEmpty == 0)  // Yj不能产生空, 迭代结束                        break;                    else {                        countEmpty += isEmpty;                        isEmpty = 0;                    }                }                if (countEmpty == production[i].right.length())//所有右部first(Y)都有$(空),将$加入FIRST(X)中                    first_set[get_nindex(target)].insert('$');            }        }    }}void Base::get_follow(char target) {    int targetIndex = get_nindex(target);    for (int i = 0; i<T; i++) {        int index = -1;        int len = production[i].right.length();        for (int j = 0; j < len; j++) {  // 寻找target在产生式中的位置index            if (production[i].right[j] == target) {                index = j;                break;            }        }        if (index != -1 && index < len - 1) {  // 找到target在产生式中的位置index                                               // 存在A->αBβ, 将FIRST(β)中除了终结符$之外的所有放入FOLLOW(B)中                                               // 这里B对应target, β对应nxt            char nxt = production[i].right[index + 1];             if (!isNonterminal(nxt)) {  // β是终结符                follow_set[targetIndex].insert(nxt);            } else {  // β是非终结符                int isExt = 0;                set<char>::iterator it;                int nxtIndex = get_nindex(nxt);                for (it = first_set[nxtIndex].begin(); it != first_set[nxtIndex].end(); it++) {                    if (*it == '$')                        isExt = 1;                    else                        follow_set[targetIndex].insert(*it);                }                if (isExt && production[i].left != target) { // 存在A->αBβ且FIRST(β)->$                                                             // FOLLOW(A)放在FOLLOW(B)中                    get_follow(production[i].left);                    set<char>::iterator it;                    char tmp = production[i].left;                    int tmpIndex = get_nindex(tmp);                    for (it = follow_set[tmpIndex].begin(); it != follow_set[tmpIndex].end(); it++)                        follow_set[targetIndex].insert(*it);                }            }        } else if (index != -1 && index == len - 1 && target != production[i].left) {  // 存在A->αB ,FOLLOW(A)放在FOLLOW(B)中            get_follow(production[i].left);            set<char>::iterator it;            char tmp = production[i].left;            int tmpIndex = get_nindex(tmp);            for (it = follow_set[tmpIndex].begin(); it != follow_set[tmpIndex].end(); it++)                follow_set[targetIndex].insert(*it);        }    }}void Base::inputAndSolve() {    string s;    cout << "输入的产生式的个数:" << endl;    cin >> T;    for (int index = 0; index < T; index++) {  // 处理每一个产生式        cin >> s;        string temp = "";  // 存储去掉空格的产生式        for (int i = 0; i < s.length(); i++) {  // 去掉产生式中的' '            if (s[i] != ' ')                temp += s[i];        }        production[index].left = temp[0];  // 产生式的左部        for (int i = 3; i<temp.length(); i++) // 产生式的右部            production[index].right += temp[i];        for (int i = 0; i < temp.length(); i++) {  // 存储所有终结符和非终结符            if (i == 1 || i == 2) continue;  // 跳过产生符号->            if (isNonterminal(temp[i])) {  //插入一个非终结符                int flag = 0;                for (int j = 0; j < nonterminal.size(); j++) {                    if (nonterminal[j] == temp[i]) {                        flag = 1;                        break;                    }                }                if (!flag) nonterminal.push_back(temp[i]);            } else {                       //插入一个终结符                int flag = 0;                for (int j = 0; j < terminal.size(); j++) {                    if (terminal[j] == temp[i]) {                        flag = 1;                        break;                    }                }                if (!flag) terminal.push_back(temp[i]);            }        }    }    terminal.push_back('#');    for (int i = 0; i < terminal.size(); i++) { // 存储没有$符号的终结符        if (terminal[i] != '$')            terminalNoEmpty.push_back(terminal[i]);    }    // 获得first集    for (int i = 0; i < nonterminal.size(); i++) {        get_first(nonterminal[i]);    }    // 获得follow集    for (int i = 0; i < nonterminal.size(); i++) {        if (i == 0)  // 开始符号, 先加入结束符号            follow_set[0].insert('#');        get_follow(nonterminal[i]);    }}void Base::displayFirstAndFollow() {    cout << "FIRST集合" << endl;    for (int i = 0; i<nonterminal.size(); i++) {        cout << nonterminal[i] << ": ";        set<char>::iterator it;        for (it = first_set[i].begin(); it != first_set[i].end(); it++)            cout << *it << "  ";        cout << endl;    }    cout << endl;    cout << "FOLLOW集合" << endl;    for (int i = 0; i<nonterminal.size(); i++) {        cout << nonterminal[i] << ": ";        set<char>::iterator it;        for (it = follow_set[i].begin(); it != follow_set[i].end(); it++)            cout << *it << "  ";        cout << endl;    }    cout << endl;}

TableStack.h

#ifndef _TABLESTACK_H_#define _TABLESTACK_H_#include"Base.h"class TableStack : public Base {protected:    vector<char> to_any; // 分析栈    vector<char> left_any;  // 剩余输入串    int tableMap[100][100];  // 预测表public:    TableStack(){ memset(tableMap, -1, sizeof(tableMap)); }    void get_table(); // 生成预测表    void analyExp(string s);  // 分析输入语句s    void print_predictTable();  // 打印预测表    void getAns(); // 综合处理};#endif

TableStack.cpp

#include"TableStack.h"void TableStack::get_table() {    for (int i = 0; i < T; i++) {                          // 对于每个产生式(编号i):A->α        char tmp = production[i].right[0];        int row = get_nindex(production[i].left);        if (!isNonterminal(tmp)) { // tmp是终结符          // 1) 对FIRST(α)中的每个终结符号a,将i加入(A, a)中            if (tmp != '$')                tableMap[row][get_index(tmp)] = i;            if (tmp == '$') {                              // 2) 如果空$在FIRST(α)中,对FOLLOW(A)中的每个终结符或结束符b,将i加入(A,b)中                set<char>::iterator  it;                for (it = follow_set[row].begin(); it != follow_set[row].end(); it++) {                    tableMap[row][get_index(*it)] = i;                }            }        } else {  // tmp是非终结符            set<char>::iterator ti;            int tmpIndex = get_nindex(tmp);                                                            // 1) 对FIRST(α)中的每个终结符号a,将i加入(A, a)中            for (ti = first_set[tmpIndex].begin(); ti != first_set[tmpIndex].end(); ti++) {                tableMap[row][get_index(*ti)] = i;            }            if (first_set[tmpIndex].count('$') != 0) {      // 2) 如果空$在FIRST(α)中,对FOLLOW(A)中的每个终结符或结束符b,将i加入(A,b)中                set<char>::iterator  it;                for (it = follow_set[row].begin(); it != follow_set[row].end(); it++) {                    tableMap[row][get_index(*it)] = i;                }            }        }    }}void TableStack::analyExp(string s) {    for (int i = 0; i < s.size(); i++)        left_any.push_back(s[i]);    left_any.push_back('#');    to_any.push_back('#');    to_any.push_back(nonterminal[0]);  // 加入开始符号    while (to_any.size() > 0) {        //cout<<"分析栈:";        string outs = "";        for (int i = 0; i < to_any.size(); i++)            outs += to_any[i];        cout << setw(15) << outs;        //cout<<"剩余输入串:";        outs = "";        for (int i = 0; i < left_any.size(); i++)            outs += left_any[i];        cout << setw(15) << outs;        // 匹配        char char1 = to_any.back();        char char2 = left_any.front();        if (char1 == char2 && char1 == '#') {            cout << setw(15) << "Accepted!" << endl;            return;        }        if (char1 == char2) {            to_any.pop_back();            left_any.erase(left_any.begin());            cout << setw(15) << "匹配:" << char1 << endl;        } else if (tableMap[get_nindex(char1)][get_index(char2)] != -1) {            int tg = tableMap[get_nindex(char1)][get_index(char2)];            to_any.pop_back();            if (production[tg].right != "$") {                for (int i = production[tg].right.length() - 1; i >= 0; i--)                    to_any.push_back(production[tg].right[i]);            }            //cout<<"推导:"<<production[tg].right<<endl;             cout << setw(15) << "推导:" << production[tg].right << endl;        } else {            cout << setw(15) << "error!" << endl;            return;        }    }}void TableStack::print_predictTable() {    //table    for (int i = 0; i<terminalNoEmpty.size(); i++) {        cout << setw(10) << terminalNoEmpty[i];    }    cout << endl;    for (int i = 0; i < nonterminal.size(); i++) {        cout << nonterminal[i] << ": ";        for (int j = 0; j<terminalNoEmpty.size(); j++) {            if (tableMap[i][j] == -1)                cout << setw(10) << "   ";            else                cout << setw(10) << production[tableMap[i][j]].right;        }        cout << endl;    }    cout << endl;}void TableStack::getAns(){    inputAndSolve();    displayFirstAndFollow();    get_table();    print_predictTable();    //栈匹配    string ss;    cout << "请输入符号串:" << endl;    cin >> ss;    cout << setw(15) << "分析栈" << setw(15) << "剩余输入串" << setw(15) << "推导式" << endl;    analyExp(ss);}

main.cpp

#include "TableStack.h"int main() {    // $表示空, #表示终止    TableStack res;    res.getAns();    return 0;}
原创粉丝点击