QtNovelUI/DesParser/XSyntaxBase.h

254 lines
6.4 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.

#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 &section, 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;
};
}