/***********************************************************************
THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY
DEVELOPER: Zihan Chen(vczh)
***********************************************************************/
#include "VlppOS.h"
#include "Vlpp.h"
#include "VlppGlrParser.h"
#include "VlppReflection.h"
#include "VlppRegex.h"

/***********************************************************************
.\PARSERGEN_GLOBAL\PARSERSYMBOL.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_PARSERSYMBOl
#define VCZH_PARSER2_PARSERGEN_PARSERSYMBOl


namespace vl
{
	namespace glr
	{
		namespace parsergen
		{
			template<typename T>
			struct MappedOwning
			{
			private:
				collections::List<Ptr<T>>				items;

			public:
				collections::List<WString>				order;
				collections::Dictionary<WString, T*>	map;

				bool Add(const WString& name, T* item)
				{
					items.Add(Ptr(item));
					if (map.Keys().Contains(name)) return false;
					order.Add(name);
					map.Add(name, item);
					return true;
				}

				Ptr<T> Remove(const WString& name)
				{
					vint indexKey = map.Keys().IndexOf(name);
					if (indexKey == -1) return nullptr;

					auto raw = map.Values()[indexKey];
					vint indexItem = items.IndexOf(raw);
					auto shared = items[indexItem];

					items.RemoveAt(indexItem);
					order.Remove(name);
					map.Remove(name);

					return shared;
				}
			};

			template<typename ...TArgs>
			void Fill(collections::List<WString>& ss, TArgs&& ...args)
			{
				WString items[] = { args... };
				for (auto& item : items)
				{
					ss.Add(item);
				}
			}

/***********************************************************************
ParserSymbolManager
***********************************************************************/

#define GLR_PARSER_ERROR_LIST(ERROR_ITEM)\
			/* AstSymbolManager */\
			ERROR_ITEM(DuplicatedFileGroup,																			fileGroupName)\
			ERROR_ITEM(DuplicatedFile,																				fileName)\
			ERROR_ITEM(FileGroupDependencyNotExists,																fileGroupName, dependency)\
			ERROR_ITEM(FileGroupCyclicDependency,																	fileGroupName, dependency)\
			ERROR_ITEM(DuplicatedSymbolInFile,																		fileName, symbolName)\
			ERROR_ITEM(DuplicatedSymbolInFileGroup,																	fileName, symbolName, anotherFileName)\
			ERROR_ITEM(DuplicatedClassProp,																			fileName, className, propName)\
			ERROR_ITEM(DuplicatedEnumItem,																			fileName, enumName, propName)\
			ERROR_ITEM(BaseClassNotExists,																			fileName, className, typeName)\
			ERROR_ITEM(BaseClassNotClass,																			fileName, className, typeName)\
			ERROR_ITEM(BaseClassNotPublic,																			fileName, className, typeName)\
			ERROR_ITEM(BaseClassCyclicDependency,																	fileName, className)\
			ERROR_ITEM(FieldTypeNotExists,																			fileName, className, propName)\
			ERROR_ITEM(FieldTypeNotClass,																			fileName, className, propName)\
			ERROR_ITEM(FieldTypeNotPublic,																			fileName, className, propName)\
			/* LexerSymbolManager */\
			ERROR_ITEM(InvalidTokenDefinition,																		code)\
			ERROR_ITEM(DuplicatedToken,																				tokenName)\
			ERROR_ITEM(DuplicatedTokenByDisplayText,																tokenName)\
			ERROR_ITEM(InvalidTokenRegex,																			tokenName, errorMessage)\
			ERROR_ITEM(TokenRegexNotPure,																			tokenName)\
			ERROR_ITEM(DuplicatedTokenFragment,																		fragmentName)\
			ERROR_ITEM(TokenFragmentNotExists,																		fragmentName)\
			/* SyntaxSymbolManager */\
			ERROR_ITEM(DuplicatedRule,																				ruleName)\
			ERROR_ITEM(RuleIsIndirectlyLeftRecursive,																ruleNames)													/* Indirect left recursion must be resolved before */\
			/* SyntaxAst(ResolveName) */\
			ERROR_ITEM(RuleNameConflictedWithToken,																	ruleName)\
			ERROR_ITEM(TypeNotUniqueInRule,																			ruleName, name)\
			ERROR_ITEM(TypeNotExistsInRule,																			ruleName, name)\
			ERROR_ITEM(TypeNotClassInRule,																			ruleName, name)\
			ERROR_ITEM(TokenOrRuleNotExistsInRule,																	ruleName, name)\
			ERROR_ITEM(ReferencedRuleNotPublicInRuleOfDifferentFile,												ruleName, name)\
			ERROR_ITEM(LiteralNotValidToken,																		ruleName, name)\
			ERROR_ITEM(LiteralIsDiscardedToken,																		ruleName, name)\
			ERROR_ITEM(ConditionalLiteralNotValidToken,																ruleName, name)\
			ERROR_ITEM(ConditionalLiteralIsDiscardedToken,															ruleName, name)\
			ERROR_ITEM(ConditionalLiteralIsDisplayText,																ruleName, name)\
			ERROR_ITEM(DuplicatedSwitch,																			switchName)\
			ERROR_ITEM(UnusedSwitch,																				switchName)\
			ERROR_ITEM(SwitchNotExists,																				ruleName, switchName)\
			ERROR_ITEM(SyntaxInvolvesSwitchWithIllegalRuleName,														ruleName)													/* A syntax uses switch should not use rule name that has _SWITCH/SWITCH_ */\
			/* SyntaxAst(CalculateTypes) */\
			ERROR_ITEM(RuleMixedPartialClauseWithOtherClause,														ruleName)\
			ERROR_ITEM(RuleWithDifferentPartialTypes,																ruleName, ruleType, newType)\
			ERROR_ITEM(RuleExplicitTypeIsNotCompatibleWithClauseType,												ruleName, ruleType, newType)								/* The type of the rule is explicitly specified, but it is incompatible with its clauses */\
			ERROR_ITEM(RuleCannotResolveToDeterministicType,														ruleName, ruleType, newType)								/* Unable to resolve to one type from clauses (token, type) or (create, partial) */\
			ERROR_ITEM(CyclicDependedRuleTypeIncompatible,															ruleName, ruleTypes)										/* Types of rules are not compatible to each other when they build cyclic dependency by reuse clauses */\
			ERROR_ITEM(ReuseClauseCannotResolveToDeterministicType,													ruleName, ruleTypes)										/* A reuse clause contains multiple use rule but their types are not compatible to each other */\
			ERROR_ITEM(ReuseClauseContainsNoUseRule,																ruleName)													/* A reuse clause contains no use rule therefore the type cannot be determined */\
			/* SyntaxAst(ValidateSwitchesAndConditions, condition) */\
			ERROR_ITEM(PushedSwitchIsNotTested,																		ruleName, switchName)\
			ERROR_ITEM(SwitchUnaffectedRuleNotExist)\
			/* SyntaxAst(RewriteSyntax_Switch, condition) */\
			ERROR_ITEM(SwitchUnaffectedRuleExpandedToNoClause,														ruleName)\
			ERROR_ITEM(SwitchAffectedRuleExpandedToNoClause,														ruleName, expandedRuleName)\
			/* SyntaxAst(ValidateTypes) */\
			ERROR_ITEM(FieldNotExistsInClause,																		ruleName, clauseType, fieldName)							/* The field does not exist in the type of the clause */\
			ERROR_ITEM(RuleTypeMismatchedToField,																	ruleName, clauseType, fieldName, fieldRuleType)				/* The rule type is not compatible to the assigning field */\
			ERROR_ITEM(AssignmentToNonEnumField,																	ruleName, clauseType, fieldName)							/* Assignment can only assign fields in enum types */\
			ERROR_ITEM(EnumItemMismatchedToField,																	ruleName, clauseType, fieldName, enumItem)					/* Try to assign an unexisting or mismatched enum item to a field in an enum type */\
			ERROR_ITEM(UseRuleWithPartialRule,																		ruleName, useRuleName)										/* A use rule should not be used with a partial rule */\
			ERROR_ITEM(UseRuleInNonReuseClause,																		ruleName, useRuleName)										/* A use rule should only appear in reuse clause */\
			ERROR_ITEM(PartialRuleUsedOnField,																		ruleName, clauseType, partialRuleName, fieldName)			/* A partial rule does not create object, it cannot be assigned to a field */\
			ERROR_ITEM(ClauseTypeMismatchedToPartialRule,															ruleName, clauseType, partialRuleName, partialRuleType)		/* A clause uses a partial rule of an incompatible type */\
			/* SyntaxAst(ValidateStructure, counting) */\
			ERROR_ITEM(ClauseNotCreateObject,																		ruleName)													/* A reuse clause does not contain use rule in some potential sequences */\
			ERROR_ITEM(UseRuleUsedInOptionalBody,																	ruleName, useRuleName)\
			ERROR_ITEM(UseRuleUsedInLoopBody,																		ruleName, useRuleName)\
			ERROR_ITEM(ClauseTooManyUseRule,																		ruleName)													/* Multiple use rules in a potential sequence in a clause */\
			ERROR_ITEM(NonArrayFieldAssignedInLoop,																	ruleName, clauseType, fieldName)\
			ERROR_ITEM(NonLoopablePartialRuleUsedInLoop,															ruleName, clauseType, partialRuleName)\
			ERROR_ITEM(ClauseCouldExpandToEmptySequence,															ruleName)\
			ERROR_ITEM(LoopBodyCouldExpandToEmptySequence,															ruleName)\
			ERROR_ITEM(OptionalBodyCouldExpandToEmptySequence,														ruleName)\
			ERROR_ITEM(NegativeOptionalEndsAClause,																	ruleName)													/* Negative optional syntax cannot ends a clause */\
			ERROR_ITEM(MultiplePrioritySyntaxInAClause,																ruleName)\
			/* SyntaxAst(ValidateStructure, relationship) */\
			ERROR_ITEM(FieldAssignedMoreThanOnce,																	ruleName, clauseType, fieldName)\
			ERROR_ITEM(PartialRuleIsRecursive,																		ruleName)\
			
			enum class ParserErrorType
			{
#define ParserErrorType_EnumItem(NAME, ...) NAME,
				GLR_PARSER_ERROR_LIST(ParserErrorType_EnumItem)
#undef ParserErrorType_EnumItem
			};

			enum class ParserDefFileType
			{
				AstGroup,
				Ast,
				Lexer,
				Syntax,
			};

			struct ParserErrorLocation
			{
				ParserDefFileType			type;
				WString						name;
				ParsingTextRange			codeRange;
			};

			struct ParserError
			{
				ParserErrorType				type;
				ParserErrorLocation			location;
				WString						arg1;
				WString						arg2;
				WString						arg3;
				WString						arg4;
			};

			class ParserSymbolManager : public Object
			{
				using ErrorList = collections::List<ParserError>;
				using StringItems = collections::List<WString>;
			protected:

				ErrorList					errors;
			public:
				WString						name;
				StringItems					astIncludes;
				StringItems					syntaxIncludes;
				StringItems					cppNss;
				WString						headerGuard;

				const auto&					Errors() const { return errors; }

				template<typename ...TArgs>
				void AddError(ParserErrorType type, ParserErrorLocation location, TArgs&& ...args)
				{
					ParserError error;
					error.type = type;
					error.location = location;
					if constexpr (sizeof...(args) > 0)
					{
						WString sargs[] = { WString(args)... };
						WString* dargs[] = { &error.arg1,&error.arg2,&error.arg3,&error.arg4 };
						constexpr vint sl = sizeof(sargs) / sizeof(*sargs);
						constexpr vint dl = sizeof(dargs) / sizeof(*dargs);
						constexpr vint ml = sl < dl ? sl : dl;
						for (vint i = 0; i < ml; i++)
						{
							*dargs[i] = sargs[i];
						}
					}
					errors.Add(std::move(error));
				}
			};

/***********************************************************************
Utility
***********************************************************************/

			extern void						InitializeParserSymbolManager(ParserSymbolManager& manager);
		}
	}
}

#endif

/***********************************************************************
.\AST\ASTSYMBOL.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_AST_ASTSYMBOL
#define VCZH_PARSER2_AST_ASTSYMBOL


namespace vl
{
	namespace glr
	{
		namespace parsergen
		{
			class AstEnumSymbol;
			class AstClassSymbol;
			class AstDefFile;
			class AstDefFileGroup;
			class AstSymbolManager;

/***********************************************************************
AstSymbol
***********************************************************************/

			class AstSymbol : public Object
			{
			protected:
				AstDefFile*							ownerFile = nullptr;
				WString								name;

				AstSymbol(AstDefFile* _file, const WString& _name);
			public:
				bool								isPublic = false;
				AstDefFile*							Owner() const { return ownerFile; }
				const WString&						Name() const { return name; }
			};

/***********************************************************************
AstEnumSymbol
***********************************************************************/

			class AstEnumItemSymbol : public AstSymbol
			{
				friend class AstEnumSymbol;
			protected:
				AstEnumSymbol*						parent = nullptr;

				AstEnumItemSymbol(AstEnumSymbol* _parent, const WString& name);
			public:
				vint								value = 0;

				AstEnumSymbol*						Parent() const { return parent; }
			};

			class AstEnumSymbol : public AstSymbol
			{
				friend class AstDefFile;
			protected:
				MappedOwning<AstEnumItemSymbol>		items;

				AstEnumSymbol(AstDefFile* _file, const WString& _name);
			public:
				AstEnumItemSymbol*					CreateItem(const WString& itemName, ParsingTextRange codeRange = {});

				const auto&							Items() const { return items.map; }
				const auto&							ItemOrder() const { return items.order; }
			};

/***********************************************************************
AstClassSymbol
***********************************************************************/

			enum class AstPropType
			{
				Token,
				Type,
				Array,
			};

			class AstClassPropSymbol : public AstSymbol
			{
				friend class AstClassSymbol;
			protected:
				AstClassSymbol*						parent = nullptr;

				AstClassPropSymbol(AstClassSymbol* _parent, const WString& name);
			public:
				AstPropType							propType = AstPropType::Token;
				AstSymbol*							propSymbol = nullptr;

				AstClassSymbol*						Parent() const { return parent; }
				bool								SetPropType(AstPropType _type, const WString& typeName = WString::Empty, ParsingTextRange codeRange = {});
			};

			enum class AstClassType
			{
				Defined,
				Generated_ToResolve,
				Generated_Common,
			};

			class AstClassSymbol : public AstSymbol
			{
				friend class AstDefFile;
			protected:
				MappedOwning<AstClassPropSymbol>	props;

				AstClassSymbol(AstDefFile* _file, const WString& _name);
			public:
				AstClassType						classType = AstClassType::Defined;
				AstClassSymbol*						baseClass = nullptr;
				collections::List<AstClassSymbol*>	derivedClasses;
				
				AstClassSymbol*						derivedClass_ToResolve = nullptr;
				AstClassSymbol*						derivedClass_Common = nullptr;

				bool								SetBaseClass(const WString& typeName, ParsingTextRange codeRange = {});
				AstClassSymbol*						CreateDerivedClass_ToResolve(ParsingTextRange codeRange);
				AstClassSymbol*						CreateDerivedClass_Common(ParsingTextRange codeRange);
				AstClassPropSymbol*					CreateProp(const WString& propName, ParsingTextRange codeRange = {});

				const auto&							Props() const { return props.map; }
				const auto&							PropOrder() const { return props.order; }
			};

			extern AstClassSymbol*					FindCommonBaseClass(AstClassSymbol* c1, AstClassSymbol* c2);
			extern AstClassPropSymbol*				FindPropSymbol(AstClassSymbol*& type, const WString& name);

/***********************************************************************
AstDefFile
***********************************************************************/

			class AstDefFile : public Object
			{
				friend class AstDefFileGroup;
				using DependenciesList = collections::List<WString>;
				using StringItems = collections::List<WString>;
			protected:
				AstDefFileGroup*			ownerGroup = nullptr;
				WString						name;
				MappedOwning<AstSymbol>		symbols;

				template<typename T>
				T*							CreateSymbol(const WString& symbolName, ParsingTextRange codeRange);

				AstDefFile(AstDefFileGroup* _ownerGroup, const WString& _name);
			public:
				AstDefFileGroup*			Owner() const { return ownerGroup; }
				const WString&				Name() const { return name; }
				AstEnumSymbol*				CreateEnum(const WString& symbolName, bool isPublic = false, ParsingTextRange codeRange = {});
				AstClassSymbol*				CreateClass(const WString& symbolName, bool isPublic = false, ParsingTextRange codeRange = {});

				const auto&					Symbols() const { return symbols.map; }
				const auto&					SymbolOrder() const { return symbols.order; }

				template<typename ...TArgs>
				void AddError(ParserErrorType type, ParsingTextRange codeRange, TArgs&&... args);
			};

/***********************************************************************
AstDefFileGroup
***********************************************************************/

			class AstDefFileGroup : public Object
			{
				friend class AstDefFile;
				friend class AstSymbolManager;
				using DependenciesList = collections::List<WString>;
				using StringItems = collections::List<WString>;
				using SymbolMap = collections::Dictionary<WString, AstSymbol*>;
			protected:
				AstSymbolManager*				ownerManager = nullptr;
				WString							name;
				MappedOwning<AstDefFile>		files;
				SymbolMap						symbolMap;

				AstDefFileGroup(AstSymbolManager* _ownerManager, const WString& _name);
			public:
				DependenciesList				dependencies;
				StringItems						cppNss;
				StringItems						refNss;
				WString							classPrefix;

				AstSymbolManager*				Owner() const { return ownerManager; }
				const WString&					Name() const { return name; }
				bool							AddDependency(const WString& dependency, ParsingTextRange codeRange = {});
				AstDefFile*						CreateFile(const WString& name);

				const auto&						Files() const { return files.map; }
				const auto&						FileOrder() const { return files.order; }
				const auto&						Symbols() const { return symbolMap; }
				collections::LazyList<WString>	SymbolOrder()
				{
					return From(files.order)
						.Select([this](const WString& fileName) { return files.map[fileName]; })
						.SelectMany([](AstDefFile* file) { return From(file->SymbolOrder()); })
						;
				}

				template<typename ...TArgs>
				void AddError(ParserErrorType type, ParsingTextRange codeRange, TArgs&&... args);
			};

/***********************************************************************
AstSymbolManager
***********************************************************************/

			class AstSymbolManager : public Object
			{
				friend class AstDefFile;
				using SymbolGroup = collections::Group<WString, AstSymbol*>;
				using FileMap = collections::Dictionary<WString, AstDefFile*>;
			protected:
				ParserSymbolManager&			global;
				MappedOwning<AstDefFileGroup>	fileGroups;
				SymbolGroup						symbolGroup;
				FileMap							fileMap;

			public:
				AstSymbolManager(ParserSymbolManager& _global);

				AstDefFileGroup*				CreateFileGroup(const WString& name);

				const ParserSymbolManager&		Global() const { return global; }
				const auto&						FileGroups() const { return fileGroups.map; }
				const auto&						FileGroupOrder() const { return fileGroups.order; }
				const auto&						Symbols() const { return symbolGroup; }
				const auto&						Files() const { return fileMap; }
			};

			extern AstDefFile*					CreateParserGenTypeAst(AstSymbolManager& manager);
			extern AstDefFile*					CreateParserGenRuleAst(AstSymbolManager& manager);

/***********************************************************************
AddError
***********************************************************************/

			template<typename ...TArgs>
			void AstDefFile::AddError(ParserErrorType type, ParsingTextRange codeRange, TArgs&&... args)
			{
				auto&& global = const_cast<ParserSymbolManager&>(ownerGroup->Owner()->Global());
				global.AddError(type, { ParserDefFileType::Ast,name,codeRange }, std::forward<TArgs&&>(args)...);
			}

			template<typename ...TArgs>
			void AstDefFileGroup::AddError(ParserErrorType type, ParsingTextRange codeRange, TArgs&&... args)
			{
				auto&& global = const_cast<ParserSymbolManager&>(ownerManager->Global());
				global.AddError(type, { ParserDefFileType::AstGroup,name,codeRange }, std::forward<TArgs&&>(args)...);
			}
		}
	}
}

#endif

/***********************************************************************
.\LEXER\LEXERSYMBOL.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_LEXER_LEXERSYMBOL
#define VCZH_PARSER2_LEXER_LEXERSYMBOL


namespace vl
{
	namespace glr
	{
		namespace parsergen
		{
			class LexerSymbolManager;

/***********************************************************************
LexerSymbolManager
***********************************************************************/

			class TokenSymbol : public Object
			{
				friend class LexerSymbolManager;
			protected:
				LexerSymbolManager*			ownerManager;
				WString						name;

				TokenSymbol(LexerSymbolManager* _ownerManager, const WString& _name);
			public:
				WString						regex;
				WString						displayText;
				bool						discarded = false;
				
				LexerSymbolManager*			Owner() { return ownerManager; }
				const WString&				Name() { return name; }
			};

			class LexerSymbolManager : public Object
			{
				using TokenMap = collections::Dictionary<WString, TokenSymbol*>;
			protected:
				MappedOwning<TokenSymbol>	tokens;
				TokenMap					tokensByDisplayText;
				ParserSymbolManager&		global;

			public:
				LexerSymbolManager(ParserSymbolManager& _global);

				TokenSymbol*				CreateToken(const WString& _name, const WString& _regex, ParsingTextRange codeRange = {});
				TokenSymbol*				CreateDiscardedToken(const WString& _name, const WString& _regex, ParsingTextRange codeRange = {});

				const ParserSymbolManager&	Global() const { return global; }
				const auto&					Tokens() const { return tokens.map; }
				const auto&					TokensByDisplayText() const { return tokensByDisplayText; }
				const auto&					TokenOrder() const { return tokens.order; }

				template<typename ...TArgs>
				void AddError(ParserErrorType type, ParsingTextRange codeRange, TArgs&&... args) const
				{
					global.AddError(type, { ParserDefFileType::Lexer,WString::Empty,codeRange }, std::forward<TArgs&&>(args)...);
				}
			};

			extern void						CreateParserGenLexer(LexerSymbolManager& manager);
		}
	}
}

#endif

/***********************************************************************
.\PARSERGEN_GLOBAL\PARSERCPPGEN.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_PARSERCPPGEN
#define VCZH_PARSER2_PARSERGEN_PARSERCPPGEN


namespace vl
{
	namespace glr
	{
		namespace parsergen
		{
			class AstDefFileGroup;
			class AstClassPropSymbol;
			class AstClassSymbol;
			class TokenSymbol;
			class SyntaxSymbolManager;

/***********************************************************************
Output
***********************************************************************/

			struct CppAstGenOutput
			{
				WString			astH;
				WString			astCpp;
				WString			builderH;
				WString			builderCpp;
				WString			emptyH;
				WString			emptyCpp;
				WString			copyH;
				WString			copyCpp;
				WString			traverseH;
				WString			traverseCpp;
				WString			jsonH;
				WString			jsonCpp;
				WString			jsonDts;
			};

			struct CppSyntaxGenOutput
			{
				WString			syntaxH;
				WString			syntaxCpp;
			};

			struct CppParserGenOutput
			{
				WString																	assemblyH;
				WString																	assemblyCpp;
				WString																	lexerH;
				WString																	lexerCpp;
				collections::Dictionary<AstDefFileGroup*, Ptr<CppAstGenOutput>>			astOutputs;
				collections::Dictionary<SyntaxSymbolManager*, Ptr<CppSyntaxGenOutput>>	syntaxOutputs;

				collections::Dictionary<AstClassSymbol*, vint32_t>						classIds;
				collections::Dictionary<AstClassPropSymbol*, vint32_t>					fieldIds;
				collections::Dictionary<TokenSymbol*, vint32_t>							tokenIds;
			};

/***********************************************************************
Utility
***********************************************************************/

			extern Ptr<CppParserGenOutput>		GenerateParserFileNames(ParserSymbolManager& manager);

			extern void							WriteCppStringBody(const WString& body, stream::StreamWriter& writer);
			extern void							WriteFileComment(const WString& name, stream::StreamWriter& writer);
			extern void							WriteNssName(const collections::List<WString>& cppNss, stream::StreamWriter& writer);
			extern WString						WriteNssBegin(const collections::List<WString>& cppNss, stream::StreamWriter& writer);
			extern void							WriteNssEnd(const collections::List<WString>& cppNss, stream::StreamWriter& writer);
			extern void							WriteLoadDataFunctionHeader(const WString& prefix, const WString& functionName, stream::StreamWriter& writer);
			extern void							WriteLoadDataFunctionCpp(const WString& prefix, const WString& functionName, stream::MemoryStream& rawData, bool compressData, stream::StreamWriter& writer);
		}
	}
}

#endif

/***********************************************************************
.\AST\ASTCPPGEN.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_AST_ASTCPPGEN
#define VCZH_PARSER2_AST_ASTCPPGEN


namespace vl
{
	namespace glr
	{
		namespace parsergen
		{
			extern void											GenerateAstFileNames(AstSymbolManager& manager, Ptr<CppParserGenOutput> parserOutput);

			extern void			WriteAstHeaderFile				(AstDefFileGroup* group, stream::StreamWriter& writer);
			extern void			WriteAstCppFile					(AstDefFileGroup* group, const WString& astHeaderName, stream::StreamWriter& writer);

			extern void			WriteAstUtilityHeaderFile		(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, const WString& extraNss, stream::StreamWriter& writer, Func<void(const WString&)> callback);
			extern void			WriteAstUtilityCppFile			(AstDefFileGroup* group, const WString& utilityHeaderFile, const WString& extraNss, stream::StreamWriter& writer, Func<void(const WString&)> callback);
			extern void			WriteParserUtilityHeaderFile	(AstSymbolManager& manager, Ptr<CppParserGenOutput> output, const WString& guardPostfix, stream::StreamWriter& writer, Func<void(const WString&)> callback);
			extern void			WriteParserUtilityCppFile		(AstSymbolManager& manager, const WString& utilityHeaderFile, stream::StreamWriter& writer, Func<void(const WString&)> callback);

			extern void			WriteAstBuilderHeaderFile		(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteAstBuilderCppFile			(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteEmptyVisitorHeaderFile		(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteEmptyVisitorCppFile		(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteCopyVisitorHeaderFile		(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteCopyVisitorCppFile			(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteTraverseVisitorHeaderFile	(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteTraverseVisitorCppFile		(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteJsonVisitorHeaderFile		(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteJsonVisitorCppFile			(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteJsonVisitorDtsFile			(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);

			extern void			WriteAstAssemblerHeaderFile		(AstSymbolManager& manager, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteAstAssemblerCppFile		(AstSymbolManager& manager, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer);

			extern void			WriteAstFiles					(AstDefFileGroup* group, Ptr<CppAstGenOutput> output, collections::Dictionary<WString, WString>& files);
			extern void			WriteAstFiles					(AstSymbolManager& manager, Ptr<CppParserGenOutput> output, collections::Dictionary<WString, WString>& files);
		}
	}
}

#endif

/***********************************************************************
.\LEXER\LEXERCPPGEN.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_LEXER_LEXERCPPGEN
#define VCZH_PARSER2_LEXER_LEXERCPPGEN


namespace vl
{
	namespace glr
	{
		namespace parsergen
		{
			extern void			WriteLexerHeaderFile			(LexerSymbolManager& manager, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteLexerCppFile				(LexerSymbolManager& manager, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer);
			extern void			WriteLexerFiles					(LexerSymbolManager& manager, Ptr<CppParserGenOutput> output, collections::Dictionary<WString, WString>& files);
		}
	}
}

#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEAST.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:RuleAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_RULEAST_AST
#define VCZH_PARSER2_PARSERGEN_RULEAST_AST


namespace vl::glr::parsergen
{
	class GlrAlternativeSyntax;
	class GlrAndCondition;
	class GlrAssignment;
	class GlrClause;
	class GlrCondition;
	class GlrCreateClause;
	class GlrLoopSyntax;
	class GlrNotCondition;
	class GlrOptionalSyntax;
	class GlrOrCondition;
	class GlrPartialClause;
	class GlrPushConditionSyntax;
	class GlrRefCondition;
	class GlrRefSyntax;
	class GlrReuseClause;
	class GlrRule;
	class GlrSequenceSyntax;
	class GlrSwitchItem;
	class GlrSyntax;
	class GlrSyntaxFile;
	class GlrTestConditionBranch;
	class GlrTestConditionSyntax;
	class GlrUseSyntax;

	enum class GlrSwitchValue
	{
		UNDEFINED_ENUM_ITEM_VALUE = -1,
		False = 0,
		True = 1,
	};

	enum class GlrRefType
	{
		UNDEFINED_ENUM_ITEM_VALUE = -1,
		Id = 0,
		Literal = 1,
		ConditionalLiteral = 2,
	};

	enum class GlrOptionalPriority
	{
		UNDEFINED_ENUM_ITEM_VALUE = -1,
		Equal = 0,
		PreferTake = 1,
		PreferSkip = 2,
	};

	enum class GlrAssignmentType
	{
		UNDEFINED_ENUM_ITEM_VALUE = -1,
		Strong = 0,
		Weak = 1,
	};

	class GlrCondition abstract : public vl::glr::ParsingAstBase, vl::reflection::Description<GlrCondition>
	{
	public:
		class IVisitor : public virtual vl::reflection::IDescriptable, vl::reflection::Description<IVisitor>
		{
		public:
			virtual void Visit(GlrRefCondition* node) = 0;
			virtual void Visit(GlrNotCondition* node) = 0;
			virtual void Visit(GlrAndCondition* node) = 0;
			virtual void Visit(GlrOrCondition* node) = 0;
		};

		virtual void Accept(GlrCondition::IVisitor* visitor) = 0;

	};

	class GlrRefCondition : public GlrCondition, vl::reflection::Description<GlrRefCondition>
	{
	public:
		vl::glr::ParsingToken name;

		void Accept(GlrCondition::IVisitor* visitor) override;
	};

	class GlrNotCondition : public GlrCondition, vl::reflection::Description<GlrNotCondition>
	{
	public:
		vl::Ptr<GlrCondition> condition;

		void Accept(GlrCondition::IVisitor* visitor) override;
	};

	class GlrAndCondition : public GlrCondition, vl::reflection::Description<GlrAndCondition>
	{
	public:
		vl::Ptr<GlrCondition> first;
		vl::Ptr<GlrCondition> second;

		void Accept(GlrCondition::IVisitor* visitor) override;
	};

	class GlrOrCondition : public GlrCondition, vl::reflection::Description<GlrOrCondition>
	{
	public:
		vl::Ptr<GlrCondition> first;
		vl::Ptr<GlrCondition> second;

		void Accept(GlrCondition::IVisitor* visitor) override;
	};

	class GlrSwitchItem : public vl::glr::ParsingAstBase, vl::reflection::Description<GlrSwitchItem>
	{
	public:
		vl::glr::ParsingToken name;
		GlrSwitchValue value = GlrSwitchValue::UNDEFINED_ENUM_ITEM_VALUE;
	};

	class GlrSyntax abstract : public vl::glr::ParsingAstBase, vl::reflection::Description<GlrSyntax>
	{
	public:
		class IVisitor : public virtual vl::reflection::IDescriptable, vl::reflection::Description<IVisitor>
		{
		public:
			virtual void Visit(GlrRefSyntax* node) = 0;
			virtual void Visit(GlrUseSyntax* node) = 0;
			virtual void Visit(GlrLoopSyntax* node) = 0;
			virtual void Visit(GlrOptionalSyntax* node) = 0;
			virtual void Visit(GlrSequenceSyntax* node) = 0;
			virtual void Visit(GlrAlternativeSyntax* node) = 0;
			virtual void Visit(GlrPushConditionSyntax* node) = 0;
			virtual void Visit(GlrTestConditionSyntax* node) = 0;
		};

		virtual void Accept(GlrSyntax::IVisitor* visitor) = 0;

	};

	class GlrRefSyntax : public GlrSyntax, vl::reflection::Description<GlrRefSyntax>
	{
	public:
		GlrRefType refType = GlrRefType::UNDEFINED_ENUM_ITEM_VALUE;
		vl::glr::ParsingToken literal;
		vl::glr::ParsingToken field;

		void Accept(GlrSyntax::IVisitor* visitor) override;
	};

	class GlrUseSyntax : public GlrSyntax, vl::reflection::Description<GlrUseSyntax>
	{
	public:
		vl::glr::ParsingToken name;

		void Accept(GlrSyntax::IVisitor* visitor) override;
	};

	class GlrLoopSyntax : public GlrSyntax, vl::reflection::Description<GlrLoopSyntax>
	{
	public:
		vl::Ptr<GlrSyntax> syntax;
		vl::Ptr<GlrSyntax> delimiter;

		void Accept(GlrSyntax::IVisitor* visitor) override;
	};

	class GlrOptionalSyntax : public GlrSyntax, vl::reflection::Description<GlrOptionalSyntax>
	{
	public:
		GlrOptionalPriority priority = GlrOptionalPriority::UNDEFINED_ENUM_ITEM_VALUE;
		vl::Ptr<GlrSyntax> syntax;

		void Accept(GlrSyntax::IVisitor* visitor) override;
	};

	class GlrSequenceSyntax : public GlrSyntax, vl::reflection::Description<GlrSequenceSyntax>
	{
	public:
		vl::Ptr<GlrSyntax> first;
		vl::Ptr<GlrSyntax> second;

		void Accept(GlrSyntax::IVisitor* visitor) override;
	};

	class GlrAlternativeSyntax : public GlrSyntax, vl::reflection::Description<GlrAlternativeSyntax>
	{
	public:
		vl::Ptr<GlrSyntax> first;
		vl::Ptr<GlrSyntax> second;

		void Accept(GlrSyntax::IVisitor* visitor) override;
	};

	class GlrPushConditionSyntax : public GlrSyntax, vl::reflection::Description<GlrPushConditionSyntax>
	{
	public:
		vl::collections::List<vl::Ptr<GlrSwitchItem>> switches;
		vl::Ptr<GlrSyntax> syntax;

		void Accept(GlrSyntax::IVisitor* visitor) override;
	};

	class GlrTestConditionBranch : public vl::glr::ParsingAstBase, vl::reflection::Description<GlrTestConditionBranch>
	{
	public:
		vl::Ptr<GlrCondition> condition;
		vl::Ptr<GlrSyntax> syntax;
	};

	class GlrTestConditionSyntax : public GlrSyntax, vl::reflection::Description<GlrTestConditionSyntax>
	{
	public:
		vl::collections::List<vl::Ptr<GlrTestConditionBranch>> branches;

		void Accept(GlrSyntax::IVisitor* visitor) override;
	};

	class GlrClause abstract : public vl::glr::ParsingAstBase, vl::reflection::Description<GlrClause>
	{
	public:
		class IVisitor : public virtual vl::reflection::IDescriptable, vl::reflection::Description<IVisitor>
		{
		public:
			virtual void Visit(GlrCreateClause* node) = 0;
			virtual void Visit(GlrPartialClause* node) = 0;
			virtual void Visit(GlrReuseClause* node) = 0;
		};

		virtual void Accept(GlrClause::IVisitor* visitor) = 0;

	};

	class GlrAssignment : public vl::glr::ParsingAstBase, vl::reflection::Description<GlrAssignment>
	{
	public:
		GlrAssignmentType type = GlrAssignmentType::UNDEFINED_ENUM_ITEM_VALUE;
		vl::glr::ParsingToken field;
		vl::glr::ParsingToken value;
	};

	class GlrCreateClause : public GlrClause, vl::reflection::Description<GlrCreateClause>
	{
	public:
		vl::glr::ParsingToken type;
		vl::Ptr<GlrSyntax> syntax;
		vl::collections::List<vl::Ptr<GlrAssignment>> assignments;

		void Accept(GlrClause::IVisitor* visitor) override;
	};

	class GlrPartialClause : public GlrClause, vl::reflection::Description<GlrPartialClause>
	{
	public:
		vl::glr::ParsingToken type;
		vl::Ptr<GlrSyntax> syntax;
		vl::collections::List<vl::Ptr<GlrAssignment>> assignments;

		void Accept(GlrClause::IVisitor* visitor) override;
	};

	class GlrReuseClause : public GlrClause, vl::reflection::Description<GlrReuseClause>
	{
	public:
		vl::Ptr<GlrSyntax> syntax;
		vl::collections::List<vl::Ptr<GlrAssignment>> assignments;

		void Accept(GlrClause::IVisitor* visitor) override;
	};

	class GlrRule : public vl::glr::ParsingAstBase, vl::reflection::Description<GlrRule>
	{
	public:
		vl::glr::ParsingToken attPublic;
		vl::glr::ParsingToken attParser;
		vl::glr::ParsingToken name;
		vl::glr::ParsingToken type;
		vl::collections::List<vl::Ptr<GlrClause>> clauses;
	};

	class GlrSyntaxFile : public vl::glr::ParsingAstBase, vl::reflection::Description<GlrSyntaxFile>
	{
	public:
		vl::collections::List<vl::Ptr<GlrSwitchItem>> switches;
		vl::collections::List<vl::Ptr<GlrRule>> rules;
	};
}
namespace vl::reflection::description
{
#ifndef VCZH_DEBUG_NO_REFLECTION
	DECL_TYPE_INFO(vl::glr::parsergen::GlrCondition)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrCondition::IVisitor)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrRefCondition)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrNotCondition)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrAndCondition)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrOrCondition)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrSwitchValue)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrSwitchItem)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrSyntax)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrSyntax::IVisitor)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrRefType)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrRefSyntax)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrUseSyntax)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrLoopSyntax)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrOptionalPriority)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrOptionalSyntax)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrSequenceSyntax)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrAlternativeSyntax)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrPushConditionSyntax)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrTestConditionBranch)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrTestConditionSyntax)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrClause)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrClause::IVisitor)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrAssignmentType)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrAssignment)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrCreateClause)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrPartialClause)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrReuseClause)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrRule)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrSyntaxFile)

#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA

	BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::glr::parsergen::GlrCondition::IVisitor)
		void Visit(vl::glr::parsergen::GlrRefCondition* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrNotCondition* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrAndCondition* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrOrCondition* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

	END_INTERFACE_PROXY(vl::glr::parsergen::GlrCondition::IVisitor)

	BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::glr::parsergen::GlrSyntax::IVisitor)
		void Visit(vl::glr::parsergen::GlrRefSyntax* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrUseSyntax* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrLoopSyntax* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrOptionalSyntax* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrSequenceSyntax* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrAlternativeSyntax* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrPushConditionSyntax* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrTestConditionSyntax* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

	END_INTERFACE_PROXY(vl::glr::parsergen::GlrSyntax::IVisitor)

	BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::glr::parsergen::GlrClause::IVisitor)
		void Visit(vl::glr::parsergen::GlrCreateClause* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrPartialClause* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrReuseClause* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

	END_INTERFACE_PROXY(vl::glr::parsergen::GlrClause::IVisitor)

#endif
#endif
	/// <summary>Load all reflectable AST types, only available when <b>VCZH_DEBUG_NO_REFLECTION</b> is off.</summary>
	/// <returns>Returns true if this operation succeeded.</returns>
	extern bool ParserGenRuleAstLoadTypes();
}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEAST_BUILDER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:RuleAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_RULEAST_AST_BUILDER
#define VCZH_PARSER2_PARSERGEN_RULEAST_AST_BUILDER


namespace vl::glr::parsergen::builder
{
	class MakeAlternativeSyntax : public vl::glr::ParsingAstBuilder<GlrAlternativeSyntax>
	{
	public:
		MakeAlternativeSyntax& first(const vl::Ptr<GlrSyntax>& value);
		MakeAlternativeSyntax& second(const vl::Ptr<GlrSyntax>& value);
	};

	class MakeAndCondition : public vl::glr::ParsingAstBuilder<GlrAndCondition>
	{
	public:
		MakeAndCondition& first(const vl::Ptr<GlrCondition>& value);
		MakeAndCondition& second(const vl::Ptr<GlrCondition>& value);
	};

	class MakeAssignment : public vl::glr::ParsingAstBuilder<GlrAssignment>
	{
	public:
		MakeAssignment& field(const vl::WString& value);
		MakeAssignment& type(GlrAssignmentType value);
		MakeAssignment& value(const vl::WString& value);
	};

	class MakeCreateClause : public vl::glr::ParsingAstBuilder<GlrCreateClause>
	{
	public:
		MakeCreateClause& assignments(const vl::Ptr<GlrAssignment>& value);
		MakeCreateClause& syntax(const vl::Ptr<GlrSyntax>& value);
		MakeCreateClause& type(const vl::WString& value);
	};

	class MakeLoopSyntax : public vl::glr::ParsingAstBuilder<GlrLoopSyntax>
	{
	public:
		MakeLoopSyntax& delimiter(const vl::Ptr<GlrSyntax>& value);
		MakeLoopSyntax& syntax(const vl::Ptr<GlrSyntax>& value);
	};

	class MakeNotCondition : public vl::glr::ParsingAstBuilder<GlrNotCondition>
	{
	public:
		MakeNotCondition& condition(const vl::Ptr<GlrCondition>& value);
	};

	class MakeOptionalSyntax : public vl::glr::ParsingAstBuilder<GlrOptionalSyntax>
	{
	public:
		MakeOptionalSyntax& priority(GlrOptionalPriority value);
		MakeOptionalSyntax& syntax(const vl::Ptr<GlrSyntax>& value);
	};

	class MakeOrCondition : public vl::glr::ParsingAstBuilder<GlrOrCondition>
	{
	public:
		MakeOrCondition& first(const vl::Ptr<GlrCondition>& value);
		MakeOrCondition& second(const vl::Ptr<GlrCondition>& value);
	};

	class MakePartialClause : public vl::glr::ParsingAstBuilder<GlrPartialClause>
	{
	public:
		MakePartialClause& assignments(const vl::Ptr<GlrAssignment>& value);
		MakePartialClause& syntax(const vl::Ptr<GlrSyntax>& value);
		MakePartialClause& type(const vl::WString& value);
	};

	class MakePushConditionSyntax : public vl::glr::ParsingAstBuilder<GlrPushConditionSyntax>
	{
	public:
		MakePushConditionSyntax& switches(const vl::Ptr<GlrSwitchItem>& value);
		MakePushConditionSyntax& syntax(const vl::Ptr<GlrSyntax>& value);
	};

	class MakeRefCondition : public vl::glr::ParsingAstBuilder<GlrRefCondition>
	{
	public:
		MakeRefCondition& name(const vl::WString& value);
	};

	class MakeRefSyntax : public vl::glr::ParsingAstBuilder<GlrRefSyntax>
	{
	public:
		MakeRefSyntax& field(const vl::WString& value);
		MakeRefSyntax& literal(const vl::WString& value);
		MakeRefSyntax& refType(GlrRefType value);
	};

	class MakeReuseClause : public vl::glr::ParsingAstBuilder<GlrReuseClause>
	{
	public:
		MakeReuseClause& assignments(const vl::Ptr<GlrAssignment>& value);
		MakeReuseClause& syntax(const vl::Ptr<GlrSyntax>& value);
	};

	class MakeRule : public vl::glr::ParsingAstBuilder<GlrRule>
	{
	public:
		MakeRule& attParser(const vl::WString& value);
		MakeRule& attPublic(const vl::WString& value);
		MakeRule& clauses(const vl::Ptr<GlrClause>& value);
		MakeRule& name(const vl::WString& value);
		MakeRule& type(const vl::WString& value);
	};

	class MakeSequenceSyntax : public vl::glr::ParsingAstBuilder<GlrSequenceSyntax>
	{
	public:
		MakeSequenceSyntax& first(const vl::Ptr<GlrSyntax>& value);
		MakeSequenceSyntax& second(const vl::Ptr<GlrSyntax>& value);
	};

	class MakeSwitchItem : public vl::glr::ParsingAstBuilder<GlrSwitchItem>
	{
	public:
		MakeSwitchItem& name(const vl::WString& value);
		MakeSwitchItem& value(GlrSwitchValue value);
	};

	class MakeSyntaxFile : public vl::glr::ParsingAstBuilder<GlrSyntaxFile>
	{
	public:
		MakeSyntaxFile& rules(const vl::Ptr<GlrRule>& value);
		MakeSyntaxFile& switches(const vl::Ptr<GlrSwitchItem>& value);
	};

	class MakeTestConditionBranch : public vl::glr::ParsingAstBuilder<GlrTestConditionBranch>
	{
	public:
		MakeTestConditionBranch& condition(const vl::Ptr<GlrCondition>& value);
		MakeTestConditionBranch& syntax(const vl::Ptr<GlrSyntax>& value);
	};

	class MakeTestConditionSyntax : public vl::glr::ParsingAstBuilder<GlrTestConditionSyntax>
	{
	public:
		MakeTestConditionSyntax& branches(const vl::Ptr<GlrTestConditionBranch>& value);
	};

	class MakeUseSyntax : public vl::glr::ParsingAstBuilder<GlrUseSyntax>
	{
	public:
		MakeUseSyntax& name(const vl::WString& value);
	};

}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEAST_COPY.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:RuleAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_RULEAST_AST_COPY_VISITOR
#define VCZH_PARSER2_PARSERGEN_RULEAST_AST_COPY_VISITOR


namespace vl::glr::parsergen::copy_visitor
{
	/// <summary>A copy visitor, overriding all abstract methods with AST copying code.</summary>
	class RuleAstVisitor
		: public virtual vl::glr::CopyVisitorBase
		, protected virtual GlrCondition::IVisitor
		, protected virtual GlrSyntax::IVisitor
		, protected virtual GlrClause::IVisitor
	{
	protected:
		void CopyFields(GlrAlternativeSyntax* from, GlrAlternativeSyntax* to);
		void CopyFields(GlrAndCondition* from, GlrAndCondition* to);
		void CopyFields(GlrAssignment* from, GlrAssignment* to);
		void CopyFields(GlrClause* from, GlrClause* to);
		void CopyFields(GlrCondition* from, GlrCondition* to);
		void CopyFields(GlrCreateClause* from, GlrCreateClause* to);
		void CopyFields(GlrLoopSyntax* from, GlrLoopSyntax* to);
		void CopyFields(GlrNotCondition* from, GlrNotCondition* to);
		void CopyFields(GlrOptionalSyntax* from, GlrOptionalSyntax* to);
		void CopyFields(GlrOrCondition* from, GlrOrCondition* to);
		void CopyFields(GlrPartialClause* from, GlrPartialClause* to);
		void CopyFields(GlrPushConditionSyntax* from, GlrPushConditionSyntax* to);
		void CopyFields(GlrRefCondition* from, GlrRefCondition* to);
		void CopyFields(GlrRefSyntax* from, GlrRefSyntax* to);
		void CopyFields(GlrReuseClause* from, GlrReuseClause* to);
		void CopyFields(GlrRule* from, GlrRule* to);
		void CopyFields(GlrSequenceSyntax* from, GlrSequenceSyntax* to);
		void CopyFields(GlrSwitchItem* from, GlrSwitchItem* to);
		void CopyFields(GlrSyntax* from, GlrSyntax* to);
		void CopyFields(GlrSyntaxFile* from, GlrSyntaxFile* to);
		void CopyFields(GlrTestConditionBranch* from, GlrTestConditionBranch* to);
		void CopyFields(GlrTestConditionSyntax* from, GlrTestConditionSyntax* to);
		void CopyFields(GlrUseSyntax* from, GlrUseSyntax* to);

	protected:
		virtual void Visit(GlrSwitchItem* node);
		virtual void Visit(GlrTestConditionBranch* node);
		virtual void Visit(GlrAssignment* node);
		virtual void Visit(GlrRule* node);
		virtual void Visit(GlrSyntaxFile* node);

		void Visit(GlrRefCondition* node) override;
		void Visit(GlrNotCondition* node) override;
		void Visit(GlrAndCondition* node) override;
		void Visit(GlrOrCondition* node) override;

		void Visit(GlrRefSyntax* node) override;
		void Visit(GlrUseSyntax* node) override;
		void Visit(GlrLoopSyntax* node) override;
		void Visit(GlrOptionalSyntax* node) override;
		void Visit(GlrSequenceSyntax* node) override;
		void Visit(GlrAlternativeSyntax* node) override;
		void Visit(GlrPushConditionSyntax* node) override;
		void Visit(GlrTestConditionSyntax* node) override;

		void Visit(GlrCreateClause* node) override;
		void Visit(GlrPartialClause* node) override;
		void Visit(GlrReuseClause* node) override;

	public:
		virtual vl::Ptr<GlrCondition> CopyNode(GlrCondition* node);
		virtual vl::Ptr<GlrSyntax> CopyNode(GlrSyntax* node);
		virtual vl::Ptr<GlrClause> CopyNode(GlrClause* node);
		virtual vl::Ptr<GlrSwitchItem> CopyNode(GlrSwitchItem* node);
		virtual vl::Ptr<GlrTestConditionBranch> CopyNode(GlrTestConditionBranch* node);
		virtual vl::Ptr<GlrAssignment> CopyNode(GlrAssignment* node);
		virtual vl::Ptr<GlrRule> CopyNode(GlrRule* node);
		virtual vl::Ptr<GlrSyntaxFile> CopyNode(GlrSyntaxFile* node);

		vl::Ptr<GlrAlternativeSyntax> CopyNode(GlrAlternativeSyntax* node);
		vl::Ptr<GlrAndCondition> CopyNode(GlrAndCondition* node);
		vl::Ptr<GlrCreateClause> CopyNode(GlrCreateClause* node);
		vl::Ptr<GlrLoopSyntax> CopyNode(GlrLoopSyntax* node);
		vl::Ptr<GlrNotCondition> CopyNode(GlrNotCondition* node);
		vl::Ptr<GlrOptionalSyntax> CopyNode(GlrOptionalSyntax* node);
		vl::Ptr<GlrOrCondition> CopyNode(GlrOrCondition* node);
		vl::Ptr<GlrPartialClause> CopyNode(GlrPartialClause* node);
		vl::Ptr<GlrPushConditionSyntax> CopyNode(GlrPushConditionSyntax* node);
		vl::Ptr<GlrRefCondition> CopyNode(GlrRefCondition* node);
		vl::Ptr<GlrRefSyntax> CopyNode(GlrRefSyntax* node);
		vl::Ptr<GlrReuseClause> CopyNode(GlrReuseClause* node);
		vl::Ptr<GlrSequenceSyntax> CopyNode(GlrSequenceSyntax* node);
		vl::Ptr<GlrTestConditionSyntax> CopyNode(GlrTestConditionSyntax* node);
		vl::Ptr<GlrUseSyntax> CopyNode(GlrUseSyntax* node);
	};
}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEAST_EMPTY.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:RuleAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_RULEAST_AST_EMPTY_VISITOR
#define VCZH_PARSER2_PARSERGEN_RULEAST_AST_EMPTY_VISITOR


namespace vl::glr::parsergen::empty_visitor
{
	/// <summary>An empty visitor, overriding all abstract methods with empty implementations.</summary>
	class ConditionVisitor : public vl::Object, public GlrCondition::IVisitor
	{
	protected:
		// Dispatch (virtual) --------------------------------

	public:
		// Visitor Members -----------------------------------
		void Visit(GlrRefCondition* node) override;
		void Visit(GlrNotCondition* node) override;
		void Visit(GlrAndCondition* node) override;
		void Visit(GlrOrCondition* node) override;
	};

	/// <summary>An empty visitor, overriding all abstract methods with empty implementations.</summary>
	class SyntaxVisitor : public vl::Object, public GlrSyntax::IVisitor
	{
	protected:
		// Dispatch (virtual) --------------------------------

	public:
		// Visitor Members -----------------------------------
		void Visit(GlrRefSyntax* node) override;
		void Visit(GlrUseSyntax* node) override;
		void Visit(GlrLoopSyntax* node) override;
		void Visit(GlrOptionalSyntax* node) override;
		void Visit(GlrSequenceSyntax* node) override;
		void Visit(GlrAlternativeSyntax* node) override;
		void Visit(GlrPushConditionSyntax* node) override;
		void Visit(GlrTestConditionSyntax* node) override;
	};

	/// <summary>An empty visitor, overriding all abstract methods with empty implementations.</summary>
	class ClauseVisitor : public vl::Object, public GlrClause::IVisitor
	{
	protected:
		// Dispatch (virtual) --------------------------------

	public:
		// Visitor Members -----------------------------------
		void Visit(GlrCreateClause* node) override;
		void Visit(GlrPartialClause* node) override;
		void Visit(GlrReuseClause* node) override;
	};

}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEAST_JSON.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:RuleAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_RULEAST_AST_JSON_VISITOR
#define VCZH_PARSER2_PARSERGEN_RULEAST_AST_JSON_VISITOR


namespace vl::glr::parsergen::json_visitor
{
	/// <summary>A JSON visitor, overriding all abstract methods with AST to JSON serialization code.</summary>
	class RuleAstVisitor
		: public vl::glr::JsonVisitorBase
		, protected virtual GlrCondition::IVisitor
		, protected virtual GlrSyntax::IVisitor
		, protected virtual GlrClause::IVisitor
	{
	protected:
		virtual void PrintFields(GlrAlternativeSyntax* node);
		virtual void PrintFields(GlrAndCondition* node);
		virtual void PrintFields(GlrAssignment* node);
		virtual void PrintFields(GlrClause* node);
		virtual void PrintFields(GlrCondition* node);
		virtual void PrintFields(GlrCreateClause* node);
		virtual void PrintFields(GlrLoopSyntax* node);
		virtual void PrintFields(GlrNotCondition* node);
		virtual void PrintFields(GlrOptionalSyntax* node);
		virtual void PrintFields(GlrOrCondition* node);
		virtual void PrintFields(GlrPartialClause* node);
		virtual void PrintFields(GlrPushConditionSyntax* node);
		virtual void PrintFields(GlrRefCondition* node);
		virtual void PrintFields(GlrRefSyntax* node);
		virtual void PrintFields(GlrReuseClause* node);
		virtual void PrintFields(GlrRule* node);
		virtual void PrintFields(GlrSequenceSyntax* node);
		virtual void PrintFields(GlrSwitchItem* node);
		virtual void PrintFields(GlrSyntax* node);
		virtual void PrintFields(GlrSyntaxFile* node);
		virtual void PrintFields(GlrTestConditionBranch* node);
		virtual void PrintFields(GlrTestConditionSyntax* node);
		virtual void PrintFields(GlrUseSyntax* node);

	protected:
		void Visit(GlrRefCondition* node) override;
		void Visit(GlrNotCondition* node) override;
		void Visit(GlrAndCondition* node) override;
		void Visit(GlrOrCondition* node) override;

		void Visit(GlrRefSyntax* node) override;
		void Visit(GlrUseSyntax* node) override;
		void Visit(GlrLoopSyntax* node) override;
		void Visit(GlrOptionalSyntax* node) override;
		void Visit(GlrSequenceSyntax* node) override;
		void Visit(GlrAlternativeSyntax* node) override;
		void Visit(GlrPushConditionSyntax* node) override;
		void Visit(GlrTestConditionSyntax* node) override;

		void Visit(GlrCreateClause* node) override;
		void Visit(GlrPartialClause* node) override;
		void Visit(GlrReuseClause* node) override;

	public:
		RuleAstVisitor(vl::stream::StreamWriter& _writer);

		void Print(GlrCondition* node);
		void Print(GlrSyntax* node);
		void Print(GlrClause* node);
		void Print(GlrSwitchItem* node);
		void Print(GlrTestConditionBranch* node);
		void Print(GlrAssignment* node);
		void Print(GlrRule* node);
		void Print(GlrSyntaxFile* node);
	};
}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEAST_TRAVERSE.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:RuleAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_RULEAST_AST_TRAVERSE_VISITOR
#define VCZH_PARSER2_PARSERGEN_RULEAST_AST_TRAVERSE_VISITOR


namespace vl::glr::parsergen::traverse_visitor
{
	/// <summary>A traverse visitor, overriding all abstract methods with AST visiting code.</summary>
	class RuleAstVisitor
		: public vl::Object
		, protected virtual GlrCondition::IVisitor
		, protected virtual GlrSyntax::IVisitor
		, protected virtual GlrClause::IVisitor
	{
	protected:
		virtual void Traverse(vl::glr::ParsingToken& token);
		virtual void Traverse(vl::glr::ParsingAstBase* node);
		virtual void Traverse(GlrAlternativeSyntax* node);
		virtual void Traverse(GlrAndCondition* node);
		virtual void Traverse(GlrAssignment* node);
		virtual void Traverse(GlrClause* node);
		virtual void Traverse(GlrCondition* node);
		virtual void Traverse(GlrCreateClause* node);
		virtual void Traverse(GlrLoopSyntax* node);
		virtual void Traverse(GlrNotCondition* node);
		virtual void Traverse(GlrOptionalSyntax* node);
		virtual void Traverse(GlrOrCondition* node);
		virtual void Traverse(GlrPartialClause* node);
		virtual void Traverse(GlrPushConditionSyntax* node);
		virtual void Traverse(GlrRefCondition* node);
		virtual void Traverse(GlrRefSyntax* node);
		virtual void Traverse(GlrReuseClause* node);
		virtual void Traverse(GlrRule* node);
		virtual void Traverse(GlrSequenceSyntax* node);
		virtual void Traverse(GlrSwitchItem* node);
		virtual void Traverse(GlrSyntax* node);
		virtual void Traverse(GlrSyntaxFile* node);
		virtual void Traverse(GlrTestConditionBranch* node);
		virtual void Traverse(GlrTestConditionSyntax* node);
		virtual void Traverse(GlrUseSyntax* node);

	protected:
		virtual void Finishing(vl::glr::ParsingAstBase* node);
		virtual void Finishing(GlrAlternativeSyntax* node);
		virtual void Finishing(GlrAndCondition* node);
		virtual void Finishing(GlrAssignment* node);
		virtual void Finishing(GlrClause* node);
		virtual void Finishing(GlrCondition* node);
		virtual void Finishing(GlrCreateClause* node);
		virtual void Finishing(GlrLoopSyntax* node);
		virtual void Finishing(GlrNotCondition* node);
		virtual void Finishing(GlrOptionalSyntax* node);
		virtual void Finishing(GlrOrCondition* node);
		virtual void Finishing(GlrPartialClause* node);
		virtual void Finishing(GlrPushConditionSyntax* node);
		virtual void Finishing(GlrRefCondition* node);
		virtual void Finishing(GlrRefSyntax* node);
		virtual void Finishing(GlrReuseClause* node);
		virtual void Finishing(GlrRule* node);
		virtual void Finishing(GlrSequenceSyntax* node);
		virtual void Finishing(GlrSwitchItem* node);
		virtual void Finishing(GlrSyntax* node);
		virtual void Finishing(GlrSyntaxFile* node);
		virtual void Finishing(GlrTestConditionBranch* node);
		virtual void Finishing(GlrTestConditionSyntax* node);
		virtual void Finishing(GlrUseSyntax* node);

	protected:
		void Visit(GlrRefCondition* node) override;
		void Visit(GlrNotCondition* node) override;
		void Visit(GlrAndCondition* node) override;
		void Visit(GlrOrCondition* node) override;

		void Visit(GlrRefSyntax* node) override;
		void Visit(GlrUseSyntax* node) override;
		void Visit(GlrLoopSyntax* node) override;
		void Visit(GlrOptionalSyntax* node) override;
		void Visit(GlrSequenceSyntax* node) override;
		void Visit(GlrAlternativeSyntax* node) override;
		void Visit(GlrPushConditionSyntax* node) override;
		void Visit(GlrTestConditionSyntax* node) override;

		void Visit(GlrCreateClause* node) override;
		void Visit(GlrPartialClause* node) override;
		void Visit(GlrReuseClause* node) override;

	public:
		void InspectInto(GlrCondition* node);
		void InspectInto(GlrSyntax* node);
		void InspectInto(GlrClause* node);
		void InspectInto(GlrSwitchItem* node);
		void InspectInto(GlrTestConditionBranch* node);
		void InspectInto(GlrAssignment* node);
		void InspectInto(GlrRule* node);
		void InspectInto(GlrSyntaxFile* node);
	};
}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEAST.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:TypeAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_TYPEAST_AST
#define VCZH_PARSER2_PARSERGEN_TYPEAST_AST


namespace vl::glr::parsergen
{
	class GlrAstFile;
	class GlrClass;
	class GlrClassProp;
	class GlrEnum;
	class GlrEnumItem;
	class GlrType;

	enum class GlrPropType
	{
		UNDEFINED_ENUM_ITEM_VALUE = -1,
		Token = 0,
		Type = 1,
		Array = 2,
	};

	class GlrType abstract : public vl::glr::ParsingAstBase, vl::reflection::Description<GlrType>
	{
	public:
		class IVisitor : public virtual vl::reflection::IDescriptable, vl::reflection::Description<IVisitor>
		{
		public:
			virtual void Visit(GlrEnum* node) = 0;
			virtual void Visit(GlrClass* node) = 0;
		};

		virtual void Accept(GlrType::IVisitor* visitor) = 0;

		vl::glr::ParsingToken attPublic;
		vl::glr::ParsingToken name;
	};

	class GlrEnumItem : public vl::glr::ParsingAstBase, vl::reflection::Description<GlrEnumItem>
	{
	public:
		vl::glr::ParsingToken name;
	};

	class GlrEnum : public GlrType, vl::reflection::Description<GlrEnum>
	{
	public:
		vl::collections::List<vl::Ptr<GlrEnumItem>> items;

		void Accept(GlrType::IVisitor* visitor) override;
	};

	class GlrClassProp : public vl::glr::ParsingAstBase, vl::reflection::Description<GlrClassProp>
	{
	public:
		vl::glr::ParsingToken name;
		GlrPropType propType = GlrPropType::UNDEFINED_ENUM_ITEM_VALUE;
		vl::glr::ParsingToken propTypeName;
	};

	class GlrClass : public GlrType, vl::reflection::Description<GlrClass>
	{
	public:
		vl::glr::ParsingToken attAmbiguous;
		vl::glr::ParsingToken baseClass;
		vl::collections::List<vl::Ptr<GlrClassProp>> props;

		void Accept(GlrType::IVisitor* visitor) override;
	};

	class GlrAstFile : public vl::glr::ParsingAstBase, vl::reflection::Description<GlrAstFile>
	{
	public:
		vl::collections::List<vl::Ptr<GlrType>> types;
	};
}
namespace vl::reflection::description
{
#ifndef VCZH_DEBUG_NO_REFLECTION
	DECL_TYPE_INFO(vl::glr::parsergen::GlrType)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrType::IVisitor)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrEnumItem)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrEnum)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrPropType)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrClassProp)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrClass)
	DECL_TYPE_INFO(vl::glr::parsergen::GlrAstFile)

#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA

	BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::glr::parsergen::GlrType::IVisitor)
		void Visit(vl::glr::parsergen::GlrEnum* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

		void Visit(vl::glr::parsergen::GlrClass* node) override
		{
			INVOKE_INTERFACE_PROXY(Visit, node);
		}

	END_INTERFACE_PROXY(vl::glr::parsergen::GlrType::IVisitor)

#endif
#endif
	/// <summary>Load all reflectable AST types, only available when <b>VCZH_DEBUG_NO_REFLECTION</b> is off.</summary>
	/// <returns>Returns true if this operation succeeded.</returns>
	extern bool ParserGenTypeAstLoadTypes();
}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEAST_BUILDER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:TypeAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_TYPEAST_AST_BUILDER
#define VCZH_PARSER2_PARSERGEN_TYPEAST_AST_BUILDER


namespace vl::glr::parsergen::builder
{
	class MakeAstFile : public vl::glr::ParsingAstBuilder<GlrAstFile>
	{
	public:
		MakeAstFile& types(const vl::Ptr<GlrType>& value);
	};

	class MakeClass : public vl::glr::ParsingAstBuilder<GlrClass>
	{
	public:
		MakeClass& attAmbiguous(const vl::WString& value);
		MakeClass& baseClass(const vl::WString& value);
		MakeClass& props(const vl::Ptr<GlrClassProp>& value);
		MakeClass& attPublic(const vl::WString& value);
		MakeClass& name(const vl::WString& value);
	};

	class MakeClassProp : public vl::glr::ParsingAstBuilder<GlrClassProp>
	{
	public:
		MakeClassProp& name(const vl::WString& value);
		MakeClassProp& propType(GlrPropType value);
		MakeClassProp& propTypeName(const vl::WString& value);
	};

	class MakeEnum : public vl::glr::ParsingAstBuilder<GlrEnum>
	{
	public:
		MakeEnum& items(const vl::Ptr<GlrEnumItem>& value);
		MakeEnum& attPublic(const vl::WString& value);
		MakeEnum& name(const vl::WString& value);
	};

	class MakeEnumItem : public vl::glr::ParsingAstBuilder<GlrEnumItem>
	{
	public:
		MakeEnumItem& name(const vl::WString& value);
	};

	class MakeType : public vl::glr::ParsingAstBuilder<GlrType>
	{
	public:
		MakeType& attPublic(const vl::WString& value);
		MakeType& name(const vl::WString& value);
	};

}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEAST_COPY.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:TypeAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_TYPEAST_AST_COPY_VISITOR
#define VCZH_PARSER2_PARSERGEN_TYPEAST_AST_COPY_VISITOR


namespace vl::glr::parsergen::copy_visitor
{
	/// <summary>A copy visitor, overriding all abstract methods with AST copying code.</summary>
	class TypeAstVisitor
		: public virtual vl::glr::CopyVisitorBase
		, protected virtual GlrType::IVisitor
	{
	protected:
		void CopyFields(GlrAstFile* from, GlrAstFile* to);
		void CopyFields(GlrClass* from, GlrClass* to);
		void CopyFields(GlrClassProp* from, GlrClassProp* to);
		void CopyFields(GlrEnum* from, GlrEnum* to);
		void CopyFields(GlrEnumItem* from, GlrEnumItem* to);
		void CopyFields(GlrType* from, GlrType* to);

	protected:
		virtual void Visit(GlrEnumItem* node);
		virtual void Visit(GlrClassProp* node);
		virtual void Visit(GlrAstFile* node);

		void Visit(GlrEnum* node) override;
		void Visit(GlrClass* node) override;

	public:
		virtual vl::Ptr<GlrType> CopyNode(GlrType* node);
		virtual vl::Ptr<GlrEnumItem> CopyNode(GlrEnumItem* node);
		virtual vl::Ptr<GlrClassProp> CopyNode(GlrClassProp* node);
		virtual vl::Ptr<GlrAstFile> CopyNode(GlrAstFile* node);

		vl::Ptr<GlrClass> CopyNode(GlrClass* node);
		vl::Ptr<GlrEnum> CopyNode(GlrEnum* node);
	};
}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEAST_EMPTY.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:TypeAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_TYPEAST_AST_EMPTY_VISITOR
#define VCZH_PARSER2_PARSERGEN_TYPEAST_AST_EMPTY_VISITOR


namespace vl::glr::parsergen::empty_visitor
{
	/// <summary>An empty visitor, overriding all abstract methods with empty implementations.</summary>
	class TypeVisitor : public vl::Object, public GlrType::IVisitor
	{
	protected:
		// Dispatch (virtual) --------------------------------

	public:
		// Visitor Members -----------------------------------
		void Visit(GlrEnum* node) override;
		void Visit(GlrClass* node) override;
	};

}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEAST_JSON.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:TypeAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_TYPEAST_AST_JSON_VISITOR
#define VCZH_PARSER2_PARSERGEN_TYPEAST_AST_JSON_VISITOR


namespace vl::glr::parsergen::json_visitor
{
	/// <summary>A JSON visitor, overriding all abstract methods with AST to JSON serialization code.</summary>
	class TypeAstVisitor
		: public vl::glr::JsonVisitorBase
		, protected virtual GlrType::IVisitor
	{
	protected:
		virtual void PrintFields(GlrAstFile* node);
		virtual void PrintFields(GlrClass* node);
		virtual void PrintFields(GlrClassProp* node);
		virtual void PrintFields(GlrEnum* node);
		virtual void PrintFields(GlrEnumItem* node);
		virtual void PrintFields(GlrType* node);

	protected:
		void Visit(GlrEnum* node) override;
		void Visit(GlrClass* node) override;

	public:
		TypeAstVisitor(vl::stream::StreamWriter& _writer);

		void Print(GlrType* node);
		void Print(GlrEnumItem* node);
		void Print(GlrClassProp* node);
		void Print(GlrAstFile* node);
	};
}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEAST_TRAVERSE.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:TypeAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_TYPEAST_AST_TRAVERSE_VISITOR
#define VCZH_PARSER2_PARSERGEN_TYPEAST_AST_TRAVERSE_VISITOR


namespace vl::glr::parsergen::traverse_visitor
{
	/// <summary>A traverse visitor, overriding all abstract methods with AST visiting code.</summary>
	class TypeAstVisitor
		: public vl::Object
		, protected virtual GlrType::IVisitor
	{
	protected:
		virtual void Traverse(vl::glr::ParsingToken& token);
		virtual void Traverse(vl::glr::ParsingAstBase* node);
		virtual void Traverse(GlrAstFile* node);
		virtual void Traverse(GlrClass* node);
		virtual void Traverse(GlrClassProp* node);
		virtual void Traverse(GlrEnum* node);
		virtual void Traverse(GlrEnumItem* node);
		virtual void Traverse(GlrType* node);

	protected:
		virtual void Finishing(vl::glr::ParsingAstBase* node);
		virtual void Finishing(GlrAstFile* node);
		virtual void Finishing(GlrClass* node);
		virtual void Finishing(GlrClassProp* node);
		virtual void Finishing(GlrEnum* node);
		virtual void Finishing(GlrEnumItem* node);
		virtual void Finishing(GlrType* node);

	protected:
		void Visit(GlrEnum* node) override;
		void Visit(GlrClass* node) override;

	public:
		void InspectInto(GlrType* node);
		void InspectInto(GlrEnumItem* node);
		void InspectInto(GlrClassProp* node);
		void InspectInto(GlrAstFile* node);
	};
}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGEN_ASSEMBLER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:ParserGen
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_AST_ASSEMBLER
#define VCZH_PARSER2_PARSERGEN_AST_ASSEMBLER


namespace vl::glr::parsergen
{
	enum class ParserGenClasses : vl::vint32_t
	{
		AlternativeSyntax = 0,
		AndCondition = 1,
		Assignment = 2,
		AstFile = 3,
		Class = 4,
		ClassProp = 5,
		Clause = 6,
		Condition = 7,
		CreateClause = 8,
		Enum = 9,
		EnumItem = 10,
		LoopSyntax = 11,
		NotCondition = 12,
		OptionalSyntax = 13,
		OrCondition = 14,
		PartialClause = 15,
		PushConditionSyntax = 16,
		RefCondition = 17,
		RefSyntax = 18,
		ReuseClause = 19,
		Rule = 20,
		SequenceSyntax = 21,
		SwitchItem = 22,
		Syntax = 23,
		SyntaxFile = 24,
		TestConditionBranch = 25,
		TestConditionSyntax = 26,
		Type = 27,
		UseSyntax = 28,
	};

	enum class ParserGenFields : vl::vint32_t
	{
		AlternativeSyntax_first = 0,
		AlternativeSyntax_second = 1,
		AndCondition_first = 2,
		AndCondition_second = 3,
		Assignment_field = 4,
		Assignment_type = 5,
		Assignment_value = 6,
		AstFile_types = 7,
		Class_attAmbiguous = 8,
		Class_baseClass = 9,
		Class_props = 10,
		ClassProp_name = 11,
		ClassProp_propType = 12,
		ClassProp_propTypeName = 13,
		CreateClause_assignments = 14,
		CreateClause_syntax = 15,
		CreateClause_type = 16,
		Enum_items = 17,
		EnumItem_name = 18,
		LoopSyntax_delimiter = 19,
		LoopSyntax_syntax = 20,
		NotCondition_condition = 21,
		OptionalSyntax_priority = 22,
		OptionalSyntax_syntax = 23,
		OrCondition_first = 24,
		OrCondition_second = 25,
		PartialClause_assignments = 26,
		PartialClause_syntax = 27,
		PartialClause_type = 28,
		PushConditionSyntax_switches = 29,
		PushConditionSyntax_syntax = 30,
		RefCondition_name = 31,
		RefSyntax_field = 32,
		RefSyntax_literal = 33,
		RefSyntax_refType = 34,
		ReuseClause_assignments = 35,
		ReuseClause_syntax = 36,
		Rule_attParser = 37,
		Rule_attPublic = 38,
		Rule_clauses = 39,
		Rule_name = 40,
		Rule_type = 41,
		SequenceSyntax_first = 42,
		SequenceSyntax_second = 43,
		SwitchItem_name = 44,
		SwitchItem_value = 45,
		SyntaxFile_rules = 46,
		SyntaxFile_switches = 47,
		TestConditionBranch_condition = 48,
		TestConditionBranch_syntax = 49,
		TestConditionSyntax_branches = 50,
		Type_attPublic = 51,
		Type_name = 52,
		UseSyntax_name = 53,
	};

	extern const wchar_t* ParserGenTypeName(ParserGenClasses type);
	extern const wchar_t* ParserGenCppTypeName(ParserGenClasses type);
	extern const wchar_t* ParserGenFieldName(ParserGenFields field);
	extern const wchar_t* ParserGenCppFieldName(ParserGenFields field);

	class ParserGenAstInsReceiver : public vl::glr::AstInsReceiverBase
	{
	protected:
		vl::Ptr<vl::glr::ParsingAstBase> CreateAstNode(vl::vint32_t type) override;
		void SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::Ptr<vl::glr::ParsingAstBase> value) override;
		void SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, const vl::regex::RegexToken& token, vl::vint32_t tokenIndex) override;
		void SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::vint32_t enumItem, bool weakAssignment) override;
		vl::Ptr<vl::glr::ParsingAstBase> ResolveAmbiguity(vl::vint32_t type, vl::collections::Array<vl::Ptr<vl::glr::ParsingAstBase>>& candidates) override;
	};
}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGEN_LEXER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:ParserGen
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_LEXER
#define VCZH_PARSER2_PARSERGEN_LEXER


namespace vl::glr::parsergen
{
	enum class ParserGenTokens : vl::vint32_t
	{
		ATT_AMBIGUOUS = 0,
		ATT_PUBLIC = 1,
		ATT_PARSER = 2,
		CLASS = 3,
		ENUM = 4,
		VAR = 5,
		SWITCH = 6,
		TOKEN = 7,
		AS = 8,
		PARTIAL = 9,
		OPEN_ROUND = 10,
		CLOSE_ROUND = 11,
		OPEN_SQUARE = 12,
		CLOSE_SQUARE = 13,
		OPEN_CURLY = 14,
		CLOSE_CURLY = 15,
		OPEN_PUSH = 16,
		OPEN_TEST = 17,
		AND = 18,
		OR = 19,
		COMMA = 20,
		COLON = 21,
		SEMICOLON = 22,
		INFER = 23,
		ALTERNATIVE = 24,
		USE = 25,
		ASSIGN = 26,
		WEAK_ASSIGN = 27,
		POSITIVE = 28,
		NEGATIVE = 29,
		ID = 30,
		STRING = 31,
		CONDITIONAL_LITERAL = 32,
		SPACE = 33,
		COMMENT = 34,
	};

	constexpr vl::vint ParserGenTokenCount = 35;
	extern bool ParserGenTokenDeleter(vl::vint token);
	extern const wchar_t* ParserGenTokenId(ParserGenTokens token);
	extern const wchar_t* ParserGenTokenDisplayText(ParserGenTokens token);
	extern const wchar_t* ParserGenTokenRegex(ParserGenTokens token);
	extern void ParserGenLexerData(vl::stream::IStream& outputStream);
}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEPARSER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:ParserGen
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_RULEPARSER_SYNTAX
#define VCZH_PARSER2_PARSERGEN_RULEPARSER_SYNTAX


namespace vl::glr::parsergen
{
	enum class RuleParserStates
	{
		Cond0 = 0,
		Cond1 = 8,
		Cond2 = 14,
		Cond = 20,
		SwitchItem = 23,
		TestBranch = 28,
		Syntax0 = 34,
		Syntax1 = 73,
		Syntax2 = 78,
		Syntax = 84,
		Assignment = 87,
		Clause = 93,
		Rule = 112,
		File = 122,
	};

	const wchar_t* RuleParserRuleName(vl::vint index);
	const wchar_t* RuleParserStateLabel(vl::vint index);
	extern void ParserGenRuleParserData(vl::stream::IStream& outputStream);

	class RuleParser
		: public vl::glr::ParserBase<ParserGenTokens, RuleParserStates, ParserGenAstInsReceiver>
		, protected vl::glr::automaton::IExecutor::ITypeCallback
	{
	protected:
		vl::WString GetClassName(vl::vint32_t classIndex) const override;
		vl::vint32_t FindCommonBaseClass(vl::vint32_t class1, vl::vint32_t class2) const override;
	public:
		RuleParser();

		vl::Ptr<vl::glr::parsergen::GlrSyntaxFile> ParseFile(const vl::WString& input, vl::vint codeIndex = -1) const;
		vl::Ptr<vl::glr::parsergen::GlrSyntaxFile> ParseFile(vl::collections::List<vl::regex::RegexToken>& tokens, vl::vint codeIndex = -1) const;
	};
}
#endif

/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEPARSER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:ParserGen
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_TYPEPARSER_SYNTAX
#define VCZH_PARSER2_PARSERGEN_TYPEPARSER_SYNTAX


namespace vl::glr::parsergen
{
	enum class TypeParserStates
	{
		EnumItem = 0,
		Enum = 4,
		classProp = 12,
		Class = 23,
		Type = 34,
		File = 38,
	};

	const wchar_t* TypeParserRuleName(vl::vint index);
	const wchar_t* TypeParserStateLabel(vl::vint index);
	extern void ParserGenTypeParserData(vl::stream::IStream& outputStream);

	class TypeParser
		: public vl::glr::ParserBase<ParserGenTokens, TypeParserStates, ParserGenAstInsReceiver>
		, protected vl::glr::automaton::IExecutor::ITypeCallback
	{
	protected:
		vl::WString GetClassName(vl::vint32_t classIndex) const override;
		vl::vint32_t FindCommonBaseClass(vl::vint32_t class1, vl::vint32_t class2) const override;
	public:
		TypeParser();

		vl::Ptr<vl::glr::parsergen::GlrAstFile> ParseFile(const vl::WString& input, vl::vint codeIndex = -1) const;
		vl::Ptr<vl::glr::parsergen::GlrAstFile> ParseFile(vl::collections::List<vl::regex::RegexToken>& tokens, vl::vint codeIndex = -1) const;
	};
}
#endif

/***********************************************************************
.\PARSERGEN_PRINTER\ASTTOCODE.H
***********************************************************************/
#ifndef VCZH_PARSER2_PARSERGEN_ASTTOCODE
#define VCZH_PARSER2_PARSERGEN_ASTTOCODE


namespace vl::glr::parsergen
{
	extern Ptr<GlrAstFile> TypeSymbolToAst(
		const AstSymbolManager& manager,
		bool createGeneratedTypes
	);

	extern void TypeAstToCode(
		Ptr<GlrAstFile> file,
		stream::TextWriter& writer
	);

	extern void SyntaxAstToCode(
		Ptr<GlrSyntaxFile> file,
		stream::TextWriter& writer
	);
}

#endif

/***********************************************************************
.\SYNTAX\SYNTAXSYMBOL.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_SYNTAX_SYNTAXSYMBOL
#define VCZH_PARSER2_SYNTAX_SYNTAXSYMBOL


namespace vl
{
	namespace glr
	{
		namespace parsergen
		{
			class AstSymbolManager;
			class AstClassSymbol;
			class StateSymbol;
			class EdgeSymbol;
			class RuleSymbol;
			class SyntaxSymbolManager;
			class CompactSyntaxBuilder;

/***********************************************************************
StateSymbol
***********************************************************************/

			class StateSymbol : public Object
			{
				friend class EdgeSymbol;
				friend class SyntaxSymbolManager;
				friend class CompactSyntaxBuilder;

				using EdgeList = collections::List<EdgeSymbol*>;
			protected:
				SyntaxSymbolManager*		ownerManager;
				RuleSymbol*					rule;
				EdgeList					inEdges;
				EdgeList					outEdges;

				StateSymbol(RuleSymbol* _rule);
			public:
				WString						label;
				bool						endingState = false;

				SyntaxSymbolManager*		Owner() { return ownerManager; }
				RuleSymbol*					Rule() { return rule; }
				const EdgeList&				InEdges() { return inEdges; }
				const EdgeList&				OutEdges() { return outEdges; }

				void						GetOutEdgesInStableOrder(collections::List<StateSymbol*>& orderedStates, EdgeList& orderedEdges);
			};

/***********************************************************************
EdgeSymbol
***********************************************************************/

			enum class EdgeInputType
			{
				Epsilon,						// No input is needed to execute this edge.
				PrefixMergeRule,				// Rule transition that created from accumulated transitions, it is a temporarily mark and will be converted back to Rule, during prefix-merge process
				PrefixMergeDiscardedRule,		// Rule transition that leads accmuulated transitions, converted to PrefixMergeDiscardedRule during prefix-merge process
				CrossReferencedToken,			// Token transition that created from accumulated transitions, it is a temporarily mark and will be converted back to Token, during cross-reference process

				Ending,							// An epsilon edge that reduces the current rule.
				LeftRec,						// An epsilon edge that reduces the current rule, which is the first input of one of its left recursive clause.
				Token,							// An token is read to execute this edge.
				Rule,							// A rule is reduced to execute this edge.
			};

			struct EdgeInput
			{
				EdgeInputType						type = EdgeInputType::Epsilon;

				// Token
				vint32_t							token = -1;
				Nullable<WString>					condition;

				// Rule
				automaton::ReturnRuleType			ruleType = automaton::ReturnRuleType::Field;
				RuleSymbol*							rule = nullptr;

				auto operator<=>(const EdgeInput&) const = default;
			};

			struct EdgeCompetition
			{
				vint32_t					competitionId = -1;
				bool						highPriority = false;

				auto operator<=>(const EdgeCompetition&) const = default;
			};

			class EdgeSymbol : public Object
			{
				friend class SyntaxSymbolManager;
				friend class CompactSyntaxBuilder;

				using InsList = collections::List<AstIns>;
				using EdgeList = collections::List<EdgeSymbol*>;
				using CompetitionList = collections::List<EdgeCompetition>;
			protected:
				SyntaxSymbolManager*		ownerManager;
				StateSymbol*				fromState;
				StateSymbol*				toState;

				EdgeSymbol(StateSymbol* _from, StateSymbol* _to);
			public:
				EdgeInput					input;											// Input of this edge.
				CompetitionList				competitions;									// Competitions this edge involves in.
																							// (filled by BuildCompactNFA)
																							// If any important edge forms a cross referenced NFA edge, it becomes important too.
				InsList						insAfterInput;									// Instructions to execute after pushing the value from a token or a reduced rule.
				EdgeList					returnEdges;									// Edges of rule reduction.
																							// InsBeforeInput will be copied to a cross-referenced edge.
																							// When a reduction is done, only insAfterInput need to execute.

				SyntaxSymbolManager*		Owner() { return ownerManager; }
				StateSymbol*				From() { return fromState; }
				StateSymbol*				To() { return toState; }
			};

/***********************************************************************
RuleSymbol
***********************************************************************/

			class RuleSymbol : public Object
			{
				friend class SyntaxSymbolManager;

				using StateList = collections::List<StateSymbol*>;
			protected:
				SyntaxSymbolManager*		ownerManager;
				WString						name;
				vint						pmRuleIndex = -1;

				RuleSymbol(SyntaxSymbolManager* _ownerManager, const WString& _name, vint _fileIndex);
			public:
				StateList					startStates;
				vint						fileIndex = -1;
				bool						isPublic = false;
				bool						isParser = false;
				bool						isPartial = false;
				bool						assignedNonArrayField = false;
				AstClassSymbol*				ruleType = nullptr;

				SyntaxSymbolManager*		Owner() { return ownerManager; }
				const WString&				Name() { return name; }
			};

/***********************************************************************
SyntaxSymbolManager
***********************************************************************/

			enum class SyntaxPhase
			{
				EpsilonNFA,					// An automaton that has edges of:
											//   Epsilon
											//   Token
											//   Rule
											//   Ending

				CompactNFA,					// An automaton that has edges of
											//   Token
											//   Rule
											//   Ending
											//   LeftRec
											// with ignored but still existing edges
											//   PrefixMergeDiscardedRule
											// Epsilon edges are eliminated by compressing multiple edges into one.
											// Epsilon edges to the ending state will be compressed to an Ending edge.
											// The first edge of Rule in left-recursive clauses becomes a LeftRec edge, with its fromState changed to the ending state.
											// fromState and toState of non-LeftRec edges belong to the same clause.
											// PrefixMergeRule transitions will be built from several Rule transitions.
											// Such Rule transitions will be disconnected but still stored, and PrefixMergeRule will be renamed to Rule.

				CrossReferencedNFA,			// An automaton that has edges of
											//   Token
											//   Ending
											//   LeftRec
											// with ignored but still existing edges
											//   Rule
											//   PrefixMergeDiscardedRule
											// Edges of Rule are compressed to an edge that pointing towards states in other clauses.
											// Multiple edges of rule are stored in returnEdges in the order of execution.
											// insBeforeInput of an edge contains insBeforeInput from its returnEdges.
											// returnEdges of an edge will be pushed to a stack when it is executed.
											// Executing an Ending edge pops a returnEdges and execute its insAfterInput only.
											// automaton::Executable is exactly the same to CrossReferencedNFA, stored a more cache friendly way.
											// Rule transitions will be kept, but it is not logged, and also ignored during building automaton.
			};

			struct PrefixMergeCache;

			struct PrefixMergeSolutionApplication
			{
				collections::Array<EdgeSymbol*>					edgesToMerge;
				collections::SortedList<RuleSymbol*>			prefixRules;
			};
			using PrefixMergeSolutionApplicationList = collections::List<Ptr<PrefixMergeSolutionApplication>>;

			struct PrefixMergeSolutionValue
			{
				collections::SortedList<RuleSymbol*>			prefixRules;
				PrefixMergeSolutionApplicationList				applications;
			};
			using PrefixMergeSolutionKey = Tuple<RuleSymbol*, StateSymbol*>;
			using PrefixMergeSolutionMap = collections::Dictionary<PrefixMergeSolutionKey, Ptr<PrefixMergeSolutionValue>>;

			struct PrefixMergeApplicationItems;

			class SyntaxSymbolManager : public Object
			{
				using StateList = collections::List<Ptr<StateSymbol>>;
				using EdgeList = collections::List<Ptr<EdgeSymbol>>;
				using StartEndStatePair = collections::Pair<StateSymbol*, StateSymbol*>;
			protected:
				MappedOwning<RuleSymbol>						rules;
				StateList										states;
				EdgeList										edges;
				ParserSymbolManager&							global;
				SyntaxPhase										phase = SyntaxPhase::EpsilonNFA;

			protected:
				struct IncrementalChange
				{
					StateList									createdStates;
					EdgeList									createdEdges;
					bool										reuseOps = true; // In ApplyIncrementalChange, true means to keep opStates and opEdges, false means to remove
					collections::SortedList<StateSymbol*>		opStates;
					collections::SortedList<EdgeSymbol*>		opEdges;
				};

				static StartEndStatePair	EliminateEpsilonEdges(RuleSymbol* rule, StateList& newStates, EdgeList& newEdges);
				static void					BuildLeftRecEdge(EdgeSymbol* newEdge, EdgeSymbol* endingEdge, EdgeSymbol* lrecPrefixEdge);
				static void					EliminateLeftRecursion(RuleSymbol* rule, StateSymbol* startState, StateSymbol* endState, StateList& newStates, EdgeList& newEdges);
				static void					MergeEdgesWithSameInput(RuleSymbol* rule, StateSymbol* startState, StateList& newStates, EdgeList& newEdges);
				static void					MergeEdgesWithSameRuleUsingLeftrec(RuleSymbol* rule, StateSymbol* startState, StateList& newStates, EdgeList& newEdges);

				Ptr<PrefixMergeCache>		CreatePrefixMergeCache();
				static void					PrefixMergeCrossReference_SolveInState(
												PrefixMergeCache* cache,
												RuleSymbol* rule,
												StateSymbol* currentState,
												Ptr<PrefixMergeSolutionApplication> application);
				static void					PrefixMergeCrossReference_Solve(
												PrefixMergeCache* cache,
												bool forStartState,
												RuleSymbol* rule,
												StateSymbol* startState,
												PrefixMergeSolutionMap& prefixMergeSolutions);
				static void					PrefixMergeCrossReference_Solve(PrefixMergeCache* cache, PrefixMergeSolutionMap& prefixMergeSolutions);

				static EdgeSymbol*			PrefixMergeCrossReference_AccumulatedEdges(
												StateSymbol* fromState,
												const WString& pmLabel,
												const collections::List<Ptr<collections::List<EdgeSymbol*>>>& accumulatedEdgesList,
												IncrementalChange& ic);
				static void					PrefixMergeCrossReference_Apply(
												PrefixMergeCache* cache,
												collections::List<EdgeSymbol*>& accumulatedEdges,
												PrefixMergeApplicationItems& pmai);
				static void					PrefixMergeCrossReference_Apply(
												PrefixMergeCache* cache,
												RuleSymbol* rule,
												StateSymbol* currentState,
												Ptr<PrefixMergeSolutionValue> solution,
												IncrementalChange& ic);

				static void					ApplyIncrementalChange(const IncrementalChange& ic, StateList& newStates, EdgeList& newEdges);
				void						BuildCompactNFAInternal();

			protected:

				void						FixCrossReferencedRuleEdge(
												StateSymbol* startState,
												collections::Group<StateSymbol*,
												EdgeSymbol*>& orderedEdges,
												collections::List<EdgeSymbol*>& accumulatedEdges);
				void						BuildCrossReferencedNFAInternal();

			public:
				SyntaxSymbolManager(ParserSymbolManager& _global);

				WString							name;
				vint32_t						usedCompetitionIds = 0;
				PrefixMergeSolutionMap			prefixMergeSolutions;

				RuleSymbol*						CreateRule(const WString& name, vint fileIndex, bool isPublic, bool isParser, ParsingTextRange codeRange = {});
				void							RemoveRule(const WString& name);

				StateSymbol*					CreateState(RuleSymbol* rule);
				EdgeSymbol*						CreateEdge(StateSymbol* from, StateSymbol* to);

				void							BuildCompactNFA();
				void							BuildCrossReferencedNFA();
				void							BuildAutomaton(vint tokenCount, automaton::Executable& executable, automaton::Metadata& metadata);
				void							GetStatesInStableOrder(collections::List<StateSymbol*>& order);
				WString							GetStateGlobalLabel(StateSymbol* state, vint index);

				const ParserSymbolManager&		Global() const { return global; }
				const auto&						Rules() const { return rules.map; }
				const auto&						RuleOrder() { return rules.order; }
				SyntaxPhase						Phase() { return phase; }

				template<typename ...TArgs>
				void AddError(ParserErrorType type, ParsingTextRange codeRange, TArgs&&... args) const
				{
					global.AddError(type, { ParserDefFileType::Syntax,name,codeRange }, std::forward<TArgs&&>(args)...);
				}
			};

			extern void							CreateParserGenTypeSyntax(AstSymbolManager& ast, SyntaxSymbolManager& manager);
			extern void							CreateParserGenRuleSyntax(AstSymbolManager& ast, SyntaxSymbolManager& manager);
		}
	}
}

#endif

/***********************************************************************
.\PARSERGEN\COMPILER.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_PARSERGEN_COMPILER
#define VCZH_PARSER2_PARSERGEN_COMPILER


namespace vl
{
	namespace glr
	{
		namespace parsergen
		{
			namespace compile_syntax
			{
				template<typename TClause>
				struct GenericRuleClausePath
				{
					RuleSymbol*							ruleSymbol = nullptr;
					TClause*							clause = nullptr;

					GenericRuleClausePath() = default;
					GenericRuleClausePath(RuleSymbol* _ruleSymbol, TClause* _clause)
						: ruleSymbol(_ruleSymbol), clause(_clause) {}

					bool operator==(const GenericRuleClausePath& p) const
					{
						if (ruleSymbol != p.ruleSymbol) return false;
						if (clause != p.clause) return false;
						return true;
					}
				};
				using RuleClausePath = GenericRuleClausePath<GlrClause>;

				using RuleSymbolPair = collections::Pair<RuleSymbol*, RuleSymbol*>;

				using GlrRuleMap = collections::Dictionary<RuleSymbol*, GlrRule*>;
				using LiteralTokenMap = collections::Dictionary<GlrRefSyntax*, vint32_t>;
				using RuleDependencies = collections::Group<RuleSymbol*, RuleSymbol*>;
				using ClauseReuseDependencies = collections::Group<GlrReuseClause*, RuleSymbol*>;
				using ClauseTypeMap = collections::Dictionary<GlrClause*, AstClassSymbol*>;

				using ClauseList = collections::List<GlrClause*>;

				struct VisitorContext
				{
					const ParserSymbolManager&			global;
					const AstSymbolManager&				astManager;
					const LexerSymbolManager&			lexerManager;
					const SyntaxSymbolManager&			syntaxManager;

					// ResolveName
					GlrRuleMap							astRules;											// RuleSymbol -> GlrRule
					LiteralTokenMap						literalTokens;
					RuleDependencies					ruleReuseDependencies;								// RuleSymbol -> !rule in that rule
					ClauseReuseDependencies				clauseReuseDependencies;							// GlrReuseClause -> !rule in that clause
					ClauseTypeMap						clauseTypes;										// GlrClause -> type
					Ptr<regex::RegexLexer>				cachedLexer;

					// ValidateStructure
					RuleDependencies					partialRuleDependencies;							// RuleSymbol -> direct referenced partial rule in that partial rule

					VisitorContext(
						const AstSymbolManager& _astManager,
						const LexerSymbolManager& _lexerManager,
						const SyntaxSymbolManager& _syntaxManager
					)
						: global(_syntaxManager.Global())
						, astManager(_astManager)
						, lexerManager(_lexerManager)
						, syntaxManager(_syntaxManager)
					{
					}

					const regex::RegexLexer& GetCachedLexer()
					{
						if (!cachedLexer)
						{
							auto tokens = From(lexerManager.TokenOrder())
								.Select([&](const WString& name) { return lexerManager.Tokens()[name]->regex; });
							cachedLexer = Ptr(new regex::RegexLexer(tokens));
						}
						return *cachedLexer.Obj();
					}
				};

				using SwitchMap = collections::Dictionary<WString, collections::Pair<bool, GlrSwitchItem*>>;
				using RuleSwitchMap = collections::Group<RuleSymbol*, WString>;
				using ClauseSwitchMap = collections::Group<GlrClause*, WString>;

				struct VisitorSwitchContext
				{
					SwitchMap							switches;
					ClauseSwitchMap						clauseAffectedSwitches;								// GlrClause -> all switches that affect how it parses
					RuleSwitchMap						ruleAffectedSwitches;								// RuleSymbol -> all switches that affect how it parses
				};
			}

/***********************************************************************
Compiler
***********************************************************************/

			extern WString						UnescapeLiteral(const WString& literal, wchar_t quot);
			extern void							CompileAst(AstSymbolManager& astManager, collections::List<collections::Pair<AstDefFile*, Ptr<GlrAstFile>>>& files);
			extern void							CompileAst(AstSymbolManager& astManager, AstDefFile* astDefFile, Ptr<GlrAstFile> file);
			extern void							CompileLexer(LexerSymbolManager& lexerManager, const WString& input);
			extern Ptr<GlrSyntaxFile>			CompileSyntax(AstSymbolManager& astManager, LexerSymbolManager& lexerManager, SyntaxSymbolManager& syntaxManager, Ptr<CppParserGenOutput> output, collections::List<Ptr<GlrSyntaxFile>>& files);
			extern Ptr<GlrSyntaxFile>			CompileSyntax(AstSymbolManager& astManager, LexerSymbolManager& lexerManager, SyntaxSymbolManager& syntaxManager, Ptr<CppParserGenOutput> output, Ptr<GlrSyntaxFile> file);
		}
	}
}

#endif

/***********************************************************************
.\SYNTAX\SYNTAXCPPGEN.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_SYNTAX_SYNTAXCPPGEN
#define VCZH_PARSER2_SYNTAX_SYNTAXCPPGEN


namespace vl
{
	namespace glr
	{
		namespace parsergen
		{
			extern Ptr<CppSyntaxGenOutput>		GenerateSyntaxFileNames			(SyntaxSymbolManager& manager, Ptr<CppParserGenOutput> output);
			extern void							WriteSyntaxHeaderFile			(SyntaxSymbolManager& manager, automaton::Executable& executable, automaton::Metadata& metadata, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer);
			extern void							WriteSyntaxCppFile				(SyntaxSymbolManager& manager, automaton::Executable& executable, automaton::Metadata& metadata, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer);
			extern void							WriteSyntaxFiles				(SyntaxSymbolManager& manager, automaton::Executable& executable, automaton::Metadata& metadata, Ptr<CppParserGenOutput> output, collections::Dictionary<WString, WString>& files);
		}
	}
}

#endif

/***********************************************************************
.\SYNTAX\SYNTAXSYMBOLWRITER.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSER2_SYNTAX_SYNTAXWRITER
#define VCZH_PARSER2_SYNTAX_SYNTAXWRITER


namespace vl
{
	namespace glr
	{
		namespace parsergen
		{

/***********************************************************************
AutomatonBuilder
***********************************************************************/

			class AutomatonBuilder
			{
			public:
				struct StatePair
				{
					StateSymbol* begin;
					StateSymbol* end;
				};

			protected:
				using StatePosMap = collections::Dictionary<StateSymbol*, vint>;
				using StateBuilder = Func<StatePair()>;
				using AssignmentBuilder = Func<StatePair(StatePair)>;

			protected:
				vint						usedFieldIds = 0;
				collections::List<AstIns>	fieldIns;
				RuleSymbol*					ruleSymbol;

				WString						clauseDisplayText;
				StatePosMap					startPoses;
				StatePosMap					endPoses;

				StateSymbol* CreateState()
				{
					return ruleSymbol->Owner()->CreateState(ruleSymbol);
				}

				EdgeSymbol* CreateEdge(StateSymbol* from, StateSymbol* to)
				{
					return ruleSymbol->Owner()->CreateEdge(from, to);
				}

				StatePair					BuildRuleSyntaxInternal(RuleSymbol* rule, vint32_t field, automaton::ReturnRuleType ruleType);
			public:
				AutomatonBuilder(RuleSymbol* _ruleSymbol);

				StatePair					BuildTokenSyntax(vint32_t tokenId, const WString& displayText, Nullable<WString> condition, vint32_t field);
				StatePair					BuildFieldRuleSyntax(RuleSymbol* rule, vint32_t field);
				StatePair					BuildDiscardRuleSyntax(RuleSymbol* rule);
				StatePair					BuildUseSyntax(RuleSymbol* rule);
				StatePair					BuildLoopSyntax(const StateBuilder& loopBody, const StateBuilder& loopDelimiter, bool hasDelimiter);
				StatePair					BuildOptionalSyntax(bool preferTake, bool preferSkip, const StateBuilder& optionalBody);
				StatePair					BuildSequenceSyntax(collections::List<StateBuilder>& elements);
				StatePair					BuildAlternativeSyntax(collections::List<StateBuilder>& elements);

				StatePair					BuildClause(const StateBuilder& compileSyntax);
				StatePair					BuildAssignment(StatePair pair, vint32_t enumItem, vint32_t field, bool weakAssignment);
				StatePair					BuildCreateClause(vint32_t classId, const StateBuilder& compileSyntax);
				StatePair					BuildReuseClause(const StateBuilder& compileSyntax);
			};

			namespace syntax_writer
			{

/***********************************************************************
Clause
***********************************************************************/

				struct Token
				{
					vint32_t				id;
					vint32_t				field;
					WString					display;
				};

				struct Rule
				{
					static const vint		Discard = -1;

					RuleSymbol*				rule;
					vint32_t				field;
				};

				struct Use
				{
					RuleSymbol*				rule;
				};

				template<typename T>
				struct Loop
				{
					T						body;
				};

				template<typename T, typename U>
				struct LoopSep
				{
					T						body;
					U						delimiter;
				};

				template<typename T>
				struct Opt
				{
					T						body;
				};

				template<typename T, typename U>
				struct Seq
				{
					T						first;
					U						second;
				};

				template<typename T, typename U>
				struct Alt
				{
					T						first;
					U						second;
				};

				struct WithConfig
				{
					vint32_t				field;
					vint32_t				enumItem;
				};

				template<typename T>
				struct With
				{
					T						body;
					vint32_t				field;
					vint32_t				enumItem;
				};

				template<typename T>
				struct Create
				{
					T						body;
					vint32_t				type;

					template<typename F, typename E>
					Create<With<T>> with(F field, E enumItem)
					{
						return { { body,(vint32_t)field,(vint32_t)enumItem }, type };
					}
				};

				template<typename T>
				struct Reuse
				{
					T						body;

					template<typename F, typename E>
					Reuse<With<T>> with(F field, E enumItem)
					{
						return { { body,(vint32_t)field,(vint32_t)enumItem } };
					}
				};

/***********************************************************************
Verification
***********************************************************************/

				template<typename T>
				struct IsClause_ { static constexpr bool Value = false; };

				template<>
				struct IsClause_<Token> { static constexpr bool Value = true; };

				template<>
				struct IsClause_<Rule> { static constexpr bool Value = true; };

				template<>
				struct IsClause_<Use> { static constexpr bool Value = true; };

				template<typename T>
				struct IsClause_<Loop<T>> { static constexpr bool Value = IsClause_<T>::Value; };

				template<typename T, typename U>
				struct IsClause_<LoopSep<T, U>> { static constexpr bool Value = IsClause_<T>::Value && IsClause_<U>::Value; };

				template<typename T>
				struct IsClause_<Opt<T>> { static constexpr bool Value = IsClause_<T>::Value; };

				template<typename T, typename U>
				struct IsClause_<Seq<T, U>> { static constexpr bool Value = IsClause_<T>::Value && IsClause_<U>::Value; };

				template<typename T, typename U>
				struct IsClause_<Alt<T, U>> { static constexpr bool Value = IsClause_<T>::Value && IsClause_<U>::Value; };

				template<typename T>
				struct IsClause_<With<T>> { static constexpr bool Value = IsClause_<T>::Value; };

				template<typename T>
				struct IsClause_<Create<T>> { static constexpr bool Value = IsClause_<T>::Value; };

				template<typename T>
				struct IsClause_<Reuse<T>> { static constexpr bool Value = IsClause_<T>::Value; };

				template<typename T>
				constexpr bool IsClause = IsClause_<T>::Value;

/***********************************************************************
Operators
***********************************************************************/

				template<typename T>
				inline Token tok(T id, const WString& display)
				{
					return { (vint32_t)id,-1,display };
				}

				template<typename T, typename F>
				inline Token tok(T id, const WString& display, F field = -1)
				{
					return { (vint32_t)id,(vint32_t)field,display };
				}

				inline Rule drule(RuleSymbol* r)
				{
					CHECK_ERROR(!r->isPartial, L"vl::glr::parsergen::syntax_writer::drule(RuleSymbol*)#Rule should not be a partial rule.");
					return { r,Rule::Discard };
				}

				template<typename F>
				inline Rule rule(RuleSymbol* r, F field)
				{
					CHECK_ERROR(!r->isPartial, L"vl::glr::parsergen::syntax_writer::rule(RuleSymbol*, F)#Rule should not be a partial rule.");
					return { r,(vint32_t)field };
				}

				inline Use use(RuleSymbol* r)
				{
					CHECK_ERROR(!r->isPartial, L"vl::glr::parsergen::syntax_writer::use(RuleSymbol*)#Rule should not be a partial rule.");
					return { r };
				}

				template<typename C>
				inline std::enable_if_t<IsClause<C>, Loop<C>> loop(const C& clause)
				{
					return { clause };
				}

				template<typename C1, typename C2>
				inline std::enable_if_t<IsClause<C1> && IsClause<C2>, LoopSep<C1, C2>> loop(const C1& c1, const C2& c2)
				{
					return { c1,c2 };
				}

				template<typename C>
				inline std::enable_if_t<IsClause<C>, Opt<C>> opt(const C& clause)
				{
					return { clause };
				}

				template<typename C1, typename C2>
				inline std::enable_if_t<IsClause<C1> && IsClause<C2>, Seq<C1, C2>> operator+(const C1& c1, const C2& c2)
				{
					return { c1,c2 };
				}

				template<typename C1, typename C2>
				inline std::enable_if_t<IsClause<C1>&& IsClause<C2>, Alt<C1, C2>> operator|(const C1& c1, const C2& c2)
				{
					return { c1,c2 };
				}

				template<typename F, typename E>
				inline WithConfig with(F field, E enumItem)
				{
					return { (vint32_t)field,(vint32_t)enumItem };
				}

				template<typename C1>
				inline std::enable_if_t<IsClause<C1>, With<C1>> operator&&(const C1& c1, const WithConfig& with)
				{
					return { c1,with.field,with.enumItem };
				}

				template<typename C, typename T>
				inline std::enable_if_t<IsClause<C>, Create<C>> create(const C& clause, T type)
				{
					return { clause,(vint32_t)type };
				}

				template<typename C>
				inline std::enable_if_t<IsClause<C>, Reuse<C>> reuse(const C& clause)
				{
					return { clause };
				}

/***********************************************************************
Builder
***********************************************************************/

				struct Clause
				{
					using StatePair = AutomatonBuilder::StatePair;
				private:
					AutomatonBuilder				builder;

					StatePair Build(const Token& clause)
					{
						return builder.BuildTokenSyntax(clause.id, clause.display, {}, clause.field);
					}

					StatePair Build(const Rule& clause)
					{
						if (clause.field == Rule::Discard)
						{
							return builder.BuildDiscardRuleSyntax(clause.rule);
						}
						else
						{
							return builder.BuildFieldRuleSyntax(clause.rule, clause.field);
						}
					}

					StatePair Build(const Use& clause)
					{
						return builder.BuildUseSyntax(clause.rule);
					}

					template<typename C>
					StatePair Build(const Loop<C>& clause)
					{
						return builder.BuildLoopSyntax(
							[this, &clause]() { return Build(clause.body); },
							{},
							false
							);
					}

					template<typename C1, typename C2>
					StatePair Build(const LoopSep<C1, C2>& clause)
					{
						return builder.BuildLoopSyntax(
							[this, &clause]() { return Build(clause.body); },
							[this, &clause]() { return Build(clause.delimiter); },
							true
							);
					}

					template<typename C>
					StatePair Build(const Opt<C>& clause)
					{
						return builder.BuildOptionalSyntax(
							false,
							false,
							[this, &clause]() { return Build(clause.body); }
							);
					}

					template<typename C>
					void CollectSeq(const C& clause, collections::List<Func<StatePair()>>& elements)
					{
						elements.Add([this, &clause] { return Build(clause); });
					}

					template<typename C1, typename C2>
					void CollectSeq(const Seq<C1, C2>& clause, collections::List<Func<StatePair()>>& elements)
					{
						CollectSeq(clause.first, elements);
						CollectSeq(clause.second, elements);
					}

					template<typename C1, typename C2>
					StatePair Build(const Seq<C1, C2>& clause)
					{
						collections::List<Func<StatePair()>> elements;
						CollectSeq(clause, elements);
						return builder.BuildSequenceSyntax(elements);
					}

					template<typename C>
					void CollectAlt(const C& clause, collections::List<Func<StatePair()>>& elements)
					{
						elements.Add([this, &clause] { return Build(clause); });
					}

					template<typename C1, typename C2>
					void CollectAlt(const Alt<C1, C2>& clause, collections::List<Func<StatePair()>>& elements)
					{
						CollectAlt(clause.first, elements);
						CollectAlt(clause.second, elements);
					}

					template<typename C1, typename C2>
					StatePair Build(const Alt<C1, C2>& clause)
					{
						collections::List<Func<StatePair()>> elements;
						CollectAlt(clause, elements);
						return builder.BuildAlternativeSyntax(elements);
					}

					template<typename C>
					StatePair Build(const With<C>& clause)
					{
						return builder.BuildAssignment(Build(clause.body), clause.enumItem, clause.field, false);
					}

					template<typename C>
					StatePair Build(const Create<C>& clause)
					{
						return builder.BuildCreateClause(
							clause.type,
							[this, &clause]() { return Build(clause.body); }
							);
					}

					template<typename C>
					StatePair Build(const Reuse<C>& clause)
					{
						return builder.BuildReuseClause(
							[this, &clause]() { return Build(clause.body); }
							);
					}

					template<typename C>
					void Assign(const C& clause)
					{
						builder.BuildClause(
							[this, &clause]() { return Build(clause); }
							);
					}
				public:
					Clause(RuleSymbol* _ruleSymbol) : builder(_ruleSymbol) {}

					template<typename C>
					Clause& operator=(const Create<C>& clause)
					{
						Assign(clause);
						return *this;
					}

					template<typename C>
					Clause& operator=(const Reuse<C>& clause)
					{
						Assign(clause);
						return *this;
					}

					template<typename C>
					Clause& operator=(const C& clause)
					{
						return operator=(reuse(clause));
					}
				};
			}
		}
	}
}

#endif
