254 lines
6.4 KiB
C++
254 lines
6.4 KiB
C++
#pragma once
|
||
#include <QString>
|
||
#include <QList>
|
||
#include <QHash>
|
||
#include "LexFoundation.h"
|
||
#include "SyntaxBase.h"
|
||
|
||
namespace Syntax
|
||
{
|
||
/**
|
||
*专用于定义语法树的命名空间
|
||
*/
|
||
namespace Defines
|
||
{
|
||
/**
|
||
* @brief 元素定义类型
|
||
*/
|
||
enum class DefType
|
||
{
|
||
ELEMENT,
|
||
EXPRESSION
|
||
};
|
||
|
||
/**
|
||
* 元素定义声明.
|
||
*/
|
||
class Elm
|
||
{
|
||
public:
|
||
explicit Elm(const QString &alias_name, bool tail_mark = false);
|
||
virtual ~Elm() = default;
|
||
|
||
/**
|
||
* 定义名称,定义别名.
|
||
*
|
||
* \return
|
||
*/
|
||
QString aliasName() const;
|
||
/**
|
||
* 引用.
|
||
*
|
||
* \return
|
||
*/
|
||
QString refer() const;
|
||
/**
|
||
* 匹配类型.
|
||
*
|
||
* \return 元素或表达式
|
||
*/
|
||
virtual DefType type() const;
|
||
|
||
/**
|
||
* 是否具有结尾标记.
|
||
*
|
||
* \return
|
||
*/
|
||
bool isTail() const;
|
||
|
||
private:
|
||
QString name_store;
|
||
bool tail_mark;
|
||
|
||
protected:
|
||
DefType type_define;
|
||
};
|
||
|
||
/**
|
||
* 表达式定义声明.
|
||
*/
|
||
class Exp : public Elm
|
||
{
|
||
public:
|
||
explicit Exp(const QString &alias_name, bool tail_mark = false);
|
||
virtual ~Exp() = default;
|
||
|
||
virtual DefType type() const override;
|
||
};
|
||
}
|
||
|
||
|
||
/**
|
||
* 校验元素,单个token校验.
|
||
*/
|
||
class Element
|
||
{
|
||
public:
|
||
typedef bool rst_mark;
|
||
typedef int match_len;
|
||
|
||
explicit Element(const QString &token);
|
||
virtual ~Element() = default;
|
||
|
||
QString name() const;
|
||
virtual Defines::DefType type() const;
|
||
|
||
/**
|
||
* 校验标记序列是否符合语法定义.
|
||
*
|
||
* \param tokens 标记序列
|
||
* \param offset 偏移量
|
||
* \return tuple(完全匹配指示,最大匹配长度)
|
||
*/
|
||
virtual std::tuple<rst_mark, match_len>
|
||
elementCheck(const QList<Lex::LexResult> &tokens, int offset) const;
|
||
|
||
private:
|
||
QString value_store;
|
||
};
|
||
|
||
/**
|
||
* @brief 语法匹配调用链
|
||
*/
|
||
class Link
|
||
{
|
||
public:
|
||
Link(const QString &alias, Element *elm);
|
||
virtual ~Link() = default;
|
||
|
||
static QString name(const QString &s);
|
||
QString aliasName() const;
|
||
QString refer() const;
|
||
Element* host() const;
|
||
|
||
bool tailTest() const;
|
||
void markTail(bool v);
|
||
|
||
void appendNext(Link* ins);
|
||
QList<Link*> nextElements() const;
|
||
|
||
virtual std::tuple<Element::rst_mark, Element::match_len>
|
||
linkCheck(const QList<Lex::LexResult> &tokens, int offset) const;
|
||
|
||
private:
|
||
QString alias_name;
|
||
Element *const host_ins;
|
||
bool tail_mark;
|
||
|
||
QList<Link*> next_inss;
|
||
};
|
||
|
||
/**
|
||
* @brief 校验表达式,多个语法元素顺序校验
|
||
*/
|
||
class Expression : public Element
|
||
{
|
||
public:
|
||
explicit Expression(const QString &name);
|
||
virtual ~Expression() = default;
|
||
|
||
Link* parseFlow() const;
|
||
void resetLinks(Link* entry);
|
||
|
||
virtual Defines::DefType type() const override;
|
||
|
||
/**
|
||
* 校验标记序列是否符合语法定义.
|
||
*
|
||
* \param tokens 标记序列
|
||
* \param offset 偏移量
|
||
* \return tuple(完全匹配指示,最大匹配长度)
|
||
*/
|
||
virtual std::tuple<rst_mark, match_len>
|
||
elementCheck(const QList<Lex::LexResult> &tokens, int offset) const override;
|
||
|
||
private:
|
||
QString name_store;
|
||
Link* chain_store;
|
||
};
|
||
|
||
|
||
|
||
class XSyntaxBase;
|
||
|
||
/**
|
||
* @brief 定义解析规则,支持多范式表达式匹配
|
||
*/
|
||
class ParseRule
|
||
{
|
||
public:
|
||
ParseRule(XSyntaxBase *host, const QString &rule_name, unsigned short level,
|
||
std::function<ParseResult(const QList<Lex::LexResult>&, int)>);
|
||
virtual ~ParseRule() = default;
|
||
|
||
int level() const;
|
||
QString name() const;
|
||
|
||
void addExpression(const QString &name, const QList<Defines::Elm> &_defines);
|
||
std::tuple<bool, int> tokensMatch(const QList<Lex::LexResult> &token) const;
|
||
ParseResult syntaxTrigger(const QList<Lex::LexResult>& srcs, int count);
|
||
|
||
private:
|
||
XSyntaxBase *const host_ins;
|
||
int level_store;
|
||
QString name_store;
|
||
QList<Expression*> expression_list;
|
||
|
||
std::function<ParseResult(const QList<Lex::LexResult>&, int)> exc_store;
|
||
};
|
||
|
||
|
||
/**
|
||
* @brief 解析器的语法匹配形式
|
||
*/
|
||
enum class MatchType
|
||
{
|
||
OnlyForm,
|
||
Entirely
|
||
};
|
||
|
||
/**
|
||
* 基础解析器模型.
|
||
*/
|
||
class XSyntaxBase : public Syntax::SyntaxParser
|
||
{
|
||
public:
|
||
explicit XSyntaxBase(const QString §ion, MatchType type = MatchType::Entirely);
|
||
|
||
Expression* get_expression(const QString &name);
|
||
Element *get_element(const QString &name);
|
||
|
||
// 通过 Parse::SyntaxParser 继承
|
||
virtual void docActive(Parse::Result::DocCore *ins) override;
|
||
virtual Parse::Result::DocCore *docRef() const override;
|
||
virtual bool applied(const QList<Lex::LexResult>& seqs) override;
|
||
virtual void reset() override;
|
||
virtual ParseResult parse(QList<Lex::LexResult>& seqs) override;
|
||
virtual QList<Syntax::SyntaxParser*> children() const override;
|
||
|
||
virtual Parse::Result::DesNode * currNode() const override;
|
||
|
||
protected:
|
||
ParseRule* addRule(const QString &name, unsigned short level, std::function<ParseResult(const QList<Lex::LexResult>&, int)> exc);
|
||
virtual void addChild(QList<Syntax::SyntaxParser*> parsers) override;
|
||
void refocusNode(Parse::Result::DesNode *ins);
|
||
|
||
Expression* set_common_expression(const QString &name, const QList<Defines::Elm> &defines);
|
||
|
||
private:
|
||
MatchType target_type;
|
||
QString section_name;
|
||
int current_level;
|
||
Parse::Result::DesNode *current_node;
|
||
Parse::Result::DocCore *src_ref;
|
||
|
||
QHash<QString, Element*> elements_store;
|
||
QHash<QString, Expression*> expressions_store;
|
||
QList<Syntax::SyntaxParser*> child_parsers;
|
||
|
||
QHash<QString, ParseRule*> rule_collect;
|
||
};
|
||
|
||
|
||
}
|