236 lines
6.8 KiB
C
236 lines
6.8 KiB
C
|
|
#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 ⌖
|
|||
|
|
|
|||
|
|
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
|