QtNovelUI/libParse/syntax_foundation.h

236 lines
6.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef SYNTAX_FOUNDATION_H
#define SYNTAX_FOUNDATION_H
#include "ast_foundation.h"
#include <QString>
namespace Load {
class DocIns;
}
namespace SyntaxX {
/**
* @brief 通用语法异常
*/
class SyntaxException : public Lex::WsBaseException {
private:
const Lex::Token &target;
public:
SyntaxException(const Lex::Token &tins, const QString &simple);
virtual ~SyntaxException() = default;
virtual const Lex::Token &targetToken() const;
};
enum class Result { All, Part, Fail };
/**
* @brief 解析匹配规则
*/
class BaseRule {
public:
virtual ~BaseRule() = default;
/**
* @brief 转换成堆变量,持久化生命周期
* @return
*/
virtual BaseRule *toHeap() && = 0;
/**
* @brief 堆实例标志
* @return
*/
virtual bool heapMark() const = 0;
/**
* @brief 使用预读取方式匹配当前Token流返回匹配结果
* @param port Token流
* @param start 起始Token索引
* @param count 本次匹配长度
* @return 匹配结果长度
*/
virtual QPair<uint, Result> match(Lex::TokenReader *port, uint start, uint count) const noexcept = 0;
/**
* @brief 解析Token流构建AST
* @param port 输入端口
* @param start 父节点
*/
virtual void parse(Lex::TokenReader *port, Ast::ASTList *parent) = 0;
};
/**
* @brief Token匹配解析规则
*/
class TokenRule : public BaseRule {
private:
const Lex::TokenDef &token_type;
bool build_within_heap = false;
void *operator new(size_t s);
public:
explicit TokenRule(const Lex::TokenDef &def);
TokenRule *operator&() = delete;
virtual BaseRule *toHeap() && override;
virtual bool heapMark() const override;
virtual QPair<uint, Result> match(Lex::TokenReader *port, uint start, uint count) const noexcept override;
virtual void parse(Lex::TokenReader *port, Ast::ASTList *parent) override;
};
/**
* @brief 解析规则承载
*/
class ElmRule : public BaseRule {
private:
std::function<Ast::ASTList *(Lex::TokenReader *reader, Ast::ASTList *parent)> exec_store;
BaseRule *item_store;
public:
explicit ElmRule();
ElmRule(const ElmRule &) = delete;
ElmRule(const ElmRule &&) = delete;
virtual ~ElmRule();
void *operator new(size_t s) = delete;
ElmRule &operator=(const ElmRule &) = delete;
ElmRule &operator=(const ElmRule &&) = delete;
/**
* @brief 设置处理过程
* @param exec
*/
virtual void resetProcess(std::function<Ast::ASTList *(Lex::TokenReader *reader, Ast::ASTList *parent)> exec);
/**
* @brief 重置内部实际解析规则
* @param item
*/
void setRule(BaseRule &&item);
virtual QPair<uint, Result> match(Lex::TokenReader *port, uint start, uint count) const noexcept override;
virtual void parse(Lex::TokenReader *port, Ast::ASTList *parent) override;
// BaseRule interface
public:
virtual BaseRule *toHeap() && override;
virtual bool heapMark() const override;
};
/**
* @brief 序列解析规则
*/
class Seqs : public BaseRule {
private:
QList<BaseRule *> items_rule;
bool build_within_heap = false;
void *operator new(size_t s);
public:
Seqs();
template <class... Args> explicit Seqs(BaseRule *head, Args... args) : Seqs(std::forward<Args>(args)...) { items_rule.push_front(head); }
template <class... Args> explicit Seqs(BaseRule &&head, Args... args) : Seqs(std::forward<Args>(args)...) {
items_rule.push_front(std::move(head).toHeap());
}
Seqs(Seqs &&other);
virtual ~Seqs();
Seqs *operator&() = delete;
// BaseRule interface
public:
virtual BaseRule *toHeap() && override;
virtual bool heapMark() const override;
virtual QPair<uint, Result> match(Lex::TokenReader *port, uint start, uint count) const noexcept override;
virtual void parse(Lex::TokenReader *port, Ast::ASTList *parent) override;
};
/**
* @brief 多个分支,任意一个匹配都可以
*/
class Any : public BaseRule {
private:
QList<BaseRule *> items_rule;
bool build_within_heap = false;
void *operator new(size_t s);
public:
Any();
template <class... Args> explicit Any(BaseRule *head, Args... args) : Any(std::forward<Args>(args)...) { items_rule.push_front(head); }
template <class... Args> explicit Any(BaseRule &&head, Args... args) : Any(std::forward<Args>(args)...) {
items_rule.push_front(std::move(head).toHeap());
}
Any(Any &&other);
virtual ~Any();
Any *operator&() = delete;
// BaseRule interface
public:
virtual BaseRule *toHeap() && override;
virtual bool heapMark() const override;
virtual QPair<uint, Result> match(Lex::TokenReader *port, uint start, uint count) const noexcept override;
virtual void parse(Lex::TokenReader *port, Ast::ASTList *parent) override;
};
/**
* @brief 重复,指定匹配次数
*/
class Repeat : public BaseRule {
private:
BaseRule &item_store;
uint match_max, match_min;
bool build_within_heap = false;
void *operator new(size_t s);
public:
Repeat(BaseRule &&item, uint min = 1, uint max = UINT_MAX);
Repeat(BaseRule *item, uint min = 1, uint max = UINT_MAX);
Repeat *operator&() = delete;
// BaseRule interface
public:
virtual BaseRule *toHeap() && override;
virtual bool heapMark() const override;
virtual QPair<uint, Result> match(Lex::TokenReader *port, uint start, uint count) const noexcept override;
virtual void parse(Lex::TokenReader *port, Ast::ASTList *parent) override;
};
class Optional : public BaseRule {
private:
BaseRule &item_store;
bool build_within_heap = false;
void *operator new(size_t s);
public:
Optional(BaseRule *item);
Optional(BaseRule &&item);
Optional *operator&() = delete;
// BaseRule interface
public:
virtual BaseRule *toHeap() && override;
virtual bool heapMark() const override;
virtual QPair<uint, Result> match(Lex::TokenReader *port, uint start, uint count) const noexcept override;
virtual void parse(Lex::TokenReader *port, Ast::ASTList *parent) override;
};
typedef TokenRule T;
} // namespace SyntaxX
#endif // SYNTAX_FOUNDATION_H