#pragma once #include "libsyntax_global.h" #include "libtokens.h" #include #include #include #include namespace ast_basic { class IExprInst; class ExprElement; } namespace lib_syntax { /** * @brief 语法异常 */ class LIBSYNTAX_EXPORT SyntaxException { private: QString msg_store; public: SyntaxException(const QString& message); virtual ~SyntaxException() = default; virtual QString message() const; }; // 基础语法解析接口 =================================================================================================== /** * @brief 解析上下文接口 */ class MatchCursor { private: QList> _expr_through; //表达式解析路径 QList _total_errors; // 所有解析错误 QList _exprs_errors; // 当前表达式解析错误 std::shared_ptr _current_token = nullptr; // 当前Token std::shared_ptr _remains_word = nullptr; // 剩余词语 public: MatchCursor(); MatchCursor(const MatchCursor& other); virtual ~MatchCursor() = default; virtual void enterExprs(std::shared_ptr ins); virtual std::shared_ptr currentExprs() const; virtual void logExprsError(const QString& msg); virtual void quitExprs(); virtual bool mustStop() const; virtual int exprsErrorCount() const; virtual int totalErrorCount() const; virtual QList totalErrors() const; virtual void setCurrent(std::shared_ptr t, std::shared_ptr remains); virtual std::shared_ptr currentToken() const; virtual std::shared_ptr currentWords() const; }; /** * @brief 基础语法匹配规则接口 */ class IBasicRule { public: /** * 返回匹配语法规则的词法序列表达 * * \return 词法表达序列 */ virtual QString present() const = 0; /** * @brief 解析 * @param rt_inst 解析上下文 * @param head 列表头 * @return 返回结果<匹配完成新列表头,匹配长度> */ virtual QList> parse(std::shared_ptr cursor) const = 0; }; /** * @brief 组合语法匹配规则接口 */ class ICompositRule : public IBasicRule { public: /** * @brief 子规则 * @return */ virtual QList> children() const = 0; }; template using token_proc = void(*)(std::shared_ptr expr_inst, std::shared_ptr token); /** * @brief token匹配 */ template xproc = nullptr> class TokenMatch : public IBasicRule, public std::enable_shared_from_this> { private: std::shared_ptr _define_peers; public: TokenMatch(std::shared_ptr define) : _define_peers(define) { } // IBasicRule interface public: virtual QList> parse(std::shared_ptr current) const override { auto w_this = current->currentWords(); auto match_result = _define_peers->analysis(w_this); if (std::get<0>(match_result)) { auto current_inst = current->currentExprs(); current_inst->addToken(std::get<0>(match_result)); if (xproc) { xproc(std::dynamic_pointer_cast(current_inst), std::get<0>(match_result)); } auto remains = w_this->nextWord(); if (std::get<1>(match_result)) { remains = std::make_shared(std::get<1>(match_result), remains); } auto clone_ins = std::make_shared(current); auto chain = std::make_shared(std::get<0>(match_result), current->currentToken()); clone_ins->setCurrent(std::get<0>(chain, remains)); return QList>() << clone_ins; } else { QList> retvals; // 少一个 auto short_one = std::make_shared(current); short_one->logExprsError(QString(u8"Syntax[0x00001]语法匹配错误,缺失\"%1\"") .arg(this->_define_peers->reviseWords()) .arg(w_this->row()).arg(w_this->column()).arg(w_this->file())); retvals << short_one; // 错一个 auto error_one = std::make_shared(current); error_one->logExprsError(QString(u8"Syntax[0x00001]语法匹配错误,请修正\"%1\"") .arg(w_this->content()).arg(w_this->row()).arg(w_this->column()).arg(w_this->file())); auto tkins = std::make_shared( w_this->row(), w_this->column(), w_this->position(), w_this->content(), w_this->file(), this->_define_peers); auto tkchain = std::make_shared(tkins, error_one->currentToken()); error_one->setCurrent(tkchain, w_this->nextWord()); retvals << error_one; // 多一个 rt_inst->appendParseErrors(rt_inst->currentFile(), head->position(), QString(u8"Syntax[0x00001]语法匹配错误,无法识别\"%1\"(应该为:%4)\n\t目标语法:%5。\n") .arg(head->content()).arg(head->row()).arg(head->column()).arg(this->_define_peers->reviseWords()) .arg(rt_inst->currentExprRule()->present())); return std::make_tuple(IBasicRule::MatchResult::Part, head); } } virtual QString present() const override { return QString(u8"%1").arg(this->_define_peers->reviseWords()); } }; /** * @brief 语法规则或匹配 */ class LIBSYNTAX_EXPORT Any : public IBasicRule, public std::enable_shared_from_this { private: QList> mbrs_store; std::tuple, std::shared_ptr> rule_select(std::shared_ptr head) const; public: Any(const QList> mbrs); // IBasicRule interface public: virtual QList> children() const override; virtual std::tuple> parse(std::shared_ptr rt_inst, std::shared_ptr head) const override; virtual QString present() const override; }; /** * @brief 语法规则序列匹配 */ class LIBSYNTAX_EXPORT Seqs : public IBasicRule, public std::enable_shared_from_this { private: QList> mbrs_store; public: Seqs(const QList> mbrs); // IBasicRule interface public: virtual QList> children() const override; virtual std::tuple> parse(std::shared_ptr rt_inst, std::shared_ptr head) const override; virtual QString present() const override; }; /** * @brief 语法规则重复匹配 */ class LIBSYNTAX_EXPORT Rept : public IBasicRule, public std::enable_shared_from_this { private: std::shared_ptr rule_peer; int min_match, max_match; public: Rept(std::shared_ptr rule, int min, int max); // IBasicRule interface public: virtual QList> children() const override; virtual std::tuple> parse(std::shared_ptr rt_inst, std::shared_ptr head) const override; virtual QString present() const override; }; // 组合语法实体解析 =================================================================================================== /** * @brief 对应语法表达式解析规则 */ class LIBSYNTAX_EXPORT ExprRule : public lib_syntax::IBasicRule, public std::enable_shared_from_this { public: typedef QList> TokenSeqs; ExprRule(const QString& rule_name, int expr_mark); virtual std::shared_ptr reloadRule(std::shared_ptr rule); virtual QString name() const; virtual int typeMark() const; virtual std::shared_ptr newEmptyInstance() const = 0; virtual std::shared_ptr makeCopy() const = 0; // IBasicRule interface public: virtual QList> children() const override; virtual std::tuple> parse(std::shared_ptr rt_inst, std::shared_ptr head) const override; virtual QString present() const override; protected: std::shared_ptr child_store; private: QString name_store; int mark_store; }; /** * 语法元素解析规则. */ template class ElementRule : public ExprRule { public: ElementRule(const QString& rule_name, int expr_mark) :ExprRule(rule_name, expr_mark) { } virtual std::shared_ptr newEmptyInstance() const { return std::dynamic_pointer_cast( std::make_shared(this->shared_from_this())); } virtual std::shared_ptr makeCopy() const { return std::make_shared>(name(), typeMark()); } }; } // namespace lib_syntax