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

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

#ifndef VCZH_PARSING_PARSINGTREE
#define VCZH_PARSING_PARSINGTREE


namespace vl
{
	namespace parsing
	{

/***********************************************************************
Location
***********************************************************************/

		/// <summary>A type representing text position.</summary>
		struct ParsingTextPos
		{
			static const vint	UnknownValue=-2;
			/// <summary>Character index, begins at 0.</summary>
			vint				index;
			/// <summary>Row number, begins at 0.</summary>
			vint				row;
			/// <summary>Column number, begins at 0.</summary>
			vint				column;

			ParsingTextPos()
				:index(UnknownValue)
				,row(UnknownValue)
				,column(UnknownValue)
			{
			}

			ParsingTextPos(vint _index)
				:index(_index)
				,row(UnknownValue)
				,column(UnknownValue)
			{
			}

			ParsingTextPos(vint _row, vint _column)
				:index(UnknownValue)
				,row(_row)
				,column(_column)
			{
			}

			ParsingTextPos(vint _index, vint _row, vint _column)
				:index(_index)
				,row(_row)
				,column(_column)
			{
			}

			/// <summary>Test if this position a valid position.</summary>
			/// <returns>Returns true if this position is a valid position.</returns>
			bool IsInvalid()const
			{
				return index < 0 && row < 0 && column < 0;
			}

			friend std::strong_ordering operator<=>(const ParsingTextPos& a, const ParsingTextPos& b)
			{
				if (a.IsInvalid() && b.IsInvalid())
				{
					return std::strong_ordering::equal;
				}
				else if (a.IsInvalid())
				{
					return std::strong_ordering::less;
				}
				else if (b.IsInvalid())
				{
					return std::strong_ordering::greater;
				}
				else if (a.index >= 0 && b.index >= 0)
				{
					return a.index <=> b.index;
				}
				else if (a.row >= 0 && a.column >= 0 && b.row >= 0 && b.column >= 0)
				{
					if (a.row == b.row)
					{
						return a.column <=> b.column;
					}
					else
					{
						return a.row <=> b.row;
					}
				}
				else
				{
					return std::strong_ordering::equal;
				}
			}

			friend bool operator==(const ParsingTextPos& a, const ParsingTextPos& b)
			{
				return (a <=> b) == 0;
			}
		};

		/// <summary>A type representing text range.</summary>
		struct ParsingTextRange
		{
			/// <summary>Text position for the first character.</summary>
			ParsingTextPos	start;
			/// <summary>Text position for the last character.</summary>
			ParsingTextPos	end;
			/// <summary>Code index, refer to [F:vl.regex.RegexToken.codeIndex]</summary>
			vint			codeIndex;

			ParsingTextRange()
				:codeIndex(-1)
			{
				end.index=-1;
				end.column=-1;
			}

			ParsingTextRange(const ParsingTextPos& _start, const ParsingTextPos& _end, vint _codeIndex = -1)
				:start(_start)
				, end(_end)
				, codeIndex(_codeIndex)
			{
			}

			ParsingTextRange(const regex::RegexToken* startToken, const regex::RegexToken* endToken)
				:codeIndex(startToken->codeIndex)
			{
				start.index=startToken->start;
				start.row=startToken->rowStart;
				start.column=startToken->columnStart;
				end.index=endToken->start+endToken->length-1;
				end.row=endToken->rowEnd;
				end.column=endToken->columnEnd;
			}

			bool operator==(const ParsingTextRange& range)const{return start==range.start && end==range.end;}
			bool operator!=(const ParsingTextRange& range)const{return start!=range.start || end!=range.end;}
			bool Contains(const ParsingTextPos& pos)const{return start<=pos && pos<=end;}
			bool Contains(const ParsingTextRange& range)const{return start<=range.start && range.end<=end;}
		};
	}

	namespace stream
	{
		namespace internal
		{
			BEGIN_SERIALIZATION(parsing::ParsingTextPos)
				SERIALIZE(index)
				SERIALIZE(row)
				SERIALIZE(column)
			END_SERIALIZATION
			
			BEGIN_SERIALIZATION(parsing::ParsingTextRange)
				SERIALIZE(start)
				SERIALIZE(end)
				SERIALIZE(codeIndex)
			END_SERIALIZATION
		}
	}

	namespace parsing
	{
/***********************************************************************
General Syntax Tree
***********************************************************************/

		class ParsingTreeNode;
		class ParsingTreeToken;
		class ParsingTreeObject;
		class ParsingTreeArray;

		/// <summary>Abstract syntax tree, usually created by a sub class of  <see cref="tabling::ParsingGeneralParser"/></summary>
		class ParsingTreeNode : public Object, public reflection::Description<ParsingTreeNode>
		{
		public:
			class IVisitor : public Interface
			{
			public:
				virtual void					Visit(ParsingTreeToken* node)=0;
				virtual void					Visit(ParsingTreeObject* node)=0;
				virtual void					Visit(ParsingTreeArray* node)=0;
			};

			class TraversalVisitor : public Object, public IVisitor
			{
			public:
				enum TraverseDirection
				{
					ByTextPosition,
					ByStorePosition
				};
			protected:
				TraverseDirection				direction;
			public:
				TraversalVisitor(TraverseDirection _direction);

				virtual void					BeforeVisit(ParsingTreeToken* node);
				virtual void					AfterVisit(ParsingTreeToken* node);
				virtual void					BeforeVisit(ParsingTreeObject* node);
				virtual void					AfterVisit(ParsingTreeObject* node);
				virtual void					BeforeVisit(ParsingTreeArray* node);
				virtual void					AfterVisit(ParsingTreeArray* node);

				virtual void					Visit(ParsingTreeToken* node)override;
				virtual void					Visit(ParsingTreeObject* node)override;
				virtual void					Visit(ParsingTreeArray* node)override;
			};
		protected:
			typedef collections::List<Ptr<ParsingTreeNode>>				NodeList;

			ParsingTextRange					codeRange;
			ParsingTreeNode*					parent;
			NodeList							cachedOrderedSubNodes;

			virtual const NodeList&				GetSubNodesInternal()=0;
			bool								BeforeAddChild(Ptr<ParsingTreeNode> node);
			void								AfterAddChild(Ptr<ParsingTreeNode> node);
			bool								BeforeRemoveChild(Ptr<ParsingTreeNode> node);
			void								AfterRemoveChild(Ptr<ParsingTreeNode> node);
		public:
			ParsingTreeNode(const ParsingTextRange& _codeRange);
			~ParsingTreeNode();

			virtual void						Accept(IVisitor* visitor)=0;
			virtual Ptr<ParsingTreeNode>		Clone()=0;
			ParsingTextRange					GetCodeRange();
			void								SetCodeRange(const ParsingTextRange& range);

			/// <summary>Cache necessary data to improve searching performance for this node and all child nodes.</summary>
			void								InitializeQueryCache();
			/// <summary>Clear all cache made by <see cref="InitializeQueryCache"/>.</summary>
			void								ClearQueryCache();
			/// <summary>Get the parent node. Using this function requires <see cref="InitializeQueryCache"/> to be called.</summary>
			/// <returns>The parent node.</returns>
			ParsingTreeNode*					GetParent();
			/// <summary>Get the child nodes. Using this function requires <see cref="InitializeQueryCache"/> to be called.</summary>
			/// <returns>The child nodes.</returns>
			const NodeList&						GetSubNodes();
			
			/// <summary>Find a direct child node at the position. Using this function requires <see cref="InitializeQueryCache"/> to be called.</summary>
			/// <returns>The found node.</returns>
			/// <param name="position">The position.</param>
			ParsingTreeNode*					FindSubNode(const ParsingTextPos& position);
			/// <summary>Find a direct child node at the range. Using this function requires <see cref="InitializeQueryCache"/> to be called.</summary>
			/// <returns>The found node.</returns>
			/// <param name="range">The range.</param>
			ParsingTreeNode*					FindSubNode(const ParsingTextRange& range);
			/// <summary>Find a most deepest indirect child node at the position. Using this function requires <see cref="InitializeQueryCache"/> to be called.</summary>
			/// <returns>The found node.</returns>
			/// <param name="position">The position.</param>
			ParsingTreeNode*					FindDeepestNode(const ParsingTextPos& position);
			/// <summary>Find a most deepest indirect child node at the range. Using this function requires <see cref="InitializeQueryCache"/> to be called.</summary>
			/// <returns>The found node.</returns>
			/// <param name="range">The range.</param>
			ParsingTreeNode*					FindDeepestNode(const ParsingTextRange& range);
		};

		/// <summary>Representing a token node in an abstract syntax tree.</summary>
		class ParsingTreeToken : public ParsingTreeNode, public reflection::Description<ParsingTreeToken>
		{
		protected:
			WString								value;
			vint								tokenIndex;

			const NodeList&						GetSubNodesInternal()override;
		public:
			ParsingTreeToken(const WString& _value, vint _tokenIndex=-1, const ParsingTextRange& _codeRange=ParsingTextRange());
			~ParsingTreeToken();

			void								Accept(IVisitor* visitor)override;
			Ptr<ParsingTreeNode>				Clone()override;
			vint								GetTokenIndex();
			void								SetTokenIndex(vint _tokenIndex);
			/// <summary>Get the content of the token.</summary>
			/// <returns>The content of the token.</returns>
			const WString&						GetValue();
			void								SetValue(const WString& _value);
		};
		
		/// <summary>Representing an object node in an abstract syntax tree.</summary>
		class ParsingTreeObject : public ParsingTreeNode, public reflection::Description<ParsingTreeObject>
		{
		protected:
			typedef collections::Dictionary<WString, Ptr<ParsingTreeNode>>				NodeMap;
			typedef collections::SortedList<WString>									NameList;
			typedef collections::List<WString>											RuleList;

			WString								type;
			NodeMap								members;
			RuleList							rules;

			const NodeList&			GetSubNodesInternal()override;
		public:
			ParsingTreeObject(const WString& _type=L"", const ParsingTextRange& _codeRange=ParsingTextRange());
			~ParsingTreeObject();

			void								Accept(IVisitor* visitor)override;
			Ptr<ParsingTreeNode>				Clone()override;
			/// <summary>Get the type name of the object.</summary>
			/// <returns>The type name of the object.</returns>
			const WString&						GetType();
			void								SetType(const WString& _type);
			/// <summary>Get all fields of the object.</summary>
			/// <returns>All fields of the object.</returns>
			NodeMap&							GetMembers();
			/// <summary>Get a field of the object by the field name.</summary>
			/// <returns>The field of the object.</returns>
			/// <param name="name">The field name.</param>
			Ptr<ParsingTreeNode>				GetMember(const WString& name);
			bool								SetMember(const WString& name, Ptr<ParsingTreeNode> node);
			bool								RemoveMember(const WString& name);
			/// <summary>Get all field names.</summary>
			/// <returns>All field names of the object.</returns>
			const NameList&						GetMemberNames();
			/// <summary>Get names of all rules that return this object.</summary>
			/// <returns>Names of all rules.</returns>
			RuleList&							GetCreatorRules();
		};
		
		/// <summary>Representing an array node in an abstract syntax tree.</summary>
		class ParsingTreeArray : public ParsingTreeNode, public reflection::Description<ParsingTreeArray>
		{
		protected:
			typedef collections::List<Ptr<ParsingTreeNode>>								NodeArray;

			WString								elementType;
			NodeArray							items;

			const NodeList&						GetSubNodesInternal()override;
		public:
			ParsingTreeArray(const WString& _elementType=L"", const ParsingTextRange& _codeRange=ParsingTextRange());
			~ParsingTreeArray();

			void								Accept(IVisitor* visitor)override;
			Ptr<ParsingTreeNode>				Clone()override;
			/// <summary>Get the type of all elements. It could be different from any actual element's type, but it should at least be the base types of them.</summary>
			/// <returns>The type of all elements.</returns>
			const WString&						GetElementType();
			void								SetElementType(const WString& _elementType);
			/// <summary>Get all elements in this array.</summary>
			/// <returns>All elements in this array.</returns>
			NodeArray&							GetItems();
			/// <summary>Get a specified element in this array by the index.</summary>
			/// <returns>The element.</returns>
			/// <param name="index">The index of the element.</param>
			Ptr<ParsingTreeNode>				GetItem(vint index);
			bool								SetItem(vint index, Ptr<ParsingTreeNode> node);
			bool								AddItem(Ptr<ParsingTreeNode> node);
			bool								InsertItem(vint index, Ptr<ParsingTreeNode> node);
			bool								RemoveItem(vint index);
			bool								RemoveItem(ParsingTreeNode* node);
			vint								IndexOfItem(ParsingTreeNode* node);
			bool								ContainsItem(ParsingTreeNode* node);
			vint								Count();
			bool								Clear();
		};

/***********************************************************************
AST Building Block
***********************************************************************/

		/// <summary>Base type of all strong typed syntax tree. Normally all strong typed syntax tree are generated from a grammar file using ParserGen.exe in Tools project. See [T:vl.parsing.tabling.ParsingTable] for details.</summary>
		class ParsingTreeCustomBase : public Object, public reflection::Description<ParsingTreeCustomBase>
		{
		public:
			/// <summary>Range of all tokens that form this object.</summary>
			ParsingTextRange					codeRange;
			/// <summary>Names of all rules that return this object.</summary>
			collections::List<WString>			creatorRules;
		};

		/// <summary>Strong typed token syntax node, for all class fields of type "token" in the grammar file. See [T:vl.parsing.tabling.ParsingTable] for details.</summary>
		class ParsingToken : public ParsingTreeCustomBase, public reflection::Description<ParsingToken>
		{
		public:
			/// <summary>Type of the token, representing the index of a regular expression that creates this token in the regular expression list in the grammar file.</summary>
			vint								tokenIndex;
			/// <summary>Content of the token.</summary>
			WString								value;

			ParsingToken():tokenIndex(-1){}
		};

		/// <summary>Error.</summary>
		class ParsingError : public Object, public reflection::Description<ParsingError>
		{
		public:
			/// <summary>Range where the error happens.</summary>
			ParsingTextRange					codeRange;
			/// <summary>Token at which the error happens.</summary>
			const regex::RegexToken*			token;
			/// <summary>A syntax tree that contains this error.</summary>
			ParsingTreeCustomBase*				parsingTree;
			/// <summary>The error message.</summary>
			WString								errorMessage;

			ParsingError();
			ParsingError(const WString& _errorMessage);
			ParsingError(const regex::RegexToken* _token, const WString& _errorMessage);
			ParsingError(ParsingTreeCustomBase* _parsingTree, const WString& _errorMessage);
			~ParsingError();
		};

/***********************************************************************
Syntax Tree Serialization Helper
***********************************************************************/

		class ParsingTreeConverter : public Object
		{
		public:
			typedef collections::List<regex::RegexToken>	TokenList;

			virtual Ptr<ParsingTreeCustomBase>				ConvertClass(Ptr<ParsingTreeObject> obj, const TokenList& tokens)=0;

			bool SetMember(ParsingToken& member, Ptr<ParsingTreeNode> node, const TokenList& tokens)
			{
				Ptr<ParsingTreeToken> token=node.Cast<ParsingTreeToken>();
				if(token)
				{
					member.tokenIndex=token->GetTokenIndex();
					member.value=token->GetValue();
					member.codeRange=token->GetCodeRange();
					return true;
				}
				return false;
			}

			template<typename T>
			bool SetMember(collections::List<T>& member, Ptr<ParsingTreeNode> node, const TokenList& tokens)
			{
				Ptr<ParsingTreeArray> arr=node.Cast<ParsingTreeArray>();
				if(arr)
				{
					member.Clear();
					vint count=arr->Count();
					for(vint i=0;i<count;i++)
					{
						T t;
						SetMember(t, arr->GetItem(i), tokens);
						member.Add(t);
					}
					return true;
				}
				return false;
			}

			template<typename T>
			bool SetMember(Ptr<T>& member, Ptr<ParsingTreeNode> node, const TokenList& tokens)
			{
				Ptr<ParsingTreeObject> obj=node.Cast<ParsingTreeObject>();
				if(obj)
				{
					Ptr<ParsingTreeCustomBase> tree=ConvertClass(obj, tokens);
					if(tree)
					{
						tree->codeRange=node->GetCodeRange();
						member=tree.Cast<T>();
						return member;
					}
				}
				return false;
			}
		};

/***********************************************************************
Logging
***********************************************************************/

		class IParsingPrintNodeRecorder : public virtual Interface
		{
		public:
			virtual void						Record(ParsingTreeCustomBase* node, const ParsingTextRange& range) = 0;
		};

		class ParsingEmptyPrintNodeRecorder : public Object, public virtual IParsingPrintNodeRecorder
		{
		public:
			ParsingEmptyPrintNodeRecorder();
			~ParsingEmptyPrintNodeRecorder();

			void								Record(ParsingTreeCustomBase* node, const ParsingTextRange& range)override;
		};

		class ParsingMultiplePrintNodeRecorder : public Object, public virtual IParsingPrintNodeRecorder
		{
			typedef collections::List<Ptr<IParsingPrintNodeRecorder>>				RecorderList;
		protected:
			RecorderList						recorders;

		public:
			ParsingMultiplePrintNodeRecorder();
			~ParsingMultiplePrintNodeRecorder();

			void								AddRecorder(Ptr<IParsingPrintNodeRecorder> recorder);
			void								Record(ParsingTreeCustomBase* node, const ParsingTextRange& range)override;
		};

		class ParsingOriginalLocationRecorder : public Object, public virtual IParsingPrintNodeRecorder
		{
		protected:
			Ptr<IParsingPrintNodeRecorder>		recorder;

		public:
			ParsingOriginalLocationRecorder(Ptr<IParsingPrintNodeRecorder> _recorder);
			~ParsingOriginalLocationRecorder();

			void								Record(ParsingTreeCustomBase* node, const ParsingTextRange& range)override;
		};

		class ParsingGeneratedLocationRecorder : public Object, public virtual IParsingPrintNodeRecorder
		{
			typedef collections::Dictionary<ParsingTreeCustomBase*, ParsingTextRange>		RangeMap;
		protected:
			RangeMap&							rangeMap;

		public:
			ParsingGeneratedLocationRecorder(RangeMap& _rangeMap);
			~ParsingGeneratedLocationRecorder();

			void								Record(ParsingTreeCustomBase* node, const ParsingTextRange& range)override;
		};

		class ParsingUpdateLocationRecorder : public Object, public virtual IParsingPrintNodeRecorder
		{
		public:
			ParsingUpdateLocationRecorder();
			~ParsingUpdateLocationRecorder();

			void								Record(ParsingTreeCustomBase* node, const ParsingTextRange& range)override;
		};

		class ParsingWriter : public stream::TextWriter
		{
			typedef collections::Pair<ParsingTreeCustomBase*, ParsingTextPos>				NodePosPair;
			typedef collections::List<NodePosPair>											NodePosList;
		protected:
			stream::TextWriter&					writer;
			Ptr<IParsingPrintNodeRecorder>		recorder;
			vint								codeIndex;
			ParsingTextPos						lastPos;
			ParsingTextPos						currentPos;
			NodePosList							nodePositions;

			void								HandleChar(wchar_t c);
		public:
			ParsingWriter(stream::TextWriter& _writer, Ptr<IParsingPrintNodeRecorder> _recorder = nullptr, vint _codeIndex = -1);
			~ParsingWriter();

			using stream::TextWriter::WriteString;
			void								WriteChar(wchar_t c)override;
			void								WriteString(const wchar_t* string, vint charCount)override;
			void								BeforePrint(ParsingTreeCustomBase* node);
			void								AfterPrint(ParsingTreeCustomBase* node);
		};

		extern void								Log(ParsingTreeNode* node, const WString& originalInput, stream::TextWriter& writer, const WString& prefix=L"");
	}
}

#endif


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

#ifndef VCZH_PARSING_PARSINGDEFINITIONS
#define VCZH_PARSING_PARSINGDEFINITIONS


namespace vl
{
	namespace parsing
	{
		namespace definitions
		{

/***********************************************************************
Attributes
***********************************************************************/

			class ParsingDefinitionAttribute : public ParsingTreeCustomBase
			{
			public:
				WString											name;
				collections::List<WString>						arguments;
			};

			class ParsingDefinitionBase : public ParsingTreeCustomBase
			{
				typedef collections::List<Ptr<ParsingDefinitionAttribute>>				AttributeList;
			public:
				AttributeList									attributes;
			};

/***********************************************************************
Type
***********************************************************************/

			class ParsingDefinitionPrimitiveType;
			class ParsingDefinitionTokenType;
			class ParsingDefinitionSubType;
			class ParsingDefinitionArrayType;

			class ParsingDefinitionType : public ParsingTreeCustomBase
			{
			public:
				class IVisitor : public Interface
				{
				public:
					virtual void								Visit(ParsingDefinitionPrimitiveType* node)=0;
					virtual void								Visit(ParsingDefinitionTokenType* node)=0;
					virtual void								Visit(ParsingDefinitionSubType* node)=0;
					virtual void								Visit(ParsingDefinitionArrayType* node)=0;
				};

				virtual void									Accept(IVisitor* visitor)=0;
			};

			class ParsingDefinitionPrimitiveType : public ParsingDefinitionType
			{
			public:
				WString											name;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionTokenType : public ParsingDefinitionType
			{
			public:

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionSubType : public ParsingDefinitionType
			{
			public:
				Ptr<ParsingDefinitionType>						parentType;
				WString											subTypeName;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionArrayType : public ParsingDefinitionType
			{
			public:
				Ptr<ParsingDefinitionType>						elementType;

				void											Accept(IVisitor* visitor)override;
			};

/***********************************************************************
Type Definition
***********************************************************************/

			class ParsingDefinitionClassMemberDefinition;
			class ParsingDefinitionClassDefinition;
			class ParsingDefinitionEnumMemberDefinition;
			class ParsingDefinitionEnumDefinition;

			class ParsingDefinitionTypeDefinition : public ParsingDefinitionBase
			{
			public:
				class IVisitor : public Interface
				{
				public:
					virtual void								Visit(ParsingDefinitionClassMemberDefinition* node)=0;
					virtual void								Visit(ParsingDefinitionClassDefinition* node)=0;
					virtual void								Visit(ParsingDefinitionEnumMemberDefinition* node)=0;
					virtual void								Visit(ParsingDefinitionEnumDefinition* node)=0;
				};

				virtual void									Accept(IVisitor* visitor)=0;
			public:
				WString											name;
			};

			class ParsingDefinitionClassMemberDefinition : public ParsingDefinitionTypeDefinition
			{
			public:
				Ptr<ParsingDefinitionType>						type;
				WString											unescapingFunction;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionClassDefinition : public ParsingDefinitionTypeDefinition
			{
			public:
				typedef collections::List<Ptr<ParsingDefinitionClassMemberDefinition>>	MemberList;
				typedef collections::List<Ptr<ParsingDefinitionTypeDefinition>>			TypeList;

				Ptr<ParsingDefinitionType>						ambiguousType;
				Ptr<ParsingDefinitionType>						parentType;
				MemberList										members;
				TypeList										subTypes;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionEnumMemberDefinition : public ParsingDefinitionTypeDefinition
			{
			public:

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionEnumDefinition : public ParsingDefinitionTypeDefinition
			{
			public:
				typedef collections::List<Ptr<ParsingDefinitionEnumMemberDefinition>>	MemberList;

				MemberList										members;

				void											Accept(IVisitor* visitor)override;
			};

/***********************************************************************
Grammar
***********************************************************************/

			class ParsingDefinitionPrimitiveGrammar;
			class ParsingDefinitionTextGrammar;
			class ParsingDefinitionSequenceGrammar;
			class ParsingDefinitionAlternativeGrammar;
			class ParsingDefinitionLoopGrammar;
			class ParsingDefinitionOptionalGrammar;
			class ParsingDefinitionCreateGrammar;
			class ParsingDefinitionAssignGrammar;
			class ParsingDefinitionUseGrammar;
			class ParsingDefinitionSetterGrammar;

			class ParsingDefinitionGrammar : public ParsingTreeCustomBase
			{
			public:
				class IVisitor : public Interface
				{
				public:
					virtual void								Visit(ParsingDefinitionPrimitiveGrammar* node)=0;
					virtual void								Visit(ParsingDefinitionTextGrammar* node)=0;
					virtual void								Visit(ParsingDefinitionSequenceGrammar* node)=0;
					virtual void								Visit(ParsingDefinitionAlternativeGrammar* node)=0;
					virtual void								Visit(ParsingDefinitionLoopGrammar* node)=0;
					virtual void								Visit(ParsingDefinitionOptionalGrammar* node)=0;
					virtual void								Visit(ParsingDefinitionCreateGrammar* node)=0;
					virtual void								Visit(ParsingDefinitionAssignGrammar* node)=0;
					virtual void								Visit(ParsingDefinitionUseGrammar* node)=0;
					virtual void								Visit(ParsingDefinitionSetterGrammar* node)=0;
				};

				virtual void									Accept(IVisitor* visitor)=0;
			};

			class ParsingDefinitionPrimitiveGrammar : public ParsingDefinitionGrammar
			{
			public:
				WString											name;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionTextGrammar : public ParsingDefinitionGrammar
			{
			public:
				WString											text;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionSequenceGrammar : public ParsingDefinitionGrammar
			{
			public:
				Ptr<ParsingDefinitionGrammar>					first;
				Ptr<ParsingDefinitionGrammar>					second;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionAlternativeGrammar : public ParsingDefinitionGrammar
			{
			public:
				Ptr<ParsingDefinitionGrammar>					first;
				Ptr<ParsingDefinitionGrammar>					second;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionLoopGrammar : public ParsingDefinitionGrammar
			{
			public:
				Ptr<ParsingDefinitionGrammar>					grammar;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionOptionalGrammar : public ParsingDefinitionGrammar
			{
			public:
				Ptr<ParsingDefinitionGrammar>					grammar;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionCreateGrammar : public ParsingDefinitionGrammar
			{
			public:
				Ptr<ParsingDefinitionGrammar>					grammar;
				Ptr<ParsingDefinitionType>						type;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionAssignGrammar : public ParsingDefinitionGrammar
			{
			public:
				Ptr<ParsingDefinitionGrammar>					grammar;
				WString											memberName;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionUseGrammar : public ParsingDefinitionGrammar
			{
			public:
				Ptr<ParsingDefinitionGrammar>					grammar;

				void											Accept(IVisitor* visitor)override;
			};

			class ParsingDefinitionSetterGrammar : public ParsingDefinitionGrammar
			{
			public:
				Ptr<ParsingDefinitionGrammar>					grammar;
				WString											memberName;
				WString											value;

				void											Accept(IVisitor* visitor)override;
			};

/***********************************************************************
Token and Rule
***********************************************************************/

			class ParsingDefinitionTokenDefinition : public ParsingDefinitionBase
			{
			public:
				WString											name;
				WString											regex;
				bool											discard;
			};

			class ParsingDefinitionRuleDefinition : public ParsingDefinitionBase
			{
			public:
				WString															name;
				Ptr<ParsingDefinitionType>										type;
				collections::List<Ptr<ParsingDefinitionGrammar>>				grammars;
			};

			class ParsingDefinition : public ParsingTreeCustomBase
			{
			public:
				collections::List<Ptr<ParsingDefinitionTypeDefinition>>			types;
				collections::List<Ptr<ParsingDefinitionTokenDefinition>>		tokens;
				collections::List<Ptr<ParsingDefinitionRuleDefinition>>			rules;
			};

/***********************************************************************
Attribute Writer
***********************************************************************/

			class ParsingDefinitionAttributeWriter : public Object
			{
				friend ParsingDefinitionAttributeWriter			Attribute(const WString& name);
			protected:
				Ptr<ParsingDefinitionAttribute>					attribute;

				ParsingDefinitionAttributeWriter(const WString& name);
			public:
				ParsingDefinitionAttributeWriter(const ParsingDefinitionAttributeWriter& attributeWriter);

				ParsingDefinitionAttributeWriter&				Argument(const WString& argument);
				Ptr<ParsingDefinitionAttribute>					Attribute()const;
			};

			extern ParsingDefinitionAttributeWriter				Attribute(const WString& name);

/***********************************************************************
Type Writer
***********************************************************************/

			class ParsingDefinitionTypeWriter : public Object
			{
				friend ParsingDefinitionTypeWriter				Type(const WString& name);
				friend ParsingDefinitionTypeWriter				TokenType();
			protected:
				Ptr<ParsingDefinitionType>						type;

				ParsingDefinitionTypeWriter(Ptr<ParsingDefinitionType> internalType);
				ParsingDefinitionTypeWriter(const WString& name);
			public:
				ParsingDefinitionTypeWriter(const ParsingDefinitionTypeWriter& typeWriter);

				ParsingDefinitionTypeWriter						Sub(const WString& subTypeName)const;
				ParsingDefinitionTypeWriter						Array()const;
				Ptr<ParsingDefinitionType>						Type()const;
			};

			extern ParsingDefinitionTypeWriter					Type(const WString& name);
			extern ParsingDefinitionTypeWriter					TokenType();

/***********************************************************************
Type Definition Writer
***********************************************************************/

			class ParsingDefinitionTypeDefinitionWriter : public Object
			{
			public:
				virtual Ptr<ParsingDefinitionTypeDefinition>	Definition()const=0;
			};

			class ParsingDefinitionClassDefinitionWriter : public ParsingDefinitionTypeDefinitionWriter
			{
			protected:
				Ptr<ParsingDefinitionBase>						currentDefinition;
				Ptr<ParsingDefinitionClassDefinition>			definition;

			public:
				ParsingDefinitionClassDefinitionWriter(const WString& name);
				ParsingDefinitionClassDefinitionWriter(const WString& name, const ParsingDefinitionTypeWriter& parentType);

				ParsingDefinitionClassDefinitionWriter&			AmbiguousType(const ParsingDefinitionTypeWriter& ambiguousType);
				ParsingDefinitionClassDefinitionWriter&			Member(const WString& name, const ParsingDefinitionTypeWriter& type, const WString& unescapingFunction=L"");
				ParsingDefinitionClassDefinitionWriter&			SubType(const ParsingDefinitionTypeDefinitionWriter& type);
				ParsingDefinitionClassDefinitionWriter&			Attribute(const ParsingDefinitionAttributeWriter& attribute);

				Ptr<ParsingDefinitionTypeDefinition>			Definition()const override;
			};
			
			extern ParsingDefinitionClassDefinitionWriter		Class(const WString& name);
			extern ParsingDefinitionClassDefinitionWriter		Class(const WString& name, const ParsingDefinitionTypeWriter& parentType);

			class ParsingDefinitionEnumDefinitionWriter : public ParsingDefinitionTypeDefinitionWriter
			{
			protected:
				Ptr<ParsingDefinitionBase>						currentDefinition;
				Ptr<ParsingDefinitionEnumDefinition>			definition;

			public:
				ParsingDefinitionEnumDefinitionWriter(const WString& name);

				ParsingDefinitionEnumDefinitionWriter&			Member(const WString& name);
				ParsingDefinitionEnumDefinitionWriter&			Attribute(const ParsingDefinitionAttributeWriter& attribute);

				Ptr<ParsingDefinitionTypeDefinition>			Definition()const override;
			};

			extern ParsingDefinitionEnumDefinitionWriter		Enum(const WString& name);

/***********************************************************************
Grammar Writer
***********************************************************************/

			class ParsingDefinitionGrammarWriter : public Object
			{
				friend ParsingDefinitionGrammarWriter			Rule(const WString& name);
				friend ParsingDefinitionGrammarWriter			Text(const WString& name);
				friend ParsingDefinitionGrammarWriter			Opt(const ParsingDefinitionGrammarWriter& writer);
			protected:
				Ptr<ParsingDefinitionGrammar>					grammar;

				ParsingDefinitionGrammarWriter(Ptr<ParsingDefinitionGrammar> internalGrammar);
			public:
				ParsingDefinitionGrammarWriter(const ParsingDefinitionGrammarWriter& grammarWriter);

				ParsingDefinitionGrammarWriter					operator+(const ParsingDefinitionGrammarWriter& next)const;
				ParsingDefinitionGrammarWriter					operator|(const ParsingDefinitionGrammarWriter& next)const;
				ParsingDefinitionGrammarWriter					operator*()const;
				ParsingDefinitionGrammarWriter					As(const ParsingDefinitionTypeWriter& type)const;
				ParsingDefinitionGrammarWriter					operator[](const WString& memberName)const;
				ParsingDefinitionGrammarWriter					operator!()const;
				ParsingDefinitionGrammarWriter					Set(const WString& memberName, const WString& value)const;

				Ptr<ParsingDefinitionGrammar>					Grammar()const;
			};

			extern ParsingDefinitionGrammarWriter				Rule(const WString& name);
			extern ParsingDefinitionGrammarWriter				Text(const WString& text);
			extern ParsingDefinitionGrammarWriter				Opt(const ParsingDefinitionGrammarWriter& writer);

/***********************************************************************
Token and Rule Writer
***********************************************************************/

			class ParsingDefinitionWriter;

			class ParsingDefinitionTokenDefinitionWriter : public Object
			{
			protected:
				Ptr<ParsingDefinitionTokenDefinition>			token;
				ParsingDefinitionWriter&						owner;
			public:
				ParsingDefinitionTokenDefinitionWriter(ParsingDefinitionWriter& _owner, Ptr<ParsingDefinitionTokenDefinition> _token);

				ParsingDefinitionTokenDefinitionWriter&			Attribute(const ParsingDefinitionAttributeWriter& attribute);
				ParsingDefinitionWriter&						EndToken();
			};

			class ParsingDefinitionRuleDefinitionWriter : public Object
			{
			protected:
				Ptr<ParsingDefinitionRuleDefinition>			rule;
				ParsingDefinitionWriter&						owner;
			public:
				ParsingDefinitionRuleDefinitionWriter(ParsingDefinitionWriter& _owner, Ptr<ParsingDefinitionRuleDefinition> _rule);

				ParsingDefinitionRuleDefinitionWriter&			Imply(const ParsingDefinitionGrammarWriter& grammar);
				ParsingDefinitionRuleDefinitionWriter&			Attribute(const ParsingDefinitionAttributeWriter& attribute);
				ParsingDefinitionWriter&						EndRule();
			};

			class ParsingDefinitionWriter : public Object
			{
			protected:
				Ptr<ParsingDefinition>							definition;

			public:
				ParsingDefinitionWriter();

				ParsingDefinitionWriter&						Type(const ParsingDefinitionTypeDefinitionWriter& type);
				ParsingDefinitionWriter&						Token(const WString& name, const WString& regex);
				ParsingDefinitionTokenDefinitionWriter			TokenAtt(const WString& name, const WString& regex);
				ParsingDefinitionWriter&						Discard(const WString& name, const WString& regex);
				ParsingDefinitionRuleDefinitionWriter			Rule(const WString& name, const ParsingDefinitionTypeWriter& type);

				Ptr<ParsingDefinition>							Definition()const;
			};

/***********************************************************************
Helper Functions
***********************************************************************/

			extern WString										TypeToString(ParsingDefinitionType* type);
			extern WString										GrammarToString(ParsingDefinitionGrammar* grammar);
			extern WString										GrammarStateToString(ParsingDefinitionGrammar* grammar, ParsingDefinitionGrammar* stateNode, bool beforeNode);
			extern ParsingDefinitionGrammar*					FindAppropriateGrammarState(ParsingDefinitionGrammar* grammar, ParsingDefinitionGrammar* stateNode, bool beforeNode);
			extern void											Log(Ptr<ParsingDefinition> definition, stream::TextWriter& writer);
			extern WString										DeserializeString(const WString& value);
			extern WString										SerializeString(const WString& value);

/***********************************************************************
Bootstrap
***********************************************************************/
			
			extern Ptr<ParsingDefinition>						CreateParserDefinition();
			extern Ptr<ParsingDefinition>						DeserializeDefinition(Ptr<ParsingTreeNode> node);
		}
	}
}

#endif

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

#ifndef VCZH_PARSING_PARSINGANALYZER
#define VCZH_PARSING_PARSINGANALYZER


namespace vl
{
	namespace parsing
	{
		namespace analyzing
		{

/***********************************************************************
DefinitionTypeScopePair
***********************************************************************/

			class ParsingSymbol;
			class ParsingSymbolManager;

			struct DefinitionTypeScopePair
			{
				definitions::ParsingDefinitionType*		type;
				ParsingSymbol*							scope;

				DefinitionTypeScopePair()
				{
				}

				DefinitionTypeScopePair(definitions::ParsingDefinitionType* _type, ParsingSymbol* _scope)
					:type(_type)
					,scope(_scope)
				{
				}

				std::strong_ordering operator<=>(const DefinitionTypeScopePair& pair)const
				{
					std::strong_ordering
					result = type <=> pair.type; if (result != 0) return result;
					result = scope <=> pair.scope; if (result != 0) return result;
					return result;
				}

				bool operator==(const DefinitionTypeScopePair& pair)const
				{
					return (*this <=> pair) == 0;
				}
			};

/***********************************************************************
ParsingSymbol Management
***********************************************************************/

			class ParsingSymbol : public Object
			{
				friend class ParsingSymbolManager;

				typedef collections::Dictionary<WString, ParsingSymbol*>		ParsingSymbolMap;
				typedef collections::List<ParsingSymbol*>						ParsingSymbolList;
			public:
				enum SymbolType
				{
					Global,
					EnumType,
					ClassType,		// descriptor == base type
					ArrayType,		// descriptor == element type
					TokenType,
					EnumItem,		// descriptor == parent
					ClassField,		// descriptor == field type
					TokenDef,		// descriptor == token type
					RuleDef,		// descriptor == rule type
				};

			protected:
				ParsingSymbolManager*			manager;
				SymbolType						type;
				WString							name;
				ParsingSymbol*					descriptorSymbol;
				WString							descriptorString;
				ParsingSymbol*					parentSymbol;
				ParsingSymbol*					arrayTypeSymbol;
				ParsingSymbolList				subSymbolList;
				ParsingSymbolMap				subSymbolMap;

				bool							AddSubSymbol(ParsingSymbol* subSymbol);

				ParsingSymbol(ParsingSymbolManager* _manager, SymbolType _type, const WString& _name, ParsingSymbol* _descriptorSymbol, const WString& _descriptorString);
			public:
				~ParsingSymbol();

				ParsingSymbolManager*			GetManager();
				SymbolType						GetType();
				const WString&					GetName();
				vint							GetSubSymbolCount();
				ParsingSymbol*					GetSubSymbol(vint index);
				ParsingSymbol*					GetSubSymbolByName(const WString& name);
				ParsingSymbol*					GetDescriptorSymbol();
				WString							GetDescriptorString();
				ParsingSymbol*					GetParentSymbol();
				bool							IsType();
				ParsingSymbol*					SearchClassSubSymbol(const WString& name);
				ParsingSymbol*					SearchCommonBaseClass(ParsingSymbol* classType);
			};

			class ParsingSymbolManager : public Object
			{
				typedef definitions::ParsingDefinitionClassDefinition												ClassDefinition;
				typedef collections::List<Ptr<ParsingSymbol>>														ParsingSymbolList;
				typedef collections::Dictionary<DefinitionTypeScopePair, ParsingSymbol*>							DefinitionTypeSymbolMap;
				typedef collections::Dictionary<definitions::ParsingDefinitionGrammar*, ParsingSymbol*>				DefinitionGrammarSymbolMap;
				typedef collections::Dictionary<ParsingSymbol*, ClassDefinition*>									SymbolClassDefinitionMap;
				typedef collections::Dictionary<ClassDefinition*, ParsingSymbol*>									ClassDefinitionSymbolMap;
			protected:
				ParsingSymbol*					globalSymbol;
				ParsingSymbol*					tokenTypeSymbol;
				ParsingSymbolList				createdSymbols;
				DefinitionTypeSymbolMap			definitionTypeSymbolCache;
				DefinitionGrammarSymbolMap		definitionGrammarSymbolCache;
				DefinitionGrammarSymbolMap		definitionGrammarTypeCache;
				SymbolClassDefinitionMap		symbolClassDefinitionCache;
				ClassDefinitionSymbolMap		classDefinitionSymbolCache;

				bool							TryAddSubSymbol(Ptr<ParsingSymbol> subSymbol, ParsingSymbol* parentSymbol);
			public:
				ParsingSymbolManager();
				~ParsingSymbolManager();

				ParsingSymbol*					GetGlobal();
				ParsingSymbol*					GetTokenType();
				ParsingSymbol*					GetArrayType(ParsingSymbol* elementType);

				ParsingSymbol*					AddClass(definitions::ParsingDefinitionClassDefinition* classDef, ParsingSymbol* baseType, ParsingSymbol* parentType=0);
				ParsingSymbol*					AddField(const WString& name, ParsingSymbol* classType, ParsingSymbol* fieldType);
				ParsingSymbol*					AddEnum(const WString& name, ParsingSymbol* parentType=0);
				ParsingSymbol*					AddEnumItem(const WString& name, ParsingSymbol* enumType);
				ParsingSymbol*					AddTokenDefinition(const WString& name, const WString& regex);
				ParsingSymbol*					AddRuleDefinition(const WString& name, ParsingSymbol* ruleType);

				ClassDefinition*				CacheGetClassDefinition(ParsingSymbol* type);
				ParsingSymbol*					CacheGetClassType(ClassDefinition* type);
				ParsingSymbol*					CacheGetType(definitions::ParsingDefinitionType* type, ParsingSymbol* scope);
				bool							CacheSetType(definitions::ParsingDefinitionType* type, ParsingSymbol* scope, ParsingSymbol* symbol);
				ParsingSymbol*					CacheGetSymbol(definitions::ParsingDefinitionGrammar* grammar);
				bool							CacheSetSymbol(definitions::ParsingDefinitionGrammar* grammar, ParsingSymbol* symbol);
				ParsingSymbol*					CacheGetType(definitions::ParsingDefinitionGrammar* grammar);
				bool							CacheSetType(definitions::ParsingDefinitionGrammar* grammar, ParsingSymbol* type);
			};

/***********************************************************************
Semantic Analyzer
***********************************************************************/

			extern WString						GetTypeFullName(ParsingSymbol* type);
			extern ParsingSymbol*				FindType(definitions::ParsingDefinitionType* type, ParsingSymbolManager* manager, ParsingSymbol* scope, collections::List<Ptr<ParsingError>>& errors);
			extern void							PrepareSymbols(Ptr<definitions::ParsingDefinition> definition, ParsingSymbolManager* manager, collections::List<Ptr<ParsingError>>& errors);
			extern void							ValidateRuleStructure(Ptr<definitions::ParsingDefinition> definition, Ptr<definitions::ParsingDefinitionRuleDefinition> rule, ParsingSymbolManager* manager, collections::List<Ptr<ParsingError>>& errors);
			extern void							ResolveRuleSymbols(Ptr<definitions::ParsingDefinitionRuleDefinition> rule, ParsingSymbolManager* manager, collections::List<Ptr<ParsingError>>& errors);
			extern void							ResolveSymbols(Ptr<definitions::ParsingDefinition> definition, ParsingSymbolManager* manager, collections::List<Ptr<ParsingError>>& errors);
			extern void							ValidateDefinition(Ptr<definitions::ParsingDefinition> definition, ParsingSymbolManager* manager, collections::List<Ptr<ParsingError>>& errors);
		}
	}
}

#endif


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

#ifndef VCZH_PARSING_PARSINGTABLE
#define VCZH_PARSING_PARSINGTABLE


namespace vl
{
	namespace parsing
	{
		namespace tabling
		{

/***********************************************************************
Parsing Table
***********************************************************************/

			/// <summary>
			/// <p>
			/// The parsing table. When you complete a grammar file, use ParserGen.exe to generate the C++ code for you to create a parsing table.
			/// </p>
			/// <p>
			/// Here is a brief description of the grammar file format:
			/// </p>
			/// <p>
			/// The grammar file consists of four parts: configuration, types, tokens and grammar in order like this:
			/// <program><code><![CDATA[
			/// CONFIGURATION
			/// grammar:
			/// TYPES
			/// TOKENS
			/// GRAMMAR
			/// ]]></code></program>
			/// </p>
			/// <p>
			/// <b>Configuration</b>
			/// <ul>
			/// <li>
			/// <b>include:"releative path to the VlppParser.h"</b>:
			/// (multiple) e.g. "../Import/Vlpp.h"
			/// </li>
			/// <li>
			/// <b>namespace:C++-NAMESPACE</b>:
			/// (single) Namespaces separated by "." to contain the generated code. e.g. vl.parsing.xml
			/// </li>
			/// <li>
			/// <b>reflection:REFLECTION-NAMESPACE</b>:
			/// (single) Namespaces separated by "." to contain the name of reflectable types. In most of the cases this should be the same as namespace. e.g. vl.parsing.xml
			/// </li>
			/// <li>
			/// <b>filePrefix:FILE-PREFIX</b>:
			/// (single) A prefix that will be add before all generated files. e.g. ParsingXml
			/// </li>
			/// <li>
			/// <b>classPrefix:CLASS-PREFIX</b>:
			/// (single) A prefix that will be add before all generated types and function. e.g. Xml
			/// </li>
			/// <li>
			/// <b>classRoot:CLASS-ROOT</b>:
			/// (single) The class that represents the whole text being parsed.
			/// </li>
			/// <li>
			/// <b>guard:C++-HEADER-GUARD</b>:
			/// (single) The C++ header guard pattern macro name. e.g. VCZH_PARSING_XML_PARSINGXML_PARSER
			/// </li>
			/// <li>
			/// <b>parser:NAME(RULE)</b>:
			/// (multiple) Pair a function name to a rule name.
			/// It will generate a function called "XmlParseDocument" to parse the input using the rule named "XDocument",
			/// if you have "classPrefix:Xml" and "parser:ParseDocument(XDocument)".</li>
			/// <li>
			/// <b>file:FEATURE(POSTFIX)</b>:
			/// (multiple) Generate code for a specified feature to "&lt;FILE-PREFIX&gt;&lt;POSTFIX&gt;.h" and "&lt;FILE-PREFIX&gt;&lt;POSTFIX&gt;.cpp".
			/// FEATURE could be Ast, Parser, Copy, Traverse and Empty.
			/// Ast is the definition of all classes in the grammar file.
			/// Parser is the implementation of all parsers.
			/// Others are visitors for Ast with different traversing features.
			/// </li>
			/// <li>
			/// <b>ambiguity:(enabled|disabled)</b>:
			/// (single) Set to "enabled" indicating that the grammar is by design to have ambiguity.
			/// If ambiguity happens during parser, but here is "disabled", then an error will be generated.
			/// </li>
			/// <li>
			/// <b>serialization:(enabled|disabled)</b>:
			/// (single) Set to "enabled" to serialize the parsing table as binary in the generated C++ code,
			/// so that when the "&lt;CLASS-PREFIX&gt;LoadTable" function is called to load the table,
			/// it can deserialize from the binary data directly,
			/// instead of parsing the grammar again.
			/// But the grammar text will always be in the generated C++ code regardless of the value of "serialization",
			/// it can always be retrived using the "&lt;CLASS-PREFIX&gt;GetParserTextBuffer" function.
			/// </li>
			/// </ul>
			/// </p>
			/// <p>
			/// <b>Character escaping in strings</b>
			/// </p>
			/// <p>
			/// There is only character escaping in strings: "", which means the " character.
			/// For example, "a""b""c" means R"TEXT(a"b"c)TEXT" in C++.
			/// </p>
			/// <p>
			/// <b>Types</b>
			/// </p>
			/// <p>
			/// You can write attributes like @AttributeName("argument1", "argument2", ...) in the middle of types.
			/// But attributes don't affect parsing.
			/// All attribute definitions will be stored in the generated parsing table,
			/// and who uses the table defines how attributes work. Multiple attributes are separated by ",".
			/// </p>
			/// <p>
			/// If you only need parsing, usually you don't need to use attributes.
			/// GacUI will use some attributes to drive colorizer and intellisense.
			/// This part is subject to change in the next version, so it will not be described here.
			/// </p>
			/// <p>
			/// <ul>
			///     <li>
			///         <b>Enum</b>:
			///         <program><code><![CDATA[
			///             enum EnumName <attributes>
			///             {
			///                 Item1 <attributes>,
			///                 Item2 <attributes>,
			///                 ... // cannot skip the last ","
			///             }
			///         ]]></code></program>
			///     </li>
			///     <li>
			///         <p>
			///         <b>Class</b>:
			///         <program><code><![CDATA[
			///             class Name [ambiguous(AmbiguousType)] [: ParentType] <attributes>
			///             {
			///                 Type name [(UnescapingFunction)] <attributes> ;
			///             }
			///         ]]></code></program>
			///         </p>
			///         <p>
			///         UnescapingFunction is a callback,
			///         which will be called after the contained type is fully constructed.
			///         The generated C++ code will define forward declarations of all unescaping functions in the cpp file.
			///         You should implement them in other places, or you will get linking errors.
			///         </p>
			///         <p>
			///         If the grammar enables ambiguity, then the parsing result may contain ambiguous results for the same part of the input. For example, in C++:
			///         <program><code><![CDATA[
			///         A*B;
			///         ]]></code></program>
			///         has two meanings without considering the surrounding context: a multiplication expression or a pointer variable definition.
			///         </p>
			///         <p>
			///         If the grammar doesn't enable ambiguity, it will refuce to generate C++ codes because the grammar is wrong.
			///         Note that it doesn't generate errors for every possible cases of ambiguity.
			///         Do not rely on this to check ambiguity in the grammar.
			///         </p>
			///         <p>
			///         If the grammar enables ambiguity, than the syntax tree should be defined like this:
			///         <program><code><![CDATA[
			///             // when ambiguity happens for Statement, AmbiguiusStatement will be used to container all possible cases
			///             class Statement ambiguous(AmbiguousStatement)
			///             {
			///             }
			///
			///             // so that "AmbiguousStatement" should inherit from "Statement"
			///             class AmbiguousStatement : Statement
			///             {
			///                 // it should called "items", and the type should be an array of the base type
			///                 Statement[] items;
			///             }
			///
			///             class ExpressionStatement : Statement
			///             {
			///                 Expression expression;
			///             }
			///
			///             class VariableDefinitionStatement : Statement
			///             {
			///                 Type type;
			///                 token name;
			///             }
			///         ]]></code></program>
			///         For "A*B;" part in the whole input, it becomes an AmbiguousStatement.
			///         The "items" field contains two instances, which are "ExpressionStatement" and "VariableDefinitionStatement".
			///         You could write C++ code to resolve the ambiguity in later passes.
			///         </p>
			///     </li>
			///     <li>
			///         <p><b>Type references</b>:</p>
			///         <p>
			///         Types can be defined globally or inside classes. Generic type is not supported. You can use the following types for a class field:
			///         <ul>
			///             <li><b>token</b>: Store a token, which will becomes [T:vl.parsing.ParsingToken].</li>
			///             <li><b>ClassName</b>: Instance of a specified type, which will becomes Ptr&lt;ClassName&gt;.</li>
			///             <li>
			///                 <p><b>ClassName[]</b>: Array, which will becomes List&lt;Ptr&lt;ClassName&gt;&gt;. Array of tokens are not supported.</p>
			///                 <p>A class name could also be<b>OuterClass.InnerClass</b>, referring to the "InnerClass" defined inside the "OuterClass".</p>
			///             </li>
			///         </ul>
			///         </p>
			///     </li>
			/// </ul>
			/// </p>
			/// <p>
			/// <b>Token definitions</b>
			/// <program><code><![CDATA[
			///     token TokenName = "regular expression" <attributes>;
			///     discardtoken TokenName = "regular expression";
			/// ]]></code></program>
			/// "discardtoken" means that,
			/// if such a token is identified,
			/// it will not appear in the lexical analyzing result.
			/// You cannot use tokens marked with "discardtoken" in the grammar.
			/// </p>
			/// <p>
			/// <b>Grammar</b>
			/// <program><code><![CDATA[
			///     rule RuleType RuleName <attributes>
			///         = Grammar1
			///         = Grammar2
			///         ...
			///         ;
			/// ]]></code></program>
			/// It means rule "RuleName" is defined by those grammars,
			/// and matching this rule will create an instance of "RuleType" or one of its sub classes.
			/// </p>
			/// <p>
			/// Here are all supported grammars that:
			/// <ul>
			///     <li><b>RuleName</b>: Defines an input that matches a rule.</li>
			///     <li><b>TokenName</b>: Defines an input that formed by the specified token.</li>
			///     <li><b>"StringConstant"</b>: Defines an input that formed by exactly the string constant. There should be exactly one token who can only be this string constant.</li>
			///     <li><b>Grammar: FieldName</b>: Defines an input that matches Grammar (should be either a rule name or a token name), and the result will be stored in field "FieldName" of the created object.</li>
			///     <li><b>!Grammar</b>: Defines an input that matches Grammar, and the rule will use the created object from this grammar. The input should still match other part of the rule, but result of other parts are ignored.</li>
			///     <li><b>[Grammar]</b>: Defines an input that, if it matches Grammar, it returns the result from that grammar; otherwise, it returns null.</li>
			///     <li><b>{Grammar}</b>: Defines an input that matches 0, 1 or more Grammar.</li>
			///     <li><b>(Grammar)</b>: Defines an input that matches the the grammar. Brackets is only for changing operator associations.</li>
			///     <li><b>Grammar1 Grammar2</b>: Defines an input that should match Grammar1 followed by Grammar2.</li>
			///     <li><b>Grammar1 | Grammar2</b>: Defines an input that match either Grammar1 or Grammar2. When it matches Grammar1, Grammar2 will be ignored.</li>
			///     <li><b>Grammar as Type</b>: Defines an input that matches the Grammar, and the whole branch of the rule creates an instance of type "Type".</li>
			///     <li><b>Grammar with { FieldName = Value }</b>: Defines an input that matches the Grammar, assign "Value" to the field "FieldName" of the created object.</li>
			/// </ul>
			/// A grammar branch must be "GRAMMAR as TYPE with {Field1 = Value1} with {Field2 = Value2} ...".
			/// </p>
			/// <p>
			/// <b>Example</b>
			/// </p>
			/// <p>
			/// Here is an example to parse expression containing +, -, *, /, () and numbers:
			/// <program><code><![CDATA[
			///     include:"Vlpp.h"
			///     namespace:vl.calculator
			///     reflection:vl.calculator
			///     filePrefix:Calc
			///     classPrefix:Calc
			///     classRoot:Expression
			///     guard:VCZH_CALCULATOR_PARSER
			///     parser:ParseExpression(Expr)
			///     file:Ast(_Ast)
			///     file:Parser(_Parser)
			///     ambiguity:disabled
			///     serialization:enabled
			///     grammar:
			///
			///     class Expression
			///     {
			///     }
			///
			///     enum BinaryOperator
			///     {
			///         Add, Sub, Mul, Div,
			///     }
			///
			///     class NumberExpression : Expression
			///     {
			///         token number;
			///     }
			///
			///     class BinaryExpression : Expression
			///     {
			///         BinaryOperator op;
			///         Expression left;
			///         Expression right;
			///     }
			///
			///     token ADD "\+"
			///     token SUB "-"
			///     token MUL "\*"
			///     token DIV "\/"
			///     token NUMBER "\d+(.\d+)?"
			///     token OPEN "("
			///     token CLOSE ")"
			///     discardtoken SPACE = "/s+";
			///     
			///     rule Expression Factor
			///         = NUMBER : number as NumberExpression
			///         = "(" !Expr ")"
			///         ;
			///     rule Expression Term
			///         = !Factor
			///         = Term : left "*" Factor : right as BinaryExpression with {op = "Mul"}
			///         = Term : left "/" Factor : right as BinaryExpression with {op = "Div"}
			///         ;
			///     rule Expression Expr
			///         = !Term
			///         = Expr : left "+" Term : right as BinaryExpression with {op = "Add"}
			///         = Expr : left "-" Term : right as BinaryExpression with {op = "Sub"}
			///         ;
			/// ]]></code></program>
			/// </p>
			/// <p>
			/// After using ParserGen.exe to generate C++ codes, you can do this:
			/// <program><code><![CDATA[
			///     // this table can be used, please cache the result to improve the performance
			///     auto table = CalcLoadTable();
			///     List<Ptr<ParsingError>> errors;
			///     // it should be a Ptr<CalcExpression>, will returns nullptr if the input contains syntax errors
			///     auto expression = CalcParseExpression(L"(1+2) * (3+4)", table, errors);
			/// ]]></code></program>
			/// You don't need to define the "errors" if you don't actually care how the input is wrong.
			/// There will be a overloaded version of CalcParseExpression that doesn't need the third argument.
			/// </p>
			/// <p>
			/// You can also automatically correct wrong input.
			/// Ifthe input is not too wrong to recognize,
			/// you can still get a syntax tree,
			/// but some fields are nullptr,
			/// with errors filled into the "error" variable.
			/// <program><code><![CDATA[
			///     auto table = CalcLoadTable();                   // Load the table.
			///     ParsingState state(L"(1+2) * (3+4)", table);    // Initialize a state with the input and the table.
			///     state.Reset(L"Expr");                           // Set the rule to parse.
			///     auto parser = CreateAutoRecoverParser(table);   // Create an appropriate automatic error recoverable parser.
			///     List<Ptr<ParsingError>> errors;                 // Define an error list.
			///     auto node = parser->Parse(state, errors);       // Parse to get an abstract syntax tree, which is a Ptr<ParsingTreeNode>.
			///     if (node)
			///     {
			///         auto expression = CalcConvertParsingTreeNode(node, state.GetTokens()).Cast<CalcExpression>();
			///     }
			/// ]]></code></program>
			/// </p>
			/// <p>
			/// After you get a strong typed syntax tree, you can use the generated visitor interface to do something, like evaluate the results of the expression:
			/// <program><code><![CDATA[
			///     class Evaluator : public Object, public virtual CalcExpression::IVisitor
			///     {
			///     private:
			///         double result;
			///
			///         double Call(CalcExpression* node)
			///         {
			///             node->Accept(this);
			///             return result;
			///         }
			///
			///     public:
			///         static double Evaluate(CalcExpression* node)
			///         {
			///             return Evaluator().Call(node);
			///         }
			///
			///         void Visit(CalcNumberExpression* node)override
			///         {
			///             return wtof(node->number.value);
			///         }
			///
			///         void Visit(CalcBinaryExpression* node)override
			///         {
			///             auto left = Calc(node->left.Obj());
			///             auto right = Calc(node->right.Obj());
			///             switch (node->op)
			///             {
			///             case CalcBinaryOperator::Add:
			///                 result = left + right;
			///                 break;
			///             case CalcBinaryOperator::Sub:
			///                 result = left 0 right;
			///                 break;
			///             case CalcBinaryOperator::Mul:
			///                 result = left * right;
			///                 break;
			///             case CalcBinaryOperator::Div:
			///                 result = left / right;
			///                 break;
			///             }
			///         }
			///     };
			///
			///     Nullable<double> EvaluateExpression(const WString& input)
			///     {
			///         static auto table = CalcLoadTable();
			///         auto expression = CalcParseExpression(input, table);
			///         Nulllable<double> result;
			///         if (expression)
			///         {
			///             result = Evaluator::Evaulate(expression.Obj());
			///         }
			///         return result;
			///     }
			/// ]]></code></program>
			/// </p>
			/// </summary>
			class ParsingTable : public Object
			{
			public:
				static const vint							TokenBegin=0;
				static const vint							TokenFinish=1;
				static const vint							NormalReduce=2;
				static const vint							LeftRecursiveReduce=3;
				static const vint							UserTokenStart=4;

				class AttributeInfo : public Object
				{
				public:
					WString									name;
					collections::List<WString>				arguments;

					AttributeInfo(const WString& _name = L"")
						:name(_name)
					{
					}

					AttributeInfo* Argument(const WString& argument)
					{
						arguments.Add(argument);
						return this;
					}
				};

				class AttributeInfoList : public Object
				{
				public:
					collections::List<Ptr<AttributeInfo>>	attributes;

					Ptr<AttributeInfo> FindFirst(const WString& name);
				};

				class TreeTypeInfo
				{
				public:
					WString									type;
					vint									attributeIndex;

					TreeTypeInfo()
						:attributeIndex(-1)
					{
					}

					TreeTypeInfo(const WString& _type, vint _attributeIndex)
						:type(_type)
						,attributeIndex(_attributeIndex)
					{
					}
				};

				class TreeFieldInfo
				{
				public:
					WString									type;
					WString									field;
					vint									attributeIndex;

					TreeFieldInfo()
						:attributeIndex(-1)
					{
					}

					TreeFieldInfo(const WString& _type, const WString& _field, vint _attributeIndex)
						:type(_type)
						,field(_field)
						,attributeIndex(_attributeIndex)
					{
					}
				};

				class TokenInfo
				{
				public:
					WString									name;
					WString									regex;
					vint									regexTokenIndex;
					vint									attributeIndex;

					TokenInfo()
						:regexTokenIndex(-1)
						,attributeIndex(-1)
					{
					}

					TokenInfo(const WString& _name, const WString& _regex, vint _attributeIndex)
						:name(_name)
						,regex(_regex)
						,regexTokenIndex(-1)
						,attributeIndex(_attributeIndex)
					{
					}
				};

				class StateInfo
				{
				public:
					WString									ruleName;
					WString									stateName;
					WString									stateExpression;

					WString									ruleAmbiguousType;		// filled in Initialize()

					StateInfo()
					{
					}

					StateInfo(const WString& _ruleName, const WString& _stateName, const WString& _stateExpression)
						:ruleName(_ruleName)
						,stateName(_stateName)
						,stateExpression(_stateExpression)
					{
					}
				};

				class RuleInfo
				{
				public:
					WString									name;
					WString									type;
					WString									ambiguousType;
					vint									rootStartState;
					vint									attributeIndex;

					RuleInfo()
						:rootStartState(-1)
						,attributeIndex(-1)
					{
					}

					RuleInfo(const WString& _name, const WString& _type, const WString& _ambiguousType, vint _rootStartState, vint _attributeIndex)
						:name(_name)
						,type(_type)
						,ambiguousType(_ambiguousType)
						,rootStartState(_rootStartState)
						,attributeIndex(_attributeIndex)
					{
					}
				};

				class Instruction
				{
				public:
					enum InstructionType
					{
						Create,
						Assign,
						Item,
						Using,
						Setter,
						Shift,
						Reduce,
						LeftRecursiveReduce,
					};

					InstructionType							instructionType;
					vint									stateParameter;
					WString									nameParameter;
					WString									value;
					WString									creatorRule;

					Instruction()
						:instructionType(Create)
						,stateParameter(0)
					{
					}

					Instruction(InstructionType _instructionType, vint _stateParameter, const WString& _nameParameter, const WString& _value, const WString& _creatorRule)
						:instructionType(_instructionType)
						,stateParameter(_stateParameter)
						,nameParameter(_nameParameter)
						,value(_value)
						,creatorRule(_creatorRule)
					{
					}
				};

				class LookAheadInfo
				{
				public:
					collections::List<vint>					tokens;
					vint									state;

					LookAheadInfo()
						:state(-1)
					{
					}

					enum PrefixResult
					{
						Prefix,
						Equal,
						NotPrefix,
					};

					static PrefixResult						TestPrefix(Ptr<LookAheadInfo> a, Ptr<LookAheadInfo> b);
					static void								WalkInternal(Ptr<ParsingTable> table, Ptr<LookAheadInfo> previous, vint state, collections::SortedList<vint>& walkedStates, collections::List<Ptr<LookAheadInfo>>& newInfos);
					static void								Walk(Ptr<ParsingTable> table, Ptr<LookAheadInfo> previous, vint state, collections::List<Ptr<LookAheadInfo>>& newInfos);
				};

				class TransitionItem
				{
				public:
					vint									token;
					vint									targetState;
					collections::List<Ptr<LookAheadInfo>>	lookAheads;
					collections::List<vint>					stackPattern;
					collections::List<Instruction>			instructions;

					enum OrderResult
					{
						CorrectOrder,
						WrongOrder,
						SameOrder,
						UnknownOrder,
					};

					TransitionItem(){}

					TransitionItem(vint _token, vint _targetState)
						:token(_token)
						,targetState(_targetState)
					{
					}

					static OrderResult						CheckOrder(Ptr<TransitionItem> t1, Ptr<TransitionItem> t2, OrderResult defaultResult = UnknownOrder);
					static vint								Compare(Ptr<TransitionItem> t1, Ptr<TransitionItem> t2, OrderResult defaultResult);
				};

				class TransitionBag
				{
				public:
					collections::List<Ptr<TransitionItem>>	transitionItems;
				};

			protected:
				// metadata
				bool																ambiguity;
				collections::Array<Ptr<AttributeInfoList>>							attributeInfos;
				collections::Array<TreeTypeInfo>									treeTypeInfos;
				collections::Array<TreeFieldInfo>									treeFieldInfos;

				// LALR table
				vint																tokenCount;			// tokenInfos.Count() + discardTokenInfos.Count()
				vint																stateCount;			// stateInfos.Count()
				collections::Array<TokenInfo>										tokenInfos;
				collections::Array<TokenInfo>										discardTokenInfos;
				collections::Array<StateInfo>										stateInfos;
				collections::Array<RuleInfo>										ruleInfos;
				collections::Array<Ptr<TransitionBag>>								transitionBags;

				// generated data
				Ptr<regex::RegexLexer>												lexer;
				collections::Dictionary<WString, vint>								ruleMap;
				collections::Dictionary<WString, vint>								treeTypeInfoMap;
				collections::Dictionary<collections::Pair<WString, WString>, vint>	treeFieldInfoMap;

				template<typename TIO>
				void IO(TIO& io);

			public:
				ParsingTable(vint _attributeInfoCount, vint _treeTypeInfoCount, vint _treeFieldInfoCount, vint _tokenCount, vint _discardTokenCount, vint _stateCount, vint _ruleCount);
				/// <summary>Deserialize the parsing table from a stream. <see cref="Initialize"/> should be before using this table.</summary>
				/// <param name="input">The stream.</param>
				ParsingTable(stream::IStream& input);
				~ParsingTable();

				/// <summary>Serialize the parsing table to a stream.</summary>
				/// <param name="output">The stream.</param>
				void										Serialize(stream::IStream& output);

				bool										GetAmbiguity();
				void										SetAmbiguity(bool value);

				vint										GetAttributeInfoCount();
				Ptr<AttributeInfoList>						GetAttributeInfo(vint index);
				void										SetAttributeInfo(vint index, Ptr<AttributeInfoList> info);

				vint										GetTreeTypeInfoCount();
				const TreeTypeInfo&							GetTreeTypeInfo(vint index);
				const TreeTypeInfo&							GetTreeTypeInfo(const WString& type);
				void										SetTreeTypeInfo(vint index, const TreeTypeInfo& info);

				vint										GetTreeFieldInfoCount();
				const TreeFieldInfo&						GetTreeFieldInfo(vint index);
				const TreeFieldInfo&						GetTreeFieldInfo(const WString& type, const WString& field);
				void										SetTreeFieldInfo(vint index, const TreeFieldInfo& info);

				vint										GetTokenCount();
				const TokenInfo&							GetTokenInfo(vint token);
				void										SetTokenInfo(vint token, const TokenInfo& info);

				vint										GetDiscardTokenCount();
				const TokenInfo&							GetDiscardTokenInfo(vint token);
				void										SetDiscardTokenInfo(vint token, const TokenInfo& info);

				vint										GetStateCount();
				const StateInfo&							GetStateInfo(vint state);
				void										SetStateInfo(vint state, const StateInfo& info);

				vint										GetRuleCount();
				const RuleInfo&								GetRuleInfo(const WString& ruleName);
				const RuleInfo&								GetRuleInfo(vint rule);
				void										SetRuleInfo(vint rule, const RuleInfo& info);

				const regex::RegexLexer&					GetLexer();
				Ptr<TransitionBag>							GetTransitionBag(vint state, vint token);
				void										SetTransitionBag(vint state, vint token, Ptr<TransitionBag> bag);
				/// <summary>Initialize the parsing table. This function should be called after deserializing the table from a string.</summary>
				void										Initialize();
				bool										IsInputToken(vint regexTokenIndex);
				vint										GetTableTokenIndex(vint regexTokenIndex);
				vint										GetTableDiscardTokenIndex(vint regexTokenIndex);
			};

/***********************************************************************
Helper Functions
***********************************************************************/

			extern void										Log(Ptr<ParsingTable> table, stream::TextWriter& writer);
		}
	}
}

#endif

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

#ifndef VCZH_PARSING_PARSINGAUTOMATON
#define VCZH_PARSING_PARSINGAUTOMATON


namespace vl
{
	namespace parsing
	{
		namespace analyzing
		{

/***********************************************************************
Automaton
***********************************************************************/

			class Action;
			class Transition;
			class State;

			class Action : public Object
			{
			public:
				enum ActionType
				{
					Create, // new source
					Assign, // source ::= <created symbol>
					Using,  // use <created symbol>
					Setter, // source ::= target
					Shift,
					Reduce,
					LeftRecursiveReduce,
				};

				ActionType											actionType;
				ParsingSymbol*										actionTarget;
				ParsingSymbol*										actionSource;
				definitions::ParsingDefinitionRuleDefinition*		creatorRule;

				// the following two fields record which rule symbol transition generate this shift/reduce action
				State*												shiftReduceSource;
				State*												shiftReduceTarget;

				Action();
				~Action();
			};

			class Transition : public Object
			{
			public:
				enum TransitionType
				{
					TokenBegin,				// token stream start
					TokenFinish,			// token stream end
					NormalReduce,			// rule end
					LeftRecursiveReduce,	// rule end with left recursive
					Epsilon,				// an epsilon transition
					Symbol,					// a syntax symbol
				};

				enum StackOperationType
				{
					None,
					ShiftReduceCompacted,
					LeftRecursive,
				};

				State*												source;
				State*												target;
				collections::List<Ptr<Action>>						actions;
				
				TransitionType										transitionType;
				StackOperationType									stackOperationType;
				ParsingSymbol*										transitionSymbol;

				Transition();
				~Transition();

				static bool											IsEquivalent(Transition* t1, Transition* t2, bool careSourceAndTarget);
			};

			class State : public Object
			{
			public:
				enum StatePosition
				{
					BeforeNode,
					AfterNode,
				};

				collections::List<Transition*>						transitions;
				collections::List<Transition*>						inputs;
				bool												endState;

				ParsingSymbol*										ownerRuleSymbol;
				definitions::ParsingDefinitionRuleDefinition*		ownerRule;
				definitions::ParsingDefinitionGrammar*				grammarNode;
				definitions::ParsingDefinitionGrammar*				stateNode;
				StatePosition										statePosition;
				WString												stateName;
				WString												stateExpression;

				State();
				~State();
			};

			class RuleInfo : public Object
			{
			public:
				State*												rootRuleStartState;
				State*												rootRuleEndState;
				State*												startState;
				collections::List<State*>							endStates;
				int													stateNameCount;

				RuleInfo();
				~RuleInfo();
			};

			class Automaton : public Object
			{
				typedef collections::List<definitions::ParsingDefinitionRuleDefinition*>							RuleDefList;
				typedef collections::Dictionary<definitions::ParsingDefinitionRuleDefinition*, Ptr<RuleInfo>>		RuleInfoMap;
			public:
				ParsingSymbolManager*								symbolManager;
				collections::List<Ptr<Transition>>					transitions;
				collections::List<Ptr<State>>						states;
				collections::List<Ptr<RuleInfo>>					ruleInfos;

				RuleDefList											orderedRulesDefs;
				RuleInfoMap											ruleDefToInfoMap;

				Automaton(ParsingSymbolManager* _symbolManager);
				~Automaton();

				void												AddRuleInfo(definitions::ParsingDefinitionRuleDefinition* rule, Ptr<RuleInfo> ruleInfo);

				State*												RuleStartState(definitions::ParsingDefinitionRuleDefinition* ownerRule);
				State*												RootRuleStartState(definitions::ParsingDefinitionRuleDefinition* ownerRule);
				State*												RootRuleEndState(definitions::ParsingDefinitionRuleDefinition* ownerRule);
				State*												StartState(definitions::ParsingDefinitionRuleDefinition* ownerRule, definitions::ParsingDefinitionGrammar* grammarNode, definitions::ParsingDefinitionGrammar* stateNode);
				State*												EndState(definitions::ParsingDefinitionRuleDefinition* ownerRule, definitions::ParsingDefinitionGrammar* grammarNode, definitions::ParsingDefinitionGrammar* stateNode);
				State*												CopyState(State* oldState);

				Transition*											CreateTransition(State* start, State* end);
				Transition*											TokenBegin(State* start, State* end);
				Transition*											TokenFinish(State* start, State* end);
				Transition*											NormalReduce(State* start, State* end);
				Transition*											LeftRecursiveReduce(State* start, State* end);
				Transition*											Epsilon(State* start, State* end);
				Transition*											Symbol(State* start, State* end, ParsingSymbol* transitionSymbol);
				Transition*											CopyTransition(State* start, State* end, Transition* oldTransition);

				void												DeleteTransition(Transition* transition);
				void												DeleteState(State* state);
			};

/***********************************************************************
Helper: Closuer Searching
***********************************************************************/

			struct ClosureItem
			{
				enum SearchResult
				{
					Continue,
					Hit,
					Blocked,
				};

				State*											state;			// target state of one path of a closure
				Ptr<collections::List<Transition*>>				transitions;	// path
				bool											cycle;			// true: invalid closure because there are cycles, and in the middle of the path there will be a transition that targets to the state field.

				ClosureItem()
					:state(0)
					,cycle(false)
				{
				}

				ClosureItem(State* _state, Ptr<collections::List<Transition*>> _transitions, bool _cycle)
					:state(_state)
					,transitions(_transitions)
					,cycle(_cycle)
				{
				}
			};

			extern void												SearchClosure(ClosureItem::SearchResult(*closurePredicate)(Transition*), State* startState, collections::List<ClosureItem>& closure);
			extern void												RemoveEpsilonTransitions(collections::Dictionary<State*, State*>& oldNewStateMap, collections::List<State*>& scanningStates, Ptr<Automaton> automaton);

/***********************************************************************
Helper: State Merging
***********************************************************************/
			
			extern void												DeleteUnnecessaryStates(Ptr<Automaton> automaton, Ptr<RuleInfo> ruleInfo, collections::List<State*>& newStates);
			extern void												MergeStates(Ptr<Automaton> automaton, Ptr<RuleInfo> ruleInfo, collections::List<State*>& newStates);

/***********************************************************************
Helper: Automaton Building
***********************************************************************/
			
			extern Ptr<Automaton>									CreateEpsilonPDA(Ptr<definitions::ParsingDefinition> definition, ParsingSymbolManager* manager);
			extern Ptr<Automaton>									CreateNondeterministicPDAFromEpsilonPDA(Ptr<Automaton> epsilonPDA);
			extern Ptr<Automaton>									CreateJointPDAFromNondeterministicPDA(Ptr<Automaton> nondeterministicPDA);
			extern void												CompactJointPDA(Ptr<Automaton> jointPDA);
			extern void												MarkLeftRecursiveInJointPDA(Ptr<Automaton> jointPDA, collections::List<Ptr<ParsingError>>& errors);

/***********************************************************************
Helper: Parsing Table Generating
***********************************************************************/

			extern WString											GetTypeNameForCreateInstruction(ParsingSymbol* type);
			extern Ptr<tabling::ParsingTable>						GenerateTableFromPDA(Ptr<definitions::ParsingDefinition> definition, ParsingSymbolManager* manager, Ptr<Automaton> jointPDA, bool enableAmbiguity, collections::List<Ptr<ParsingError>>& errors);
			extern Ptr<tabling::ParsingTable>						GenerateTable(Ptr<definitions::ParsingDefinition> definition, bool enableAmbiguity, collections::List<Ptr<ParsingError>>& errors);
			extern void												Log(Ptr<Automaton> automaton, stream::TextWriter& writer);
		}
	}
}

#endif

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

#ifndef VCZH_PARSING_PARSINGSTATE
#define VCZH_PARSING_PARSINGSTATE


namespace vl
{
	namespace parsing
	{
		namespace tabling
		{

/***********************************************************************
Syntax Analyzer
***********************************************************************/
			
			class ParsingTokenWalker : public Object
			{
			protected:
				class LookAheadEnumerator : public Object, public collections::IEnumerator<vint>
				{
				protected:
					const ParsingTokenWalker*			walker;
					vint								firstToken;
					vint								currentToken;
					vint								currentValue;
					vint								index;

				public:
					LookAheadEnumerator(const ParsingTokenWalker* _walker, vint _currentToken);
					LookAheadEnumerator(const LookAheadEnumerator& _enumerator);

					collections::IEnumerator<vint>*		Clone()const override;
					const vint&							Current()const override;
					vint								Index()const override;
					bool								Next()override;
					void								Reset()override;
				};

				class TokenLookAhead : public collections::EnumerableBase<vint>
				{
				protected:
					const ParsingTokenWalker*			walker;
				public:
					TokenLookAhead(const ParsingTokenWalker* _talker);

					collections::IEnumerator<vint>*			CreateEnumerator()const override;
				};

				class ReduceLookAhead : public collections::EnumerableBase<vint>
				{
				protected:
					const ParsingTokenWalker*			walker;
				public:
					ReduceLookAhead(const ParsingTokenWalker* _walker);

					collections::IEnumerator<vint>*			CreateEnumerator()const override;
				};

			protected:
				collections::List<regex::RegexToken>&	tokens;
				Ptr<ParsingTable>						table;
				vint									currentToken;
				TokenLookAhead							tokenLookAhead;
				ReduceLookAhead							reduceLookAhead;

				vint									GetNextIndex(vint index)const;
				vint									GetTableTokenIndex(vint index)const;
			public:
				ParsingTokenWalker(collections::List<regex::RegexToken>& _tokens, Ptr<ParsingTable> _table);
				~ParsingTokenWalker();

				const collections::IEnumerable<vint>&	GetTokenLookahead()const;
				const collections::IEnumerable<vint>&	GetReduceLookahead()const;
				void									Reset();
				bool									Move();
				vint									GetTableTokenIndex()const;
				regex::RegexToken*						GetRegexToken()const;
				vint									GetTokenIndexInStream()const;
			};

			class ParsingState : public Object
			{
			public:
				struct ShiftReduceRange
				{
					regex::RegexToken*							shiftToken;
					regex::RegexToken*							reduceToken;

					ShiftReduceRange()
						:shiftToken(0)
						,reduceToken(0)
					{
					}
				};

				struct TransitionResult
				{
					enum TransitionType
					{
						ExecuteInstructions,
						AmbiguityBegin,
						AmbiguityBranch,
						AmbiguityEnd,
						SkipToken,
					};

					TransitionType								transitionType;
					vint										ambiguityAffectedStackNodeCount;
					WString										ambiguityNodeType;

					vint										tableTokenIndex;
					vint										tableStateSource;
					vint										tableStateTarget;
					vint										tokenIndexInStream;
					regex::RegexToken*							token;

					ParsingTable::TransitionItem*				transition;
					vint										instructionBegin;
					vint										instructionCount;
					Ptr<collections::List<ShiftReduceRange>>	shiftReduceRanges;

					TransitionResult(TransitionType _transitionType=ExecuteInstructions)
						:transitionType(_transitionType)
						,ambiguityAffectedStackNodeCount(0)
						,tableTokenIndex(-1)
						,tableStateSource(-1)
						,tableStateTarget(-1)
						,tokenIndexInStream(-1)
						,token(0)
						,transition(0)
						,instructionBegin(-1)
						,instructionCount(-1)
					{
					}

					operator bool()const
					{
						return transitionType!=ExecuteInstructions || transition!=0;
					}

					void AddShiftReduceRange(regex::RegexToken* shiftToken, regex::RegexToken* reduceToken)
					{
						ShiftReduceRange range;
						range.shiftToken=shiftToken;
						range.reduceToken=reduceToken;
						if(!shiftReduceRanges)
						{
							shiftReduceRanges = Ptr(new collections::List<ShiftReduceRange>());
						}
						shiftReduceRanges->Add(range);
					}
				};

				struct Future
				{
					vint									currentState;
					vint									reduceStateCount;
					collections::List<vint>					shiftStates;
					regex::RegexToken*						selectedRegexToken;
					vint									selectedToken;
					ParsingTable::TransitionItem*			selectedItem;
					Future*									previous;
					Future*									next;

					Future()
						:currentState(-1)
						,reduceStateCount(0)
						,selectedRegexToken(0)
						,selectedToken(-1)
						,selectedItem(0)
						,previous(0)
						,next(0)
					{
					}

					Future* Clone()
					{
						Future* future = new Future;
						future->currentState = currentState;
						future->reduceStateCount = reduceStateCount;
						CopyFrom(future->shiftStates, shiftStates);
						future->selectedRegexToken = selectedRegexToken;
						future->selectedToken = selectedToken;
						future->selectedItem = selectedItem;
						future->previous = previous;
						return future;
					}
				};

				struct StateGroup
				{
					collections::List<vint>						stateStack;
					vint										currentState;
					vint										tokenSequenceIndex;

					collections::List<regex::RegexToken*>		shiftTokenStack;
					regex::RegexToken*							shiftToken;
					regex::RegexToken*							reduceToken;

					StateGroup();
					StateGroup(const ParsingTable::RuleInfo& info);
					StateGroup(const StateGroup& group);
				};
			private:
				WString										input;
				Ptr<ParsingTable>							table;
				collections::List<regex::RegexToken>		tokens;
				Ptr<ParsingTokenWalker>						walker;
				
				WString										parsingRule;
				vint										parsingRuleStartState;
				Ptr<StateGroup>								stateGroup;
			public:
				ParsingState(const WString& _input, Ptr<ParsingTable> _table, vint codeIndex=-1);
				~ParsingState();

				const WString&								GetInput();
				Ptr<ParsingTable>							GetTable();
				const collections::List<regex::RegexToken>&	GetTokens();
				regex::RegexToken*							GetToken(vint index);

				vint										Reset(const WString& rule);
				WString										GetParsingRule();
				vint										GetParsingRuleStartState();
				vint										GetCurrentToken();
				vint										GetCurrentTableTokenIndex();
				const collections::List<vint>&				GetStateStack();
				vint										GetCurrentState();
				void										SkipCurrentToken();

				bool										TestTransitionItemInFuture(vint tableTokenIndex, Future* future, ParsingTable::TransitionItem* item, const collections::IEnumerable<vint>* lookAheadTokens);
				ParsingTable::TransitionItem*				MatchTokenInFuture(vint tableTokenIndex, Future* future, const collections::IEnumerable<vint>* lookAheadTokens);
				ParsingTable::TransitionItem*				MatchToken(vint tableTokenIndex, const collections::IEnumerable<vint>* lookAheadTokens);
				void										RunTransitionInFuture(ParsingTable::TransitionItem* transition, Future* previous, Future* now);
				ParsingState::TransitionResult				RunTransition(ParsingTable::TransitionItem* transition, regex::RegexToken* regexToken, vint instructionBegin, vint instructionCount, bool lastPart);
				ParsingState::TransitionResult				RunTransition(ParsingTable::TransitionItem* transition, regex::RegexToken* regexToken);

				bool										ReadTokenInFuture(vint tableTokenIndex, Future* previous, Future* now, const collections::IEnumerable<vint>* lookAheadTokens);
				TransitionResult							ReadToken(vint tableTokenIndex, regex::RegexToken* regexToken, const collections::IEnumerable<vint>* lookAheadTokens);
				TransitionResult							ReadToken();

				bool										TestExplore(vint tableTokenIndex, Future* previous);
				bool										Explore(vint tableTokenIndex, Future* previous, collections::List<Future*>& possibilities);
				bool										ExploreStep(collections::List<Future*>& previousFutures, vint start, vint count, collections::List<Future*>& possibilities);
				bool										ExploreNormalReduce(collections::List<Future*>& previousFutures, vint start, vint count, collections::List<Future*>& possibilities);
				bool										ExploreLeftRecursiveReduce(collections::List<Future*>& previousFutures, vint start, vint count, collections::List<Future*>& possibilities);
				Future*										ExploreCreateRootFuture();

				Ptr<StateGroup>								TakeSnapshot();
				void										RestoreSnapshot(Ptr<StateGroup> group);
			};

/***********************************************************************
AST Generating
***********************************************************************/

			class ParsingTransitionProcessor : public Object
			{
			public:
				virtual void								Reset()=0;
				virtual bool								Run(const ParsingState::TransitionResult& result)=0;
				virtual bool								GetProcessingAmbiguityBranch()=0;
			};

			class ParsingTreeBuilder : public ParsingTransitionProcessor
			{
			protected:
				Ptr<ParsingTreeNode>						createdObject;
				Ptr<ParsingTreeObject>						operationTarget;
				collections::List<Ptr<ParsingTreeObject>>	nodeStack;

				bool										processingAmbiguityBranch;
				Ptr<ParsingTreeNode>						ambiguityBranchCreatedObject;
				Ptr<ParsingTreeNode>						ambiguityBranchOperationTarget;
				vint										ambiguityBranchSharedNodeCount;
				collections::List<Ptr<ParsingTreeObject>>	ambiguityBranchNodeStack;
				collections::List<Ptr<ParsingTreeObject>>	ambiguityNodes;
			public:
				ParsingTreeBuilder();
				~ParsingTreeBuilder();

				void										Reset()override;
				bool										Run(const ParsingState::TransitionResult& result)override;
				bool										GetProcessingAmbiguityBranch()override;
				Ptr<ParsingTreeObject>						GetNode()const;
			};

			class ParsingTransitionCollector : public ParsingTransitionProcessor
			{
				typedef collections::List<ParsingState::TransitionResult>		TransitionResultList;
			protected:
				vint										ambiguityBegin;
				TransitionResultList						transitions;

				collections::Dictionary<vint, vint>			ambiguityBeginToEnds;
				collections::Group<vint, vint>				ambiguityBeginToBranches;
				collections::Dictionary<vint, vint>			ambiguityBranchToBegins;
			public:
				ParsingTransitionCollector();
				~ParsingTransitionCollector();

				void										Reset()override;
				bool										Run(const ParsingState::TransitionResult& result)override;
				bool										GetProcessingAmbiguityBranch()override;

				const TransitionResultList&					GetTransitions()const;
				vint										GetAmbiguityEndFromBegin(vint transitionIndex)const;
				const collections::List<vint>&				GetAmbiguityBranchesFromBegin(vint transitionIndex)const;
				vint										GetAmbiguityBeginFromBranch(vint transitionIndex)const;
			};
		}
	}
}

#endif

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

#ifndef VCZH_PARSING_PARSING
#define VCZH_PARSING_PARSING


namespace vl
{
	namespace parsing
	{
		namespace tabling
		{

/***********************************************************************
Parser
***********************************************************************/

			/// <summary>Base type of all parser strategy.</summary>
			class ParsingGeneralParser : public Object
			{
			protected:
				Ptr<ParsingTable>							table;
				
			public:
				ParsingGeneralParser(Ptr<ParsingTable> _table);
				~ParsingGeneralParser();
				
				/// <summary>Get the parser table that used to do the parsing.</summary>
				/// <returns>The parser table that used to do the parsing.</returns>
				Ptr<ParsingTable>							GetTable();
				/// <summary>Initialization. It should be called before each time of parsing.</summary>
				virtual void								BeginParse();
				virtual ParsingState::TransitionResult		ParseStep(ParsingState& state, collections::List<Ptr<ParsingError>>& errors)=0;
				bool										Parse(ParsingState& state, ParsingTransitionProcessor& processor, collections::List<Ptr<ParsingError>>& errors);
				Ptr<ParsingTreeNode>						Parse(ParsingState& state, collections::List<Ptr<ParsingError>>& errors);
				/// <summary>Parse an input and get an abstract syntax tree if no error happens or all errors are recovered.</summary>
				/// <returns>The abstract syntax tree.</returns>
				/// <param name="input">The input to parse.</param>
				/// <param name="rule">The name of the rule that used to parse the input.</param>
				/// <param name="errors">Returns all errors.</param>
				/// <param name="codeIndex">The code index to differentiate each input. This value will be stored in every tokens and abstract syntax nodes.</param>
				Ptr<ParsingTreeNode>						Parse(const WString& input, const WString& rule, collections::List<Ptr<ParsingError>>& errors, vint codeIndex = -1);
			};

/***********************************************************************
Parser with different strategies
***********************************************************************/

			/// <summary>A strict parse. It doesn't allow ambiguity and error recovery.</summary>
			class ParsingStrictParser : public ParsingGeneralParser
			{
			protected:
				
				virtual bool								OnTestErrorRecoverExists();
				virtual void								OnClearErrorRecover();
				virtual ParsingState::TransitionResult		OnErrorRecover(ParsingState& state, vint currentTokenIndex, collections::List<Ptr<ParsingError>>& errors);
			public:
				/// <summary>Create the parse using a parsing table.</summary>
				/// <param name="_table">The parsing table.</param>
				ParsingStrictParser(Ptr<ParsingTable> _table=0);
				~ParsingStrictParser();
				
				ParsingState::TransitionResult				ParseStep(ParsingState& state, collections::List<Ptr<ParsingError>>& errors)override;
			};
			
			/// <summary>A strict parse. It doesn't allow ambiguity but allows error recovery.</summary>
			class ParsingAutoRecoverParser : public ParsingStrictParser
			{
			public:
				struct RecoverFuture
				{
					ParsingState::Future*					future;
					vint									insertedTokenCount;
					vint									index;
					vint									previousIndex;
					vint									nextIndex;

					RecoverFuture()
						:future(0)
						, insertedTokenCount(0)
						, index(-1)
						, previousIndex(-1)
						, nextIndex(-1)
					{
					}
				};
			protected:
				vint										maxInsertedTokenCount;
				collections::List<RecoverFuture>			recoverFutures;
				vint										recoveringFutureIndex;
				
				RecoverFuture&								GetRecoverFuture(vint index);
				RecoverFuture&								CreateRecoverFuture(vint index, vint previousIndex);
				bool										OnTestErrorRecoverExists()override;
				void										OnClearErrorRecover()override;
				ParsingState::TransitionResult				OnErrorRecover(ParsingState& state, vint currentTokenIndex, collections::List<Ptr<ParsingError>>& errors)override;
			public:
				/// <summary>Create the parse using a parsing table.</summary>
				/// <param name="_table">The parsing table.</param>
				/// <param name="_maxInsertedTokenCount">The maximum number of tokens that allow to insert to recover an error.</param>
				ParsingAutoRecoverParser(Ptr<ParsingTable> _table = 0, vint _maxInsertedTokenCount = -1);
				~ParsingAutoRecoverParser();

				void										BeginParse()override;
			};
			
			/// <summary>A strict parse. It allows ambiguity but doesn't allow error recovery.</summary>
			class ParsingAmbiguousParser : public ParsingGeneralParser
			{
				typedef collections::List<ParsingState::TransitionResult>		DecisionList;
			protected:

				DecisionList								decisions;
				vint										consumedDecisionCount;

				virtual void								OnErrorRecover(ParsingState& state, vint currentTokenIndex, collections::List<ParsingState::Future*>& futures, vint& begin, vint& end, collections::List<Ptr<ParsingError>>& errors);
				vint										GetResolvableFutureLevels(collections::List<ParsingState::Future*>& futures, vint begin, vint end);
				vint										SearchPathForOneStep(ParsingState& state, collections::List<ParsingState::Future*>& futures, vint& begin, vint& end, collections::List<Ptr<ParsingError>>& errors);
				vint										GetConflictReduceCount(collections::List<ParsingState::Future*>& futures);
				void										GetConflictReduceIndices(collections::List<ParsingState::Future*>& futures, vint conflictReduceCount, collections::Array<vint>& conflictReduceIndices);
				vint										GetAffectedStackNodeCount(collections::List<ParsingState::Future*>& futures, collections::Array<vint>& conflictReduceIndices);
				void										BuildSingleDecisionPath(ParsingState& state, ParsingState::Future* future, vint lastAvailableInstructionCount);
				void										BuildAmbiguousDecisions(ParsingState& state, collections::List<ParsingState::Future*>& futures, vint begin, vint end, vint resolvableFutureLevels, collections::List<Ptr<ParsingError>>& errors);
				void										BuildDecisions(ParsingState& state, collections::List<ParsingState::Future*>& futures, vint begin, vint end, vint resolvableFutureLevels, collections::List<Ptr<ParsingError>>& errors);
			public:
				/// <summary>Create the parse using a parsing table.</summary>
				/// <param name="_table">The parsing table.</param>
				ParsingAmbiguousParser(Ptr<ParsingTable> _table=0);
				~ParsingAmbiguousParser();
				
				ParsingState::TransitionResult				ParseStep(ParsingState& state, collections::List<Ptr<ParsingError>>& errors)override;
				void										BeginParse()override;
			};
			
			/// <summary>A strict parse. It allow both ambiguity and error recovery.</summary>
			class ParsingAutoRecoverAmbiguousParser : public ParsingAmbiguousParser
			{
			protected:
				vint										maxInsertedTokenCount;

				void										OnErrorRecover(ParsingState& state, vint currentTokenIndex, collections::List<ParsingState::Future*>& futures, vint& begin, vint& end, collections::List<Ptr<ParsingError>>& errors)override;
			public:
				/// <summary>Create the parse using a parsing table.</summary>
				/// <param name="_table">The parsing table.</param>
				/// <param name="_maxInsertedTokenCount">The maximum number of tokens that allow to insert to recover an error.</param>
				ParsingAutoRecoverAmbiguousParser(Ptr<ParsingTable> _table = 0, vint _maxInsertedTokenCount = -1);
				~ParsingAutoRecoverAmbiguousParser();
			};

/***********************************************************************
Helper Functions
***********************************************************************/
			
			/// <summary>Create the correct strict parser from a parsing table.</summary>
			/// <returns>The created parse.</returns>
			/// <param name="table">The table to create a parser.</param>
			extern Ptr<ParsingGeneralParser>				CreateStrictParser(Ptr<ParsingTable> table);
			/// <summary>Create the correct error recoverable parser from a parsing table.</summary>
			/// <returns>The created parse.</returns>
			/// <param name="table">The table to create a parser.</param>
			extern Ptr<ParsingGeneralParser>				CreateAutoRecoverParser(Ptr<ParsingTable> table);
			/// <summary>Create the correct strict parser to parse the grammar itself.</summary>
			/// <returns>The created parse.</returns>
			extern Ptr<ParsingGeneralParser>				CreateBootstrapStrictParser();
			/// <summary>Create the correct error recoverable to parse the grammar itself.</summary>
			/// <returns>The created parse.</returns>
			extern Ptr<ParsingGeneralParser>				CreateBootstrapAutoRecoverParser();
		}
	}
}

/***********************************************************************
Reflection for AST
***********************************************************************/

#ifndef VCZH_DEBUG_NO_REFLECTION

namespace vl
{
	namespace reflection
	{
		namespace description
		{
#define PARSINGREFLECTION_TYPELIST(F)\
			F(parsing::ParsingTextPos)\
			F(parsing::ParsingTextRange)\
			F(parsing::ParsingTreeNode)\
			F(parsing::ParsingTreeToken)\
			F(parsing::ParsingTreeObject)\
			F(parsing::ParsingTreeArray)\
			F(parsing::ParsingTreeCustomBase)\
			F(parsing::ParsingToken)\
			F(parsing::ParsingError)\

			PARSINGREFLECTION_TYPELIST(DECL_TYPE_INFO)
		}
	}
}

#endif

namespace vl
{
	namespace reflection
	{
		namespace description
		{
			extern bool								LoadParsingTypes();
		}
	}
}

#endif

/***********************************************************************
.\JSON\PARSINGJSON_AST.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:ParsingJson.parser.txt
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSING_JSON_PARSINGJSON_PARSER_AST
#define VCZH_PARSING_JSON_PARSINGJSON_PARSER_AST


namespace vl
{
	namespace parsing
	{
		namespace json
		{
			/// <summary>Token types. Values of enum items will be used in <see cref="vl::regex::RegexToken::token"/>.</summary>
			enum class JsonParserTokenIndex
			{
				/// <summary>Token TRUEVALUE: true</summary>
				TRUEVALUE = 0,
				/// <summary>Token FALSEVALUE: false</summary>
				FALSEVALUE = 1,
				/// <summary>Token NULLVALUE: null</summary>
				NULLVALUE = 2,
				/// <summary>Token OBJOPEN: \{</summary>
				OBJOPEN = 3,
				/// <summary>Token OBJCLOSE: \}</summary>
				OBJCLOSE = 4,
				/// <summary>Token ARROPEN: \[</summary>
				ARROPEN = 5,
				/// <summary>Token ARRCLOSE: \]</summary>
				ARRCLOSE = 6,
				/// <summary>Token COMMA: ,</summary>
				COMMA = 7,
				/// <summary>Token COLON: :</summary>
				COLON = 8,
				/// <summary>Token NUMBER: [\-]?\d+(.\d+)?([eE][+\-]?\d+)?</summary>
				NUMBER = 9,
				/// <summary>Token STRING: &quot;([^\\&quot;]|\\[^u]|\\u\d{4})*&quot;</summary>
				STRING = 10,
				/// <summary>Discardable token SPACE: \s+</summary>
				SPACE = 11,
			};
			class JsonNode;
			class JsonLiteral;
			class JsonString;
			class JsonNumber;
			class JsonArray;
			class JsonObjectField;
			class JsonObject;

			/// <summary>Base class of JSON nodes.</summary>
			class JsonNode abstract : public vl::parsing::ParsingTreeCustomBase, vl::reflection::Description<JsonNode>
			{
			public:
				/// <summary>Visitor interface for <see cref="JsonNode"/>.</summary>
				class IVisitor : public vl::reflection::IDescriptable, vl::reflection::Description<IVisitor>
				{
				public:
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="JsonLiteral"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(JsonLiteral* node)=0;
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="JsonString"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(JsonString* node)=0;
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="JsonNumber"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(JsonNumber* node)=0;
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="JsonArray"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(JsonArray* node)=0;
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="JsonObjectField"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(JsonObjectField* node)=0;
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="JsonObject"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(JsonObject* node)=0;
				};

				/// <summary>Accept a visitor to reveal its real type of this strong-typed AST node.</summary>
				/// <param name="visitor">The visitor, one of its <b>Visit</b> method will be called according to the real type of this strong-typed AST node.</param>
				virtual void Accept(JsonNode::IVisitor* visitor)=0;

			};

			/// <summary>Literal value node that is not number or string.</summary>
			class JsonLiteral : public JsonNode, vl::reflection::Description<JsonLiteral>
			{
			public:
				/// <summary>Literal value.</summary>
				enum class JsonValue
				{
					/// <summary>A boolean literal: true.</summary>
					True,
					/// <summary>A boolean literal: false.</summary>
					False,
					/// <summary>A null literal.</summary>
					Null,
				};

				/// <summary>The literal value.</summary>
				JsonValue value;

				void Accept(JsonNode::IVisitor* visitor)override;

				static vl::Ptr<JsonLiteral> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

			/// <summary>String literal value node.</summary>
			class JsonString : public JsonNode, vl::reflection::Description<JsonString>
			{
			public:
				/// <summary>Content of the string literal.</summary>
				vl::parsing::ParsingToken content;

				void Accept(JsonNode::IVisitor* visitor)override;

				static vl::Ptr<JsonString> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

			/// <summary>Number literal value node.</summary>
			class JsonNumber : public JsonNode, vl::reflection::Description<JsonNumber>
			{
			public:
				/// <summary>Content of the number literal.</summary>
				vl::parsing::ParsingToken content;

				void Accept(JsonNode::IVisitor* visitor)override;

				static vl::Ptr<JsonNumber> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

			/// <summary>Array node.</summary>
			class JsonArray : public JsonNode, vl::reflection::Description<JsonArray>
			{
			public:
				/// <summary>Array elements.</summary>
				vl::collections::List<vl::Ptr<JsonNode>> items;

				void Accept(JsonNode::IVisitor* visitor)override;

				static vl::Ptr<JsonArray> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

			/// <summary>Object property node.</summary>
			class JsonObjectField : public JsonNode, vl::reflection::Description<JsonObjectField>
			{
			public:
				/// <summary>Property name.</summary>
				vl::parsing::ParsingToken name;
				/// <summary>Property value.</summary>
				vl::Ptr<JsonNode> value;

				void Accept(JsonNode::IVisitor* visitor)override;

				static vl::Ptr<JsonObjectField> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

			/// <summary>Object node.</summary>
			class JsonObject : public JsonNode, vl::reflection::Description<JsonObject>
			{
			public:
				/// <summary>Object properties.</summary>
				vl::collections::List<vl::Ptr<JsonObjectField>> fields;

				void Accept(JsonNode::IVisitor* visitor)override;

				static vl::Ptr<JsonObject> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

		}
	}
}
namespace vl
{
	namespace reflection
	{
		namespace description
		{
#ifndef VCZH_DEBUG_NO_REFLECTION
			DECL_TYPE_INFO(vl::parsing::json::JsonNode)
			DECL_TYPE_INFO(vl::parsing::json::JsonLiteral)
			DECL_TYPE_INFO(vl::parsing::json::JsonLiteral::JsonValue)
			DECL_TYPE_INFO(vl::parsing::json::JsonString)
			DECL_TYPE_INFO(vl::parsing::json::JsonNumber)
			DECL_TYPE_INFO(vl::parsing::json::JsonArray)
			DECL_TYPE_INFO(vl::parsing::json::JsonObjectField)
			DECL_TYPE_INFO(vl::parsing::json::JsonObject)
			DECL_TYPE_INFO(vl::parsing::json::JsonNode::IVisitor)

#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA

			BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::parsing::json::JsonNode::IVisitor)
				void Visit(vl::parsing::json::JsonLiteral* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

				void Visit(vl::parsing::json::JsonString* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

				void Visit(vl::parsing::json::JsonNumber* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

				void Visit(vl::parsing::json::JsonArray* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

				void Visit(vl::parsing::json::JsonObjectField* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

				void Visit(vl::parsing::json::JsonObject* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

			END_INTERFACE_PROXY(vl::parsing::json::JsonNode::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 JsonLoadTypes();
		}
	}
}
#endif

/***********************************************************************
.\JSON\PARSINGJSON_PARSER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:ParsingJson.parser.txt
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSING_JSON_PARSINGJSON_PARSER_PARSER
#define VCZH_PARSING_JSON_PARSINGJSON_PARSER_PARSER


namespace vl
{
	namespace parsing
	{
		namespace json
		{
			/// <summary>Get the grammar definition for this parser.</summary>
			/// <returns>The grammar definition for this parser.</returns>
			extern vl::WString JsonGetParserTextBuffer();
			/// <summary>Convert parser result to a strong typed AST node. Usually you don't need to use this function, unless you are doing meta programming like error recovering or implementing intellisense for an editor.</summary>
			/// <returns>Returns the strong typed AST node.</returns>
			/// <param name="node">The parser result.</param>
			/// <param name="tokens">Tokens for parsing. You can get the <see cref="vl::regex::RegexLexer"/> by calling <see cref="vl::parsing::tabling::ParsingTable::GetLexer"/> from <see cref="JsonLoadTable"/></param>
			extern vl::Ptr<vl::parsing::ParsingTreeCustomBase> JsonConvertParsingTreeNode(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			/// <summary>Create the parser table. You should cache the value if possible, for improving performance.</summary>
			/// <returns>The created parser table.</returns>
			extern vl::Ptr<vl::parsing::tabling::ParsingTable> JsonLoadTable();

			/// <summary>Parse a JSON text, it could be an object or an array.</summary>
			/// <returns>Returns the parsing result as a weak-typed AST node. Returns null if there is any unrecoverable error during parsing.</returns>
			/// <param name="input">The input for parsing.</param>
			/// <param name="table">The return value from <see cref="JsonLoadTable"/>.</param>
			/// <param name="errors">All errors during parsing.</param>
			/// <param name="codeIndex">(Optional): This argument will be copied to <see cref="vl::parsing::ParsingTextRange::codeIndex"/> in every AST nodes. The default value is -1.</param>
			extern vl::Ptr<vl::parsing::ParsingTreeNode> JsonParseAsParsingTreeNode(const vl::WString& input, vl::Ptr<vl::parsing::tabling::ParsingTable> table, vl::collections::List<vl::Ptr<vl::parsing::ParsingError>>& errors, vl::vint codeIndex = -1);
			/// <summary>Parse a JSON text, it could be an object or an array.</summary>
			/// <returns>Returns the parsing result as a weak-typed AST node. Returns null if there is any unrecoverable error during parsing.</returns>
			/// <param name="input">The input for parsing.</param>
			/// <param name="table">The return value from <see cref="JsonLoadTable"/>.</param>
			/// <param name="codeIndex">(Optional): This argument will be copied to <see cref="vl::parsing::ParsingTextRange::codeIndex"/> in every AST nodes. The default value is -1.</param>
			extern vl::Ptr<vl::parsing::ParsingTreeNode> JsonParseAsParsingTreeNode(const vl::WString& input, vl::Ptr<vl::parsing::tabling::ParsingTable> table, vl::vint codeIndex = -1);
			/// <summary>Parse a JSON text, it could be an object or an array.</summary>
			/// <returns>Returns the parsing result as a strong-typed AST node. Returns null if there is any unrecoverable error during parsing.</returns>
			/// <param name="input">The input for parsing.</param>
			/// <param name="table">The return value from <see cref="JsonLoadTable"/>.</param>
			/// <param name="errors">All errors during parsing.</param>
			/// <param name="codeIndex">(Optional): This argument will be copied to <see cref="vl::parsing::ParsingTextRange::codeIndex"/> in every AST nodes. The default value is -1.</param>
			extern vl::Ptr<JsonNode> JsonParse(const vl::WString& input, vl::Ptr<vl::parsing::tabling::ParsingTable> table, vl::collections::List<vl::Ptr<vl::parsing::ParsingError>>& errors, vl::vint codeIndex = -1);
			/// <summary>Parse a JSON text, it could be an object or an array.</summary>
			/// <returns>Returns the parsing result as a strong-typed AST node. Returns null if there is any unrecoverable error during parsing.</returns>
			/// <param name="input">The input for parsing.</param>
			/// <param name="table">The return value from <see cref="JsonLoadTable"/>.</param>
			/// <param name="codeIndex">(Optional): This argument will be copied to <see cref="vl::parsing::ParsingTextRange::codeIndex"/> in every AST nodes. The default value is -1.</param>
			extern vl::Ptr<JsonNode> JsonParse(const vl::WString& input, vl::Ptr<vl::parsing::tabling::ParsingTable> table, vl::vint codeIndex = -1);
		}
	}
}
#endif

/***********************************************************************
.\JSON\PARSINGJSON.H
***********************************************************************/
/***********************************************************************
Vczh Library++ 3.0
Developer: Zihan Chen(vczh)
Parser::ParsingJson_Parser

***********************************************************************/

#ifndef VCZH_PARSING_JSON_PARSINGJSON
#define VCZH_PARSING_JSON_PARSINGJSON


namespace vl
{
	namespace parsing
	{
		namespace json
		{
			extern void						JsonEscapeString(const WString& text, stream::TextWriter& writer);
			extern void						JsonUnescapeString(const WString& text, stream::TextWriter& writer);

			/// <summary>Serialize JSON to string.</summary>
			/// <param name="node">The JSON node to serialize.</param>
			/// <param name="writer">The text writer to receive the string.</param>
			extern void						JsonPrint(Ptr<JsonNode> node, stream::TextWriter& writer);

			/// <summary>Serialize JSON to string.</summary>
			/// <returns>The serialized string.</returns>
			/// <param name="node">The JSON node to serialize.</param>
			extern WString					JsonToString(Ptr<JsonNode> node);
		}
	}
}

#endif

/***********************************************************************
.\XML\PARSINGXML_AST.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:ParsingXml.parser.txt
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSING_XML_PARSINGXML_PARSER_AST
#define VCZH_PARSING_XML_PARSINGXML_PARSER_AST


namespace vl
{
	namespace parsing
	{
		namespace xml
		{
			/// <summary>Token types. Values of enum items will be used in <see cref="vl::regex::RegexToken::token"/>.</summary>
			enum class XmlParserTokenIndex
			{
				/// <summary>Token INSTRUCTION_OPEN: /&lt;/?</summary>
				INSTRUCTION_OPEN = 0,
				/// <summary>Token INSTRUCTION_CLOSE: /?/&gt;</summary>
				INSTRUCTION_CLOSE = 1,
				/// <summary>Token COMPLEX_ELEMENT_OPEN: /&lt;//</summary>
				COMPLEX_ELEMENT_OPEN = 2,
				/// <summary>Token SINGLE_ELEMENT_CLOSE: ///&gt;</summary>
				SINGLE_ELEMENT_CLOSE = 3,
				/// <summary>Token ELEMENT_OPEN: /&lt;</summary>
				ELEMENT_OPEN = 4,
				/// <summary>Token ELEMENT_CLOSE: /&gt;</summary>
				ELEMENT_CLOSE = 5,
				/// <summary>Token EQUAL: /=</summary>
				EQUAL = 6,
				/// <summary>Token NAME: [a-zA-Z0-9:._/-]+</summary>
				NAME = 7,
				/// <summary>Token ATTVALUE: &quot;[^&lt;&gt;&quot;]*&quot;|&apos;[^&lt;&gt;&apos;]*&apos;</summary>
				ATTVALUE = 8,
				/// <summary>Token COMMENT: /&lt;/!--([^/-&gt;]|-[^/-&gt;]|--[^&gt;])*--/&gt;</summary>
				COMMENT = 9,
				/// <summary>Token CDATA: /&lt;/!/[CDATA/[([^/]]|/][^/]]|/]/][^&gt;])*/]/]/&gt;</summary>
				CDATA = 10,
				/// <summary>Token TEXT: ([^&lt;&gt;=&quot;&apos; /r/n/ta-zA-Z0-9:._/-])+|&quot;|&apos;</summary>
				TEXT = 11,
				/// <summary>Discardable token SPACE: /s+</summary>
				SPACE = 12,
			};
			class XmlNode;
			class XmlText;
			class XmlCData;
			class XmlAttribute;
			class XmlComment;
			class XmlElement;
			class XmlInstruction;
			class XmlDocument;

			/// <summary>Base class of XML nodes.</summary>
			class XmlNode abstract : public vl::parsing::ParsingTreeCustomBase, vl::reflection::Description<XmlNode>
			{
			public:
				/// <summary>Visitor interface for <see cref="XmlNode"/>.</summary>
				class IVisitor : public vl::reflection::IDescriptable, vl::reflection::Description<IVisitor>
				{
				public:
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="XmlText"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(XmlText* node)=0;
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="XmlCData"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(XmlCData* node)=0;
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="XmlAttribute"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(XmlAttribute* node)=0;
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="XmlComment"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(XmlComment* node)=0;
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="XmlElement"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(XmlElement* node)=0;
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="XmlInstruction"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(XmlInstruction* node)=0;
					/// <summary>A callback that is called if the node accepting this visitor is <see cref="XmlDocument"/>.</summary>
					/// <param name="node">The strong-typed AST node in its real type.</param>
					virtual void Visit(XmlDocument* node)=0;
				};

				/// <summary>Accept a visitor to reveal its real type of this strong-typed AST node.</summary>
				/// <param name="visitor">The visitor, one of its <b>Visit</b> method will be called according to the real type of this strong-typed AST node.</param>
				virtual void Accept(XmlNode::IVisitor* visitor)=0;

			};

			/// <summary>Text node.</summary>
			class XmlText : public XmlNode, vl::reflection::Description<XmlText>
			{
			public:
				/// <summary>Content of the text node.</summary>
				vl::parsing::ParsingToken content;

				void Accept(XmlNode::IVisitor* visitor)override;

				static vl::Ptr<XmlText> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

			/// <summary>CData node.</summary>
			class XmlCData : public XmlNode, vl::reflection::Description<XmlCData>
			{
			public:
				/// <summary>Content of the cdata node</summary>
				vl::parsing::ParsingToken content;

				void Accept(XmlNode::IVisitor* visitor)override;

				static vl::Ptr<XmlCData> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

			/// <summary>Attribute node.</summary>
			class XmlAttribute : public XmlNode, vl::reflection::Description<XmlAttribute>
			{
			public:
				/// <summary>Attribute name.</summary>
				vl::parsing::ParsingToken name;
				/// <summary>Attribute value.</summary>
				vl::parsing::ParsingToken value;

				void Accept(XmlNode::IVisitor* visitor)override;

				static vl::Ptr<XmlAttribute> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

			/// <summary>Comment node.</summary>
			class XmlComment : public XmlNode, vl::reflection::Description<XmlComment>
			{
			public:
				/// <summary>Content of the comment node.</summary>
				vl::parsing::ParsingToken content;

				void Accept(XmlNode::IVisitor* visitor)override;

				static vl::Ptr<XmlComment> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

			/// <summary>Element node.</summary>
			class XmlElement : public XmlNode, vl::reflection::Description<XmlElement>
			{
			public:
				/// <summary>Element name of the open element node.</summary>
				vl::parsing::ParsingToken name;
				/// <summary>(Optional): Element name of the closing element node. The name is ignored when serializing XML to text.</summary>
				vl::parsing::ParsingToken closingName;
				/// <summary>Attributes of the element.</summary>
				vl::collections::List<vl::Ptr<XmlAttribute>> attributes;
				/// <summary>Sub nodes for element nodes, text nodes, cdata nodes and comment nodes.</summary>
				vl::collections::List<vl::Ptr<XmlNode>> subNodes;

				void Accept(XmlNode::IVisitor* visitor)override;

				static vl::Ptr<XmlElement> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

			/// <summary>Instruction node.</summary>
			class XmlInstruction : public XmlNode, vl::reflection::Description<XmlInstruction>
			{
			public:
				/// <summary>Name of the instruction.</summary>
				vl::parsing::ParsingToken name;
				/// <summary>Attributes of the instruction.</summary>
				vl::collections::List<vl::Ptr<XmlAttribute>> attributes;

				void Accept(XmlNode::IVisitor* visitor)override;

				static vl::Ptr<XmlInstruction> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

			/// <summary>XML document node.</summary>
			class XmlDocument : public XmlNode, vl::reflection::Description<XmlDocument>
			{
			public:
				/// <summary>Prologue nodes, for instructions and comments.</summary>
				vl::collections::List<vl::Ptr<XmlNode>> prologs;
				/// <summary>Root element of the XML document.</summary>
				vl::Ptr<XmlElement> rootElement;

				void Accept(XmlNode::IVisitor* visitor)override;

				static vl::Ptr<XmlDocument> Convert(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			};

		}
	}
}
namespace vl
{
	namespace reflection
	{
		namespace description
		{
#ifndef VCZH_DEBUG_NO_REFLECTION
			DECL_TYPE_INFO(vl::parsing::xml::XmlNode)
			DECL_TYPE_INFO(vl::parsing::xml::XmlText)
			DECL_TYPE_INFO(vl::parsing::xml::XmlCData)
			DECL_TYPE_INFO(vl::parsing::xml::XmlAttribute)
			DECL_TYPE_INFO(vl::parsing::xml::XmlComment)
			DECL_TYPE_INFO(vl::parsing::xml::XmlElement)
			DECL_TYPE_INFO(vl::parsing::xml::XmlInstruction)
			DECL_TYPE_INFO(vl::parsing::xml::XmlDocument)
			DECL_TYPE_INFO(vl::parsing::xml::XmlNode::IVisitor)

#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA

			BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::parsing::xml::XmlNode::IVisitor)
				void Visit(vl::parsing::xml::XmlText* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

				void Visit(vl::parsing::xml::XmlCData* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

				void Visit(vl::parsing::xml::XmlAttribute* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

				void Visit(vl::parsing::xml::XmlComment* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

				void Visit(vl::parsing::xml::XmlElement* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

				void Visit(vl::parsing::xml::XmlInstruction* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

				void Visit(vl::parsing::xml::XmlDocument* node)override
				{
					INVOKE_INTERFACE_PROXY(Visit, node);
				}

			END_INTERFACE_PROXY(vl::parsing::xml::XmlNode::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 XmlLoadTypes();
		}
	}
}
#endif

/***********************************************************************
.\XML\PARSINGXML_PARSER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:ParsingXml.parser.txt
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/

#ifndef VCZH_PARSING_XML_PARSINGXML_PARSER_PARSER
#define VCZH_PARSING_XML_PARSINGXML_PARSER_PARSER


namespace vl
{
	namespace parsing
	{
		namespace xml
		{
			/// <summary>Get the grammar definition for this parser.</summary>
			/// <returns>The grammar definition for this parser.</returns>
			extern vl::WString XmlGetParserTextBuffer();
			/// <summary>Convert parser result to a strong typed AST node. Usually you don't need to use this function, unless you are doing meta programming like error recovering or implementing intellisense for an editor.</summary>
			/// <returns>Returns the strong typed AST node.</returns>
			/// <param name="node">The parser result.</param>
			/// <param name="tokens">Tokens for parsing. You can get the <see cref="vl::regex::RegexLexer"/> by calling <see cref="vl::parsing::tabling::ParsingTable::GetLexer"/> from <see cref="XmlLoadTable"/></param>
			extern vl::Ptr<vl::parsing::ParsingTreeCustomBase> XmlConvertParsingTreeNode(vl::Ptr<vl::parsing::ParsingTreeNode> node, const vl::collections::List<vl::regex::RegexToken>& tokens);
			/// <summary>Create the parser table. You should cache the value if possible, for improving performance.</summary>
			/// <returns>The created parser table.</returns>
			extern vl::Ptr<vl::parsing::tabling::ParsingTable> XmlLoadTable();

			/// <summary>Parse an XML document.</summary>
			/// <returns>Returns the parsing result as a weak-typed AST node. Returns null if there is any unrecoverable error during parsing.</returns>
			/// <param name="input">The input for parsing.</param>
			/// <param name="table">The return value from <see cref="XmlLoadTable"/>.</param>
			/// <param name="errors">All errors during parsing.</param>
			/// <param name="codeIndex">(Optional): This argument will be copied to <see cref="vl::parsing::ParsingTextRange::codeIndex"/> in every AST nodes. The default value is -1.</param>
			extern vl::Ptr<vl::parsing::ParsingTreeNode> XmlParseDocumentAsParsingTreeNode(const vl::WString& input, vl::Ptr<vl::parsing::tabling::ParsingTable> table, vl::collections::List<vl::Ptr<vl::parsing::ParsingError>>& errors, vl::vint codeIndex = -1);
			/// <summary>Parse an XML document.</summary>
			/// <returns>Returns the parsing result as a weak-typed AST node. Returns null if there is any unrecoverable error during parsing.</returns>
			/// <param name="input">The input for parsing.</param>
			/// <param name="table">The return value from <see cref="XmlLoadTable"/>.</param>
			/// <param name="codeIndex">(Optional): This argument will be copied to <see cref="vl::parsing::ParsingTextRange::codeIndex"/> in every AST nodes. The default value is -1.</param>
			extern vl::Ptr<vl::parsing::ParsingTreeNode> XmlParseDocumentAsParsingTreeNode(const vl::WString& input, vl::Ptr<vl::parsing::tabling::ParsingTable> table, vl::vint codeIndex = -1);
			/// <summary>Parse an XML document.</summary>
			/// <returns>Returns the parsing result as a strong-typed AST node. Returns null if there is any unrecoverable error during parsing.</returns>
			/// <param name="input">The input for parsing.</param>
			/// <param name="table">The return value from <see cref="XmlLoadTable"/>.</param>
			/// <param name="errors">All errors during parsing.</param>
			/// <param name="codeIndex">(Optional): This argument will be copied to <see cref="vl::parsing::ParsingTextRange::codeIndex"/> in every AST nodes. The default value is -1.</param>
			extern vl::Ptr<XmlDocument> XmlParseDocument(const vl::WString& input, vl::Ptr<vl::parsing::tabling::ParsingTable> table, vl::collections::List<vl::Ptr<vl::parsing::ParsingError>>& errors, vl::vint codeIndex = -1);
			/// <summary>Parse an XML document.</summary>
			/// <returns>Returns the parsing result as a strong-typed AST node. Returns null if there is any unrecoverable error during parsing.</returns>
			/// <param name="input">The input for parsing.</param>
			/// <param name="table">The return value from <see cref="XmlLoadTable"/>.</param>
			/// <param name="codeIndex">(Optional): This argument will be copied to <see cref="vl::parsing::ParsingTextRange::codeIndex"/> in every AST nodes. The default value is -1.</param>
			extern vl::Ptr<XmlDocument> XmlParseDocument(const vl::WString& input, vl::Ptr<vl::parsing::tabling::ParsingTable> table, vl::vint codeIndex = -1);

			/// <summary>Parse an XML element.</summary>
			/// <returns>Returns the parsing result as a weak-typed AST node. Returns null if there is any unrecoverable error during parsing.</returns>
			/// <param name="input">The input for parsing.</param>
			/// <param name="table">The return value from <see cref="XmlLoadTable"/>.</param>
			/// <param name="errors">All errors during parsing.</param>
			/// <param name="codeIndex">(Optional): This argument will be copied to <see cref="vl::parsing::ParsingTextRange::codeIndex"/> in every AST nodes. The default value is -1.</param>
			extern vl::Ptr<vl::parsing::ParsingTreeNode> XmlParseElementAsParsingTreeNode(const vl::WString& input, vl::Ptr<vl::parsing::tabling::ParsingTable> table, vl::collections::List<vl::Ptr<vl::parsing::ParsingError>>& errors, vl::vint codeIndex = -1);
			/// <summary>Parse an XML element.</summary>
			/// <returns>Returns the parsing result as a weak-typed AST node. Returns null if there is any unrecoverable error during parsing.</returns>
			/// <param name="input">The input for parsing.</param>
			/// <param name="table">The return value from <see cref="XmlLoadTable"/>.</param>
			/// <param name="codeIndex">(Optional): This argument will be copied to <see cref="vl::parsing::ParsingTextRange::codeIndex"/> in every AST nodes. The default value is -1.</param>
			extern vl::Ptr<vl::parsing::ParsingTreeNode> XmlParseElementAsParsingTreeNode(const vl::WString& input, vl::Ptr<vl::parsing::tabling::ParsingTable> table, vl::vint codeIndex = -1);
			/// <summary>Parse an XML element.</summary>
			/// <returns>Returns the parsing result as a strong-typed AST node. Returns null if there is any unrecoverable error during parsing.</returns>
			/// <param name="input">The input for parsing.</param>
			/// <param name="table">The return value from <see cref="XmlLoadTable"/>.</param>
			/// <param name="errors">All errors during parsing.</param>
			/// <param name="codeIndex">(Optional): This argument will be copied to <see cref="vl::parsing::ParsingTextRange::codeIndex"/> in every AST nodes. The default value is -1.</param>
			extern vl::Ptr<XmlElement> XmlParseElement(const vl::WString& input, vl::Ptr<vl::parsing::tabling::ParsingTable> table, vl::collections::List<vl::Ptr<vl::parsing::ParsingError>>& errors, vl::vint codeIndex = -1);
			/// <summary>Parse an XML element.</summary>
			/// <returns>Returns the parsing result as a strong-typed AST node. Returns null if there is any unrecoverable error during parsing.</returns>
			/// <param name="input">The input for parsing.</param>
			/// <param name="table">The return value from <see cref="XmlLoadTable"/>.</param>
			/// <param name="codeIndex">(Optional): This argument will be copied to <see cref="vl::parsing::ParsingTextRange::codeIndex"/> in every AST nodes. The default value is -1.</param>
			extern vl::Ptr<XmlElement> XmlParseElement(const vl::WString& input, vl::Ptr<vl::parsing::tabling::ParsingTable> table, vl::vint codeIndex = -1);
		}
	}
}
#endif

/***********************************************************************
.\XML\PARSINGXML.H
***********************************************************************/
/***********************************************************************
Vczh Library++ 3.0
Developer: Zihan Chen(vczh)
Parser::ParsingXml

***********************************************************************/

#ifndef VCZH_PARSING_XML_PARSINGXML
#define VCZH_PARSING_XML_PARSINGXML


namespace vl
{
	namespace parsing
	{
		namespace xml
		{
			extern WString							XmlEscapeValue(const WString& value);
			extern WString							XmlUnescapeValue(const WString& value);
			extern WString							XmlEscapeCData(const WString& value);
			extern WString							XmlUnescapeCData(const WString& value);
			extern WString							XmlEscapeComment(const WString& value);
			extern WString							XmlUnescapeComment(const WString& value);

			/// <summary>Serialize XML to string.</summary>
			/// <param name="node">The XML node to serialize.</param>
			/// <param name="writer">The text writer to receive the string.</param>
			extern void								XmlPrint(Ptr<XmlNode> node, stream::TextWriter& writer);

			/// <summary>Serialize sub nodes in an XML element to string.</summary>
			/// <param name="element">The XML element in which sub nodes are to be serialized.</param>
			/// <param name="writer">The text writer to receive the string.</param>
			extern void								XmlPrintContent(Ptr<XmlElement> element, stream::TextWriter& writer);

			/// <summary>Serialize XML to string.</summary>
			/// <returns>The serialized string.</returns>
			/// <param name="node">The XML node to serialize.</param>
			extern WString							XmlToString(Ptr<XmlNode> node);

			/// <summary>Try to read an attribute in an XML element.</summary>
			/// <returns>The expected attribute. Returns null if it doesn't exist.</returns>
			/// <param name="element">The element to find the attribute.</param>
			/// <param name="name">The name of the attribute.</param>
			extern Ptr<XmlAttribute>							XmlGetAttribute(Ptr<XmlElement> element, const WString& name);

			/// <summary>Try to read a sub element in an XML element.</summary>
			/// <returns>The expected sub element. Returns null if it doesn't exist. If there are multiple elements of the expected name, returns the first one.</returns>
			/// <param name="element">The element to find the sub element.</param>
			/// <param name="name">The name of the sub element.</param>
			extern Ptr<XmlElement>								XmlGetElement(Ptr<XmlElement> element, const WString& name);

			/// <summary>Get all sub elements in an XML element.</summary>
			/// <returns>All sub elements in an XML element.</returns>
			/// <param name="element">The container XML element.</param>
			extern collections::LazyList<Ptr<XmlElement>>		XmlGetElements(Ptr<XmlElement> element);

			/// <summary>Try to read sub elements in an XML element.</summary>
			/// <returns>Expected sub elements. All sub elements of the expected name will be returned.</returns>
			/// <param name="element">The element to find sub elements.</param>
			/// <param name="name">The name of sub elements.</param>
			extern collections::LazyList<Ptr<XmlElement>>		XmlGetElements(Ptr<XmlElement> element, const WString& name);

			/// <summary>Serialize contents in an XML element.</summary>
			/// <returns>The serialized contents in an XML element.</returns>
			/// <param name="element">The XML element in which contents are to be serialized.</param>
			extern WString										XmlGetValue(Ptr<XmlElement> element);

			extern Ptr<XmlAttribute>							XmlGetAttribute(XmlElement* element, const WString& name);
			extern Ptr<XmlElement>								XmlGetElement(XmlElement* element, const WString& name);
			extern collections::LazyList<Ptr<XmlElement>>		XmlGetElements(XmlElement* element);
			extern collections::LazyList<Ptr<XmlElement>>		XmlGetElements(XmlElement* element, const WString& name);
			extern WString										XmlGetValue(XmlElement* element);

			class XmlElementWriter : public Object
			{
			protected:
				Ptr<XmlElement>					element;
				const XmlElementWriter*			previousWriter;

			public:
				XmlElementWriter(Ptr<XmlElement> _element, const XmlElementWriter* _previousWriter=0);
				~XmlElementWriter();

				const XmlElementWriter&			Attribute(const WString& name, const WString& value)const;
				XmlElementWriter				Element(const WString& name)const;
				const XmlElementWriter&			End()const;
				const XmlElementWriter&			Text(const WString& value)const;
				const XmlElementWriter&			CData(const WString& value)const;
				const XmlElementWriter&			Comment(const WString& value)const;
			};
		}
	}
}

#endif
