#pragma once

#include <QString>
#include <QList>

namespace Lex {
    class LexFoundation;

	/**
	 * 解析基准定义单元.
	 */
    struct LexDef
	{
		QString TokenType;									// Token字符
		QString RegExpression;								// 词法解析表达式
	};

	/**
	 * 词法分析结果.
	 */
	struct LexResult
	{
		QString Token;										// Token字符
		QString Text;											// 内容
		int StartRow, StartCol, EndRow, EndCol;	// 波及范围

        friend class LexFoundation;
	private:
		int index_at_segment;
	};

	/**
	 * 字符提取富信息单元.
	 */
	class XChar
	{
	public:
		explicit XChar(QChar c, int row, int col);
		QChar value() const;
		int row() const;
		int col() const;

	private:
		QChar value_store;
		int row_index, col_index;
	};

	/**
	 * 基础词法分析器.
	 */
    class LexFoundation
	{
	public:
        explicit LexFoundation(QList<LexDef> seqence, const QString UnknownToken);
        virtual ~LexFoundation() = default;

		/**
		 * 词法分析器累积解析单个字符流.
		 * 
		 * \param row 行
		 * \param col 列
		 * \param w 字符
		 * \return 累积适配结果，空累积，
		 */
		QList<LexResult> push(int row, int col, const QChar w);

	private:
		QString unknown_token;
		QList<QChar> empty_seq;

		QList<XChar> code_acc; 
        QList<LexDef> lexical_seq;

		QList<LexResult> lexical_parse(const QString &segment);
	};
}
