// // Created by lenfrex on 2023/5/7. // #ifndef LEXER_CPP_GRAMMAR_H #define LEXER_CPP_GRAMMAR_H #include #include "vector" #include "string" #include "set" #include "map" typedef std::string Express; // 单个产生式的select集合 typedef std::pair> ExpressSelectSet; // 多个产生式的Select集合set,同一个非终止符的所有推导式的select集合 typedef std::set SelectSet; typedef std::map TableRow; // 文法定义 class Grammar { private: char startChar; // 非终止符,vn std::set nonTerminals = std::set();; // 终止符,vt std::set terminals = std::set();; // 文法产生式 std::map> productionsMap; std::map> firstSet = std::map>(); std::map> followSet = std::map>(); std::map selectSet = std::map(); std::map analysisTable = std::map>(); 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 &getNonTerminals() const; [[nodiscard]] const std::set &getTerminals() const; [[nodiscard]] const std::map> &getGrammarExpresses() const; Grammar(const std::string &nonTerminalString, const std::string &terminalString, const std::set &productionTexts, char startChar); [[nodiscard]] char getStartChar() const; [[nodiscard]] const std::map> &getProductionsMap() const; [[nodiscard]] const std::map> &getFirstSet() const; [[nodiscard]] const std::map> &getFollowSet() const; [[nodiscard]] const std::map &getSelectSet() const; [[nodiscard]] const std::map &getAnalysisTable() const; [[nodiscard]] bool isLl1Grammar() const; friend std::ostream &operator<<(std::ostream &os, const Grammar &grammar); static bool canDeducedEmpty(const std::set &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