某个编译原理的实验代码存档
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

119 lines
3.1 KiB

//
// Created by lenfrex on 2023/5/7.
//
#ifndef LEXER_CPP_GRAMMAR_H
#define LEXER_CPP_GRAMMAR_H
#include <ostream>
#include "vector"
#include "string"
#include "set"
#include "map"
typedef std::string Express;
// 单个产生式的select集合
typedef std::pair<Express, std::set<char>> ExpressSelectSet;
// 多个产生式的Select集合set,同一个非终止符的所有推导式的select集合
typedef std::set<ExpressSelectSet> SelectSet;
typedef std::map<char, std::string> TableRow;
// 文法定义
class Grammar {
private:
char startChar;
// 非终止符,vn
std::set<char> nonTerminals = std::set<char>();;
// 终止符,vt
std::set<char> terminals = std::set<char>();;
// 文法产生式
std::map<char, std::set<Express>> productionsMap;
std::map<char, std::set<char>> firstSet = std::map<char, std::set<char>>();
std::map<char, std::set<char>> followSet = std::map<char, std::set<char>>();
std::map<char, SelectSet> selectSet = std::map<char, SelectSet>();
std::map<char, TableRow> analysisTable = std::map<char, std::map<char, std::string>>();
bool ll1Grammar = false;
void calcFirstSetForNonTerminal(char nonTerminal);
// 计算first集合
void generateFirstSet();
// 获取当前总的follow集合元素数量
int getTotalFollowSize();
// 计算follow集合
void generateFollowSet();
// follow集合预处理
void followPreProcess();
// follow集合完善处理
void followFinalProcess();
// 计算select集合
void generateSelectSet();
// 检查当前是否为LL1文法
bool isLL1Grammar();
// 构建预测分析表
void buildAnalysisTable();
public:
[[nodiscard]] const std::set<char> &getNonTerminals() const;
[[nodiscard]] const std::set<char> &getTerminals() const;
[[nodiscard]] const std::map<char, std::set<Express>> &getGrammarExpresses() const;
Grammar(const std::string &nonTerminalString, const std::string &terminalString,
const std::set<std::string> &productionTexts, char startChar);
[[nodiscard]] char getStartChar() const;
[[nodiscard]] const std::map<char, std::set<Express>> &getProductionsMap() const;
[[nodiscard]] const std::map<char, std::set<char>> &getFirstSet() const;
[[nodiscard]] const std::map<char, std::set<char>> &getFollowSet() const;
[[nodiscard]] const std::map<char, SelectSet> &getSelectSet() const;
[[nodiscard]] const std::map<char, TableRow> &getAnalysisTable() const;
[[nodiscard]] bool isLl1Grammar() const;
friend std::ostream &operator<<(std::ostream &os, const Grammar &grammar);
static bool canDeducedEmpty(const std::set<std::string> &productions);
};
// 文法不支持异常
class NotSupportedGrammarException : public std::exception {
private:
const std::string msg;
public:
[[nodiscard]] const char *what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW override {
return msg.data();
};
public:
explicit NotSupportedGrammarException(std::string msg) : msg(std::move(msg)) {};
[[nodiscard]] const std::string &getMsg() const {
return msg;
};
};
#endif //LEXER_CPP_GRAMMAR_H