Files
GacUI/Import/VlppGlrParser.h
2021-12-27 00:13:55 -08:00

2820 lines
95 KiB
C++

/***********************************************************************
THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY
DEVELOPER: Zihan Chen(vczh)
***********************************************************************/
#include "VlppReflection.h"
#include "VlppOS.h"
#include "Vlpp.h"
#include "VlppRegex.h"
/***********************************************************************
.\ASTBASE.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_ASTBASE
#define VCZH_PARSER2_ASTBASE
namespace vl
{
namespace glr
{
/***********************************************************************
ParsingTextPos
***********************************************************************/
/// <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;
}
static ParsingTextPos Start(const regex::RegexToken* token)
{
return { token->start,token->rowStart,token->columnStart };
}
static ParsingTextPos End(const regex::RegexToken* token)
{
return { token->start + token->length - 1,token->rowEnd,token->columnEnd };
}
static vint Compare(const ParsingTextPos& a, const ParsingTextPos& b)
{
if (a.IsInvalid() && b.IsInvalid())
{
return 0;
}
else if (a.IsInvalid())
{
return -1;
}
else if (b.IsInvalid())
{
return 1;
}
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 0;
}
}
bool operator==(const ParsingTextPos& pos)const { return Compare(*this, pos) == 0; }
bool operator!=(const ParsingTextPos& pos)const { return Compare(*this, pos) != 0; }
bool operator<(const ParsingTextPos& pos)const { return Compare(*this, pos) < 0; }
bool operator<=(const ParsingTextPos& pos)const { return Compare(*this, pos) <= 0; }
bool operator>(const ParsingTextPos& pos)const { return Compare(*this, pos) > 0; }
bool operator>=(const ParsingTextPos& pos)const { return Compare(*this, pos) >= 0; }
};
/***********************************************************************
ParsingTextRange
***********************************************************************/
/// <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 = -1;
ParsingTextRange() = default;
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)
: start(ParsingTextPos::Start(startToken))
, end(ParsingTextPos::End(endToken))
, codeIndex(startToken->codeIndex)
{
}
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; }
};
/***********************************************************************
ParsingError
***********************************************************************/
class ParsingAstBase;
struct ParsingError
{
ParsingAstBase* node = nullptr;
ParsingTextRange codeRange;
WString message;
};
/***********************************************************************
AST
***********************************************************************/
/// <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.</summary>
class ParsingAstBase : public Object, public reflection::Description<ParsingAstBase>
{
public:
/// <summary>Range of all tokens that form this object.</summary>
ParsingTextRange codeRange;
};
/// <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>
struct ParsingToken
{
public:
/// <summary>Range of all tokens that form this object.</summary>
ParsingTextRange codeRange;
/// <summary>Index of the token in the token list provided to the parser.</summary>
vint index = -1;
/// <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 token = -1;
/// <summary>Content of the token.</summary>
WString value;
operator bool() const { return value.Length() > 0; }
};
/***********************************************************************
AST (Builder)
***********************************************************************/
template<typename TAst>
class ParsingAstBuilder
{
protected:
Ptr<TAst> node = MakePtr<TAst>();
ParsingAstBuilder() {}
public:
template<typename TExpected>
operator Ptr<TExpected>() const
{
return node;
}
};
/***********************************************************************
AST (Visitor)
***********************************************************************/
class CopyVisitorBase : public Object
{
protected:
Ptr<ParsingAstBase> result;
};
class JsonVisitorBase : public Object
{
private:
stream::StreamWriter& writer;
vint indentation = 0;
collections::List<vint> indices;
protected:
void BeginObject();
void BeginField(const WString& field);
void EndField();
void EndObject();
void BeginArray();
void BeginArrayItem();
void EndArrayItem();
void EndArray();
void WriteIndent();
void WriteRange(const ParsingTextRange& range);
void WriteToken(const ParsingToken& token);
void WriteType(const WString& type, ParsingAstBase* node);
void WriteString(const WString& text);
void WriteNull();
public:
bool printTokenCodeRange = true;
bool printAstCodeRange = true;
bool printAstType = true;
JsonVisitorBase(stream::StreamWriter& _writer);
};
extern void JsonEscapeString(const WString& text, stream::TextWriter& writer);
extern void JsonUnescapeString(const WString& text, stream::TextWriter& writer);
/***********************************************************************
Instructions
***********************************************************************/
enum class AstInsType
{
Token, // Token() : Push the current token as a value.
EnumItem, // EnumItem(Value) : Push an enum item.
BeginObject, // BeginObject(Type) : Begin creating an AST node.
BeginObjectLeftRecursive, // BeginObjectLeftRecursive(Type) : Begin creating an AST node, taking the ownership of the last pushed object.
DelayFieldAssignment, // DelayFieldAssignment() : An object will be created later by ReopenObject, delay future field assignments to this object before ReopenObject.
ReopenObject, // ReopenObject() : Move the last pushed object back to creating status.
EndObject, // EndObject() : Finish creating an AST node, all objects pushed after BeginObject are supposed to be its fields.
DiscardValue, // DiscardValue() : Remove a pushed value.
Field, // Field(Field) : Associate a field name with the top object.
ResolveAmbiguity, // ResolveAmbiguity(Type, Count) : Combine several top objects to one using an ambiguity node. Type is the type of each top object.
AccumulatedDfa, // AccumulatedDfa(Count) : Multiple DelayFieldAssignment
AccumulatedEoRo, // AccumulatedEoRo(Count) : Multiple EndObject + ReopenObject
};
struct AstIns
{
AstInsType type = AstInsType::Token;
vint32_t param = -1;
vint count = -1;
vint Compare(const AstIns& ins) const
{
auto result = (vint)type - (vint)ins.type;
if (result != 0) return result;
result = (vint)param - (vint)ins.param;
if (result != 0) return result;
return count - ins.count;
}
bool operator==(const AstIns& ins) const { return Compare(ins) == 0; }
bool operator!=(const AstIns& ins) const { return Compare(ins) != 0; }
bool operator< (const AstIns& ins) const { return Compare(ins) < 0; }
bool operator<=(const AstIns& ins) const { return Compare(ins) <= 0; }
bool operator> (const AstIns& ins) const { return Compare(ins) > 0; }
bool operator>=(const AstIns& ins) const { return Compare(ins) >= 0; }
};
enum class AstInsErrorType
{
UnknownType, // UnknownType(Type) : The type id does not exist.
UnknownField, // UnknownField(Field) : The field id does not exist.
UnsupportedAbstractType, // UnsupportedAbstractType(Type) : Unable to create abstract class.
UnsupportedAmbiguityType, // UnsupportedAmbiguityType(Type) : The type is not configured to allow ambiguity.
UnexpectedAmbiguousCandidate, // UnexpectedAmbiguousCandidate(Type) : The type of the ambiguous candidate is not compatible to the required type.
FieldNotExistsInType, // FieldNotExistsInType(Field) : The type doesn't have such field.
FieldReassigned, // FieldReassigned(Field) : An object is assigned to a field but this field has already been assigned.
ObjectTypeMismatchedToField, // ObjectTypeMismatchedToField(Field) : Unable to assign an object to a field because the type does not match.
NoRootObject, // NoRootObject() : There is no created objects.
NoRootObjectAfterDfa, // NoRootObjectAfterDfa() : There is no created objects after DelayFieldAssignment.
MissingLeftRecursiveValue, // MissingLeftRecursiveValue() : There is no pushed value to create left recursive object.
LeftRecursiveValueIsNotObject, // LeftRecursiveValueIsNotObject() : The pushed value to create left recursive object is not an object.
TooManyUnassignedValues, // LeavingUnassignedValues() : The value to reopen is not the only unassigned value.
MissingDfaBeforeReopen, // MissingDfaBeforeReopen() : DelayFieldAssignment is not submitted before ReopenObject.
MissingValueToReopen, // MissingValueToReopen() : There is no pushed value to reopen.
ReopenedValueIsNotObject, // ReopenedValueIsNotObject() : The pushed value to reopen is not an object.
MissingValueToDiscard, // MissingValueToDiscard() : There is no pushed value to discard.
LeavingUnassignedValues, // LeavingUnassignedValues() : There are still values to assign to fields before finishing an object.
MissingFieldValue, // MissingFieldValue() : There is no pushed value to be assigned to a field.
MissingAmbiguityCandidate, // MissingAmbiguityCandidate() : There are not enough candidates to create an ambiguity node.
AmbiguityCandidateIsNotObject, // AmbiguityCandidateIsNotObject() : Tokens or enum items cannot be ambiguity candidates.
InstructionNotComplete, // InstructionNotComplete() : No more instruction but the root object has not been completed yet.
Corrupted, // Corrupted() : An exception has been thrown therefore this receiver cannot be used anymore.
Finished, // Finished() : The finished instruction has been executed therefore this receiver cannot be used anymore.
};
class AstInsException : public Exception
{
public:
AstInsErrorType error = AstInsErrorType::Corrupted;
vint32_t paramTypeOrField = -1;
AstInsException(const WString& message, AstInsErrorType _error, vint32_t _typeOrField = -1)
: Exception(message)
, error(_error)
, paramTypeOrField(_typeOrField)
{
}
};
/***********************************************************************
IAstInsReceiver
***********************************************************************/
class IAstInsReceiver : public virtual Interface
{
public:
virtual void Execute(AstIns instruction, const regex::RegexToken& token, vint32_t tokenIndex) = 0;
virtual Ptr<ParsingAstBase> Finished() = 0;
};
class AstInsReceiverBase : public Object, public virtual IAstInsReceiver
{
private:
struct ObjectOrToken
{
Ptr<ParsingAstBase> object;
vint32_t enumItem = -1;
regex::RegexToken token = {};
vint32_t tokenIndex = -1;
explicit ObjectOrToken(Ptr<ParsingAstBase> _object) : object(_object) {}
explicit ObjectOrToken(vint32_t _enumItem) : enumItem(_enumItem) {}
explicit ObjectOrToken(const regex::RegexToken& _token, vint32_t _tokenIndex) : token(_token), tokenIndex(_tokenIndex) {}
};
struct FieldAssignment
{
ObjectOrToken value;
vint32_t field;
};
struct CreatedObject
{
Ptr<ParsingAstBase> object;
vint pushedCount;
regex::RegexToken delayedToken;
collections::List<FieldAssignment> delayedFieldAssignments;
vint extraEmptyDfaBelow = 0;
CreatedObject(Ptr<ParsingAstBase> _object, vint _pushedCount)
: object(_object)
, pushedCount(_pushedCount)
{
}
CreatedObject(Ptr<ParsingAstBase> _object, vint _pushedCount, const regex::RegexToken& _delayedToken)
: object(_object)
, pushedCount(_pushedCount)
, delayedToken(_delayedToken)
{
}
};
collections::List<CreatedObject> created;
collections::List<ObjectOrToken> pushed;
bool finished = false;
bool corrupted = false;
void EnsureContinuable();
void SetField(ParsingAstBase* object, vint32_t field, const ObjectOrToken& value);
CreatedObject& PushCreated(CreatedObject&& createdObject);
const CreatedObject& TopCreated();
void PopCreated();
void DelayAssign(FieldAssignment&& fa);
protected:
virtual Ptr<ParsingAstBase> CreateAstNode(vint32_t type) = 0;
virtual void SetField(ParsingAstBase* object, vint32_t field, Ptr<ParsingAstBase> value) = 0;
virtual void SetField(ParsingAstBase* object, vint32_t field, const regex::RegexToken& token, vint32_t tokenIndex) = 0;
virtual void SetField(ParsingAstBase* object, vint32_t field, vint32_t enumValue) = 0;
virtual Ptr<ParsingAstBase> ResolveAmbiguity(vint32_t type, collections::Array<Ptr<ParsingAstBase>>& candidates) = 0;
public:
AstInsReceiverBase() = default;
~AstInsReceiverBase() = default;
void Execute(AstIns instruction, const regex::RegexToken& token, vint32_t tokenIndex) override;
Ptr<ParsingAstBase> Finished() override;
};
/***********************************************************************
IAstInsReceiver (Code Generation Templates)
***********************************************************************/
template<typename TClass, typename TField>
void AssemblerSetObjectField(Ptr<TField>(TClass::* member), ParsingAstBase* object, vint32_t field, Ptr<ParsingAstBase> value, const wchar_t* cppFieldName)
{
auto typedObject = dynamic_cast<TClass*>(object);
if (!typedObject)
{
throw AstInsException(
WString::Unmanaged(L"Field \"") +
WString::Unmanaged(cppFieldName) +
WString::Unmanaged(L"\" does not exist in the current object."),
AstInsErrorType::FieldNotExistsInType, field);
}
if ((typedObject->*member))
{
throw AstInsException(
WString::Unmanaged(L"Field \"") +
WString::Unmanaged(cppFieldName) +
WString::Unmanaged(L"\" has already been assigned."),
AstInsErrorType::FieldReassigned, field);
}
auto typedValue = value.Cast<TField>();
if (!typedValue)
{
throw AstInsException(
WString::Unmanaged(L"Field \"") +
WString::Unmanaged(cppFieldName) +
WString::Unmanaged(L"\" cannot be assigned with an uncompatible value."),
AstInsErrorType::ObjectTypeMismatchedToField, field);
}
(typedObject->*member) = typedValue;
}
template<typename TClass, typename TField>
void AssemblerSetObjectField(collections::List<Ptr<TField>>(TClass::* member), ParsingAstBase* object, vint32_t field, Ptr<ParsingAstBase> value, const wchar_t* cppFieldName)
{
auto typedObject = dynamic_cast<TClass*>(object);
if (!typedObject)
{
throw AstInsException(
WString::Unmanaged(L"Field \"") +
WString::Unmanaged(cppFieldName) +
WString::Unmanaged(L"\" does not exist in the current object."),
AstInsErrorType::FieldNotExistsInType, field);
}
auto typedValue = value.Cast<TField>();
if (!typedValue)
{
throw AstInsException(
WString::Unmanaged(L"Field \"") +
WString::Unmanaged(cppFieldName) +
WString::Unmanaged(L"\" cannot be assigned with an uncompatible value."),
AstInsErrorType::ObjectTypeMismatchedToField, field);
}
(typedObject->*member).Add(typedValue);
}
template<typename TClass>
void AssemblerSetTokenField(ParsingToken(TClass::* member), ParsingAstBase* object, vint32_t field, const regex::RegexToken& token, vint32_t tokenIndex, const wchar_t* cppFieldName)
{
auto typedObject = dynamic_cast<TClass*>(object);
if (!typedObject)
{
throw AstInsException(
WString::Unmanaged(L"Field \"") +
WString::Unmanaged(cppFieldName) +
WString::Unmanaged(L"\" does not exist in the current object."),
AstInsErrorType::FieldNotExistsInType, field);
}
if ((typedObject->*member).value.Length() != 0)
{
throw AstInsException(
WString::Unmanaged(L"Field \"") +
WString::Unmanaged(cppFieldName) +
WString::Unmanaged(L"\" has already been assigned."),
AstInsErrorType::FieldReassigned, field);
}
ParsingToken& tokenField = typedObject->*member;
tokenField.codeRange = { &token,&token };
tokenField.index = tokenIndex;
tokenField.token = token.token;
tokenField.value = WString::CopyFrom(token.reading, token.length);
}
template<typename TClass, typename TField>
void AssemblerSetEnumField(TField(TClass::* member), ParsingAstBase* object, vint32_t field, vint32_t enumItem, const wchar_t* cppFieldName)
{
auto typedObject = dynamic_cast<TClass*>(object);
if (!typedObject)
{
throw AstInsException(
WString::Unmanaged(L"Field \"") +
WString::Unmanaged(cppFieldName) +
WString::Unmanaged(L"\" does not exist in the current object."),
AstInsErrorType::FieldNotExistsInType, field);
}
if ((typedObject->*member) != TField::UNDEFINED_ENUM_ITEM_VALUE)
{
throw AstInsException(
WString::Unmanaged(L"Field \"") +
WString::Unmanaged(cppFieldName) +
WString::Unmanaged(L"\" has already been assigned."),
AstInsErrorType::FieldReassigned, field);
}
(typedObject->*member) = (TField)enumItem;
}
template<typename TElement, typename TAmbiguity>
Ptr<ParsingAstBase> AssemblerResolveAmbiguity(vint32_t type, collections::Array<Ptr<ParsingAstBase>>& candidates, const wchar_t* cppTypeName)
{
Ptr<TAmbiguity> ast = new TAmbiguity();
for (auto candidate : candidates)
{
if (auto typedAst = candidate.Cast<TElement>())
{
ast->candidates.Add(typedAst);
}
else if (auto ambiguityAst = candidate.Cast<TAmbiguity>())
{
CopyFrom(ast->candidates, ambiguityAst->candidates, true);
}
else
{
throw AstInsException(
WString::Unmanaged(L"The type of the ambiguous candidate is not compatible to the required type \"") +
WString::Unmanaged(cppTypeName) +
WString::Unmanaged(L"\"."),
AstInsErrorType::UnexpectedAmbiguousCandidate, type);
}
}
return ast;
}
template<vint32_t Size>
vint32_t AssemblerFindCommonBaseClass(vint32_t class1, vint32_t class2, vint32_t(&matrix)[Size][Size])
{
if (class1 < 0 || class1 >= Size) throw glr::AstInsException(L"The type id does not exist.", glr::AstInsErrorType::UnknownType, class1);
if (class2 < 0 || class2 >= Size) throw glr::AstInsException(L"The type id does not exist.", glr::AstInsErrorType::UnknownType, class2);
return matrix[class1][class2];
}
/***********************************************************************
IAstInsReceiver (Code Generation Error Templates)
***********************************************************************/
extern Ptr<ParsingAstBase> AssemblyThrowCannotCreateAbstractType(vint32_t type, const wchar_t* cppTypeName);
extern void AssemblyThrowFieldNotObject(vint32_t field, const wchar_t* cppFieldName);
extern void AssemblyThrowFieldNotToken(vint32_t field, const wchar_t* cppFieldName);
extern void AssemblyThrowFieldNotEnum(vint32_t field, const wchar_t* cppFieldName);
extern Ptr<ParsingAstBase> AssemblyThrowTypeNotAllowAmbiguity(vint32_t type, const wchar_t* cppTypeName);
/***********************************************************************
Compression
***********************************************************************/
extern void DecompressSerializedData(const char** buffer, bool decompress, vint solidRows, vint rows, vint block, vint remain, stream::IStream& outputStream);
}
/***********************************************************************
Reflection
***********************************************************************/
namespace reflection
{
namespace description
{
#ifndef VCZH_DEBUG_NO_REFLECTION
DECL_TYPE_INFO(vl::glr::ParsingTextPos)
DECL_TYPE_INFO(vl::glr::ParsingTextRange)
DECL_TYPE_INFO(vl::glr::ParsingToken)
DECL_TYPE_INFO(vl::glr::ParsingAstBase)
#endif
extern bool LoadParsing2Types();
}
}
}
#endif
/***********************************************************************
.\ASTPRINT.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_ASTPRINT
#define VCZH_PARSER2_ASTPRINT
namespace vl
{
namespace glr
{
/***********************************************************************
IParsingPrintNodeRecorder
***********************************************************************/
class IParsingPrintNodeRecorder : public virtual Interface
{
public:
virtual void Record(ParsingAstBase* node, const ParsingTextRange& range) = 0;
};
class ParsingEmptyPrintNodeRecorder : public Object, public virtual IParsingPrintNodeRecorder
{
public:
ParsingEmptyPrintNodeRecorder();
~ParsingEmptyPrintNodeRecorder();
void Record(ParsingAstBase* 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(ParsingAstBase* node, const ParsingTextRange& range)override;
};
class ParsingOriginalLocationRecorder : public Object, public virtual IParsingPrintNodeRecorder
{
protected:
Ptr<IParsingPrintNodeRecorder> recorder;
public:
ParsingOriginalLocationRecorder(Ptr<IParsingPrintNodeRecorder> _recorder);
~ParsingOriginalLocationRecorder();
void Record(ParsingAstBase* node, const ParsingTextRange& range)override;
};
class ParsingGeneratedLocationRecorder : public Object, public virtual IParsingPrintNodeRecorder
{
typedef collections::Dictionary<ParsingAstBase*, ParsingTextRange> RangeMap;
protected:
RangeMap& rangeMap;
public:
ParsingGeneratedLocationRecorder(RangeMap& _rangeMap);
~ParsingGeneratedLocationRecorder();
void Record(ParsingAstBase* node, const ParsingTextRange& range)override;
};
class ParsingUpdateLocationRecorder : public Object, public virtual IParsingPrintNodeRecorder
{
public:
ParsingUpdateLocationRecorder();
~ParsingUpdateLocationRecorder();
void Record(ParsingAstBase* node, const ParsingTextRange& range)override;
};
/***********************************************************************
ParsingWriter
***********************************************************************/
class ParsingWriter : public stream::TextWriter
{
typedef collections::Pair<ParsingAstBase*, 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(ParsingAstBase* node);
void AfterPrint(ParsingAstBase* node);
};
}
}
#endif
/***********************************************************************
.\EXECUTABLE.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_EXECUTABLE
#define VCZH_PARSER2_EXECUTABLE
namespace vl
{
namespace glr
{
namespace automaton
{
/***********************************************************************
Executable
***********************************************************************/
struct InstructionArray
{
vint32_t start = -1;
vint32_t count = 0;
};
struct ReturnIndexArray
{
vint32_t start = -1;
vint32_t count = -1;
};
struct EdgeArray
{
vint32_t start = -1;
vint32_t count = 0;
};
enum class EdgePriority
{
NoCompetition,
HighPriority,
LowPriority,
};
struct ReturnDesc
{
vint32_t consumedRule = -1;
vint32_t returnState = -1;
EdgePriority priority = EdgePriority::NoCompetition;
InstructionArray insAfterInput;
};
struct EdgeDesc
{
vint32_t fromState = -1;
vint32_t toState = -1;
EdgePriority priority = EdgePriority::NoCompetition;
InstructionArray insBeforeInput;
InstructionArray insAfterInput;
ReturnIndexArray returnIndices;
};
struct StateDesc
{
vint32_t rule = -1;
vint32_t clause = -1;
bool endingState = false;
};
struct Executable
{
static constexpr vint32_t EndOfInputInput = -1;
static constexpr vint32_t EndingInput = 0;
static constexpr vint32_t LeftrecInput = 1;
static constexpr vint32_t TokenBegin = 2;
vint32_t tokenCount = 0;
vint32_t ruleCount = 0;
collections::Array<vint32_t> ruleStartStates; // ruleStartStates[rule] = the start state of this rule.
collections::Array<EdgeArray> transitions; // transitions[state * (TokenBegin + tokenCount) + input] = edges from state with specified input.
collections::Array<AstIns> instructions; // referenced by InstructionArray
collections::Array<vint32_t> returnIndices; // referenced by ReturnIndexArray
collections::Array<ReturnDesc> returns; // referenced by Executable::returnIndices
collections::Array<EdgeDesc> edges; // referenced by EdgeArray
collections::Array<StateDesc> states; // refereced by returnState/fromState/toState
Executable() = default;
Executable(stream::IStream& inputStream);
void Serialize(stream::IStream& outputStream);
vint32_t GetTransitionIndex(vint32_t state, vint32_t input)
{
return state * (TokenBegin + tokenCount) + input;
}
};
struct Metadata
{
collections::Array<WString> ruleNames;
collections::Array<WString> stateLabels;
};
}
}
}
#endif
/***********************************************************************
.\TRACEMANAGER\TRACEMANAGER.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_TRACEMANAGER_TRACEMANAGER
#define VCZH_PARSER2_TRACEMANAGER_TRACEMANAGER
namespace vl
{
namespace glr
{
namespace automaton
{
/***********************************************************************
AllocateOnly<T>
***********************************************************************/
template<typename T>
class AllocateOnly : public Object
{
protected:
vint blockSize;
vint remains;
collections::List<Ptr<collections::Array<T>>> buffers;
public:
AllocateOnly(vint _blockSize = 65536)
: blockSize(_blockSize)
, remains(0)
{
}
T* Get(vint32_t index)
{
vint row = index / blockSize;
vint column = index % blockSize;
CHECK_ERROR(0 <= row && row < buffers.Count(), L"vl::glr::automaton::AllocateOnly<T>::Get(vint)#Index out of range.");
if (row == buffers.Count() - 1)
{
CHECK_ERROR(0 <= column && column < (blockSize - remains), L"vl::glr::automaton::AllocateOnly<T>::Get(vint)#Index out of range.");
}
else
{
CHECK_ERROR(0 <= column && column < blockSize, L"vl::glr::automaton::AllocateOnly<T>::Get(vint)#Index out of range.");
}
return &buffers[row]->operator[](column);
}
vint32_t Allocate()
{
if (remains == 0)
{
buffers.Add(new collections::Array<T>(blockSize));
remains = blockSize;
}
vint index = blockSize * (buffers.Count() - 1) + (blockSize - remains);
buffers[buffers.Count() - 1]->operator[](blockSize - remains).allocatedIndex = (vint32_t)index;
remains--;
return (vint32_t)index;
}
void Clear()
{
remains = 0;
buffers.Clear();
}
};
/***********************************************************************
TraceManager (Data Structures)
***********************************************************************/
struct ReturnStackSuccessors
{
vint32_t createdTokenIndex = -1; // index of the token when this ReturnStack is created
vint32_t successorTokenIndex = -1; // index of the token when this ReturnStack has its first successor
// the following members records all successors
// that is created at the token index
vint32_t first = -1; // first successor
vint32_t last = -1; // last successor
vint32_t prev = -1; // previous successor of ReturnStack::previous
vint32_t next = -1; // next successor of ReturnStack::previous
};
struct ReturnStack
{
vint32_t allocatedIndex = -1; // id of this ReturnStack
vint32_t previous = -1; // id of the previous ReturnStack
vint32_t returnIndex = -1; // index of ReturnDesc
ReturnStackSuccessors successors;
};
struct TraceCollection
{
vint32_t first = -1; // first trace in the collection
vint32_t last = -1; // last trace in the collection
vint32_t siblingPrev = -1; // previous trace in the collection of the owned trace
vint32_t siblingNext = -1; // next trace in the collection of the owned trace
};
struct TraceAmbiguity
{
vint32_t insEndObject = -1; // the index of the first EndObject instruction
// in {byEdge.insBeforeInput, byEdge.insAfterInput, executedReturnStack.returnIndex.insAfterInput} combined
// when this member is valid, the trace should satisfies:
// trace.ambiguity.insEndObject == trace.byEdge.insBeforeInput.count - trace.ambiguityInsPostfix
vint32_t traceBeginObject = -1; // id of the trace containing BeginObject or DelayFieldAssignment
// that ends by the above EndObject
vint32_t insBeginObject = -1; // the index of the BeginObject instruction
// from traceBeginObject
// in {byEdge.insBeforeInput, byEdge.insAfterInput, executedReturnStack.returnIndex.insAfterInput} combined
// if insBeginObject is larger than the number of instructions in traceBeginObject
// then the branches begin from the (insBeginObject - instruction-count(traceBeginObject))-th instruction (starting from 0) in all successors
vint32_t ambiguityType = -1; // when the BeginObject creates an object that later be consumed by BeginObjectLeftRecursive
// than the correct type is the type in BeginObjectLeftRecursive
};
enum class CompetitionStatus
{
Holding,
HighPriorityWin,
LowPriorityWin,
};
struct Competition
{
vint32_t allocatedIndex = -1;
vint32_t nextActiveCompetition = -1; // next active Competition
vint32_t nextHoldCompetition = -1; // next Competition hold by this trace
CompetitionStatus status = CompetitionStatus::Holding; // if predecessors from this trace have different priority, the competition begins
// when the competition is over, it will be changed to HighPriorityWin or LowPriorityWin
// if all candidates fail, it could be Holding forever
vint32_t currentTokenIndex = -1; // currentTokenIndex from the trace that creates this competition
vint32_t ruleId = -1; // the rule id of state, when an edge starts this competition
vint32_t clauseId = -1; // the clause id of the state, when an edge starts this competition
// an state must be picked up and ensure that, the syntax creating the priority and the state belong to the same clause
vint32_t highCounter = 0; // temporary counter for all existing high bets
// in the current step of input
vint32_t lowCounter = 0; // temporary counter for all existing low bets
// in the current step of input
};
struct AttendingCompetitions
{
vint32_t allocatedIndex = -1; // id of this AttendingCompetitions
vint32_t nextActiveAC = -1; // the next AttendingCompetitions for RuntimeRouting::attendingCompetitions
vint32_t nextCarriedAC = -1; // the next AttendingCompetitions for RuntimeRouting::carriedCompetitions
vint32_t competition = -1; // the id of the Competition
bool forHighPriority = false; // bet of this competition
vint32_t returnStack = -1; // the ReturnStack object for the competition
// if the competition is attended by a ReturnDesc
// then the ReturnStack object is the one before a ReturnDesc transition happens
bool closed = false; // true if the competition has been closed
// this flag is not always updated for discarded AttendingCompetitions objects
};
struct CompetitionRouting
{
vint32_t holdingCompetitions = -1; // the id of the active Competition
vint32_t attendingCompetitions = -1; // a linked list containing all AttendingCompetitions that this trace is attending
// predecessors could share and modify the same linked list
// if a competition is over, node could be removed from the linked list
// one competition only creates two AttendingCompetitions, traces with the same bet share the object
vint32_t carriedCompetitions = -1; // all attended competitions regardless of the status of the competition
};
struct AmbiguityRouting
{
vint32_t predecessorCount = -1; // the number of predecessors
// (filled by ExecuteTrace)
vint32_t branchVisited = 0; // the number of visited branches in the current loop.
// if these branches are contained in a larger ambiguity resolving loop, all branches could be visited multiple times
// (filled by ExecuteTrace)
};
struct Trace
{
vint32_t allocatedIndex = -1; // id of this Trace
TraceCollection predecessors; // id of the predecessor Trace
TraceCollection successors; // successors (filled by PrepareTraceRoute)
vint32_t state = -1; // id of the current StateDesc
vint32_t returnStack = -1; // id of the current ReturnStack
vint32_t executedReturnStack = -1; // id of the executed ReturnStack that contains the ReturnDesc being executed
vint32_t byEdge = -1; // id of the last EdgeDesc that make this trace
vint32_t byInput = -1; // the last input that make this trace
vint32_t currentTokenIndex = -1; // the index of the token that is byInput
TraceAmbiguity ambiguity; // where to end resolving ambiguity in instructions from this trace
// this member is useful when it has multiple predecessors
// (filled by PrepareTraceRoute)
vint32_t ambiguityBranchInsPostfix = -1; // this member is useful when it is not -1 and the trace has multiple successors
// specifying the length of the postfix
// of {byEdge.insBeforeInput, byEdge.insAfterInput, executedReturnStack.returnIndex.insAfterInput} combined
// only execute the specified prefix of instructions
// usually EndObject is the last instruction in the prefix
vint32_t ambiguityMergeInsPostfix = -1; // this member is useful when it is not -1 and the trace has multiple predecessors
// specifying the length of the postfix
// of {byEdge.insBeforeInput, byEdge.insAfterInput, executedReturnStack.returnIndex.insAfterInput} combined
// only execute the specified postfix of instructions
// usually EndObject is the last instruction in the prefix
CompetitionRouting competitionRouting; // a data structure carrying priority and competition information
AmbiguityRouting ambiguityRouting; // a data structure guiding instruction execution when a trace need to be executed multiple times
// this member is useful when it has multiple predecessors or successors
};
enum class TraceManagerState
{
Uninitialized,
WaitingForInput,
Finished,
PreparedTraceRoute,
};
struct TraceInsLists
{
InstructionArray edgeInsBeforeInput;
InstructionArray edgeInsAfterInput;
InstructionArray returnInsAfterInput;
vint32_t c1;
vint32_t c2;
vint32_t c3;
};
/***********************************************************************
TraceManager
***********************************************************************/
class TraceManager : public Object
{
public:
class ITypeCallback : public virtual Interface
{
public:
virtual vint32_t FindCommonBaseClass(vint32_t class1, vint32_t class2) const= 0;
};
protected:
Executable& executable;
const ITypeCallback* typeCallback = nullptr;
TraceManagerState state = TraceManagerState::Uninitialized;
AllocateOnly<ReturnStack> returnStacks;
AllocateOnly<Trace> traces;
AllocateOnly<Competition> competitions;
AllocateOnly<AttendingCompetitions> attendingCompetitions;
collections::List<Trace*> traces1;
collections::List<Trace*> traces2;
Trace* initialTrace = nullptr;
vint32_t activeCompetitions = -1;
ReturnStackSuccessors initialReturnStackSuccessors;
void BeginSwap();
void AddTrace(Trace* trace);
void EndSwap();
void AddTraceToCollection(Trace* owner, Trace* element, TraceCollection(Trace::* collection));
// Ambiguity
bool AreTwoEndingInputTraceEqual(vint32_t state, vint32_t returnStack, vint32_t executedReturnStack, vint32_t acId, Trace* candidate);
vint32_t GetInstructionPostfix(EdgeDesc& oldEdge, EdgeDesc& newEdge);
void MergeTwoEndingInputTrace(
Trace* trace,
Trace* ambiguityTraceToMerge,
vint32_t currentTokenIndex,
vint32_t input,
vint32_t byEdge,
EdgeDesc& edgeDesc,
vint32_t state,
vint32_t returnStack,
vint32_t attendingCompetitions,
vint32_t carriedCompetitions,
vint32_t executedReturnStack);
// Competition
void AttendCompetition(Trace* trace, vint32_t& newAttendingCompetitions, vint32_t& newCarriedCompetitions, vint32_t returnStack, vint32_t ruleId, vint32_t clauseId, bool forHighPriority);
ReturnStack* PushReturnStack(vint32_t base, vint32_t returnIndex, vint32_t currentTokenIndex);
void AttendCompetitionIfNecessary(Trace* trace, vint32_t currentTokenIndex, EdgeDesc& edgeDesc, vint32_t& newAttendingCompetitions, vint32_t& newCarriedCompetitions, vint32_t& newReturnStack);
void CheckAttendingCompetitionsOnEndingEdge(Trace* trace, EdgeDesc& edgeDesc, vint32_t acId, vint32_t returnStack);
void CheckBackupTracesBeforeSwapping(vint32_t currentTokenIndex);
// Walk
Trace* WalkAlongSingleEdge(vint32_t currentTokenIndex, vint32_t input, Trace* trace, vint32_t byEdge, EdgeDesc& edgeDesc);
void WalkAlongLeftrecEdges(vint32_t currentTokenIndex, vint32_t lookAhead, Trace* trace, EdgeArray& edgeArray);
void WalkAlongEpsilonEdges(vint32_t currentTokenIndex, vint32_t lookAhead, Trace* trace);
void WalkAlongTokenEdges(vint32_t currentTokenIndex, vint32_t input, vint32_t lookAhead, Trace* trace, EdgeArray& edgeArray);
// PrepareTraceRoute
struct SharedBeginObject
{
Trace* traceBeginObject = nullptr;
vint32_t insBeginObject = -1;
vint32_t type = -1;
};
void ReadInstructionList(Trace* trace, TraceInsLists& insLists);
AstIns& ReadInstruction(vint32_t instruction, TraceInsLists& insLists);
bool RunInstruction(vint32_t instruction, TraceInsLists& insLists, vint32_t& objectCount, vint32_t& reopenCount);
void AdjustToRealTrace(SharedBeginObject& shared);
void FindBalancedBoOrBolr(SharedBeginObject& balanced, vint32_t& objectCount, vint32_t& reopenCount);
void FindBalancedBoOrDfa(Trace* trace, vint32_t objectCount, SharedBeginObject& branch);
void MergeAmbiguityType(vint32_t& ambiguityType, vint32_t branchType);
SharedBeginObject MergeSharedBeginObjectsSingleRoot(Trace* trace, collections::Dictionary<Trace*, SharedBeginObject>& predecessorToBranches);
SharedBeginObject MergeSharedBeginObjectsMultipleRoot(Trace* trace, collections::Dictionary<Trace*, SharedBeginObject>& predecessorToBranches);
SharedBeginObject MergeSharedBeginObjectsPartialMultipleRoot(Trace* trace, vint32_t ambiguityType, collections::Group<Trace*, Trace*>& beginToPredecessors, collections::Dictionary<Trace*, SharedBeginObject>& predecessorToBranches);
SharedBeginObject FillAmbiguityInfoForMergingTrace(Trace* trace);
void FillAmbiguityInfoForPredecessorTraces(Trace* trace);
void CreateLastMergingTrace(Trace* rootTraceCandidate);
public:
TraceManager(Executable& _executable, const ITypeCallback* _typeCallback = nullptr);
vint32_t concurrentCount = 0;
collections::List<Trace*>* concurrentTraces = nullptr;
collections::List<Trace*>* backupTraces = nullptr;
ReturnStack* GetReturnStack(vint32_t index);
ReturnStack* AllocateReturnStack();
Trace* GetTrace(vint32_t index);
Trace* AllocateTrace();
Competition* GetCompetition(vint32_t index);
Competition* AllocateCompetition();
AttendingCompetitions* GetAttendingCompetitions(vint32_t index);
AttendingCompetitions* AllocateAttendingCompetitions();
void Initialize(vint32_t startState);
void Input(vint32_t currentTokenIndex, vint32_t token, vint32_t lookAhead);
void EndOfInput();
Trace* PrepareTraceRoute();
Ptr<ParsingAstBase> ExecuteTrace(Trace* trace, IAstInsReceiver& receiver, collections::List<regex::RegexToken>& tokens);
};
}
}
}
#endif
/***********************************************************************
.\SYNTAXBASE.H
***********************************************************************/
/***********************************************************************
Author: Zihan Chen (vczh)
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_SYNTAXBASE
#define VCZH_PARSER2_SYNTAXBASE
namespace vl
{
namespace glr
{
/***********************************************************************
ParserBase<TTokens, TStates, TReceiver, TStateTypes>
***********************************************************************/
enum class ErrorType
{
UnrecognizedToken, // (token) the token is not recognizable to the tokenizer
InvalidToken, // (token, tokens, executable, traceManager) the token cause the parser to stop
InputIncomplete, // (tokens, executable, traceManager) all traces do not reach the end
UnexpectedAstType, // (tokens, executable, traceManager, ast) unexpected type of the created AST
};
struct EndOfInputArgs
{
collections::List<regex::RegexToken>& tokens;
automaton::Executable& executable;
automaton::TraceManager& traceManager;
automaton::Trace* rootTrace;
};
struct ErrorArgs
{
bool throwError;
ErrorType error;
vint codeIndex;
regex::RegexToken& token;
collections::List<regex::RegexToken>& tokens;
automaton::Executable& executable;
automaton::TraceManager& traceManager;
Ptr<ParsingAstBase> ast;
static ErrorArgs UnrecognizedToken (const regex::RegexToken& token);
static ErrorArgs InvalidToken (regex::RegexToken& token, collections::List<regex::RegexToken>& tokens, automaton::Executable& executable, automaton::TraceManager& traceManager);
static ErrorArgs InputIncomplete (vint codeIndex, collections::List<regex::RegexToken>& tokens, automaton::Executable& executable, automaton::TraceManager& traceManager);
static ErrorArgs UnexpectedAstType (collections::List<regex::RegexToken>& tokens, automaton::Executable& executable, automaton::TraceManager& traceManager, Ptr<ParsingAstBase> ast);
ParsingError ToParsingError();
};
template<typename TParser>
Ptr<EventHandler> InstallDefaultErrorMessageGenerator(TParser& parser, collections::List<ParsingError>& errors)
{
return parser.OnError.Add([&errors](ErrorArgs& args)
{
args.throwError = false;
errors.Add(args.ToParsingError());
});
}
template<
typename TTokens,
typename TStates,
typename TReceiver
>
class ParserBase : public Object
{
static_assert(std::is_enum_v<TTokens>);
static_assert(std::is_enum_v<TStates>);
static_assert(std::is_convertible_v<TReceiver*, IAstInsReceiver*>);
using Deleter = bool(*)(vint);
using TokenList = collections::List<regex::RegexToken>;
using EndOfInputCallback = void(EndOfInputArgs&);
using ErrorCallback = void(ErrorArgs&);
protected:
Deleter deleter;
Ptr<regex::RegexLexer> lexer;
Ptr<automaton::Executable> executable;
public:
Event<EndOfInputCallback> OnEndOfInput;
Event<ErrorCallback> OnError;
ParserBase(
Deleter _deleter,
void(*_lexerData)(stream::IStream&),
void(*_parserData)(stream::IStream&)
) : deleter(_deleter)
{
{
stream::MemoryStream data;
_lexerData(data);
data.SeekFromBegin(0);
lexer = new regex::RegexLexer(data);
}
{
stream::MemoryStream data;
_parserData(data);
data.SeekFromBegin(0);
executable = new automaton::Executable(data);
}
}
regex::RegexLexer& Lexer() const
{
return *lexer.Obj();
}
Deleter LexerDeleter() const
{
return deleter;
}
void Tokenize(const WString& input, TokenList& tokens, vint codeIndex = -1) const
{
input.Buffer();
auto enumerable = lexer->Parse(input, {}, codeIndex);
Ptr<collections::IEnumerator<regex::RegexToken>> enumerator = enumerable.CreateEnumerator();
while (enumerator->Next())
{
auto&& token = enumerator->Current();
if (token.token == -1 || !token.completeToken)
{
auto args = ErrorArgs::UnrecognizedToken(token);
args.throwError = false;
OnError(args);
if (args.throwError)
{
CHECK_FAIL(L"vl::glr::ParserBase<...>::Tokenize(const WString&, List<RegexToken>&, vint)#Unrecognized token.");
}
}
else if (!deleter(token.token))
{
tokens.Add(token);
}
}
}
protected:
Ptr<ParsingAstBase> ParseInternal(TokenList& tokens, vint32_t state, automaton::TraceManager& tm, const automaton::TraceManager::ITypeCallback* typeCallback, vint codeIndex) const
{
#define ERROR_MESSAGE_PREFIX L"vl::glr::ParserBase<...>::ParseInternal(List<RegexToken>&, vint32_t TraceManager::ITypeCallback*)#"
if (codeIndex == -1 && tokens.Count() > 0)
{
codeIndex = tokens[0].codeIndex;
}
tm.Initialize(state);
for (vint32_t i = 0; i < tokens.Count(); i++)
{
auto&& token = tokens[i];
auto lookAhead = i == tokens.Count() - 1 ? -1 : tokens[i + 1].token;
tm.Input(i, (vint32_t)token.token, (vint32_t)lookAhead);
if (tm.concurrentCount == 0)
{
auto args = ErrorArgs::InvalidToken(token, tokens, *executable.Obj(), tm);
OnError(args);
if (args.throwError) CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Error happens during parsing.");
return nullptr;
}
}
tm.EndOfInput();
if (tm.concurrentCount == 0)
{
auto args = ErrorArgs::InputIncomplete(codeIndex, tokens, *executable.Obj(), tm);
OnError(args);
if (args.throwError) CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Input is incomplete.");
return nullptr;
}
auto rootTrace = tm.PrepareTraceRoute();
{
EndOfInputArgs args = { tokens, *executable.Obj(), tm, rootTrace };
OnEndOfInput(args);
}
TReceiver receiver;
return tm.ExecuteTrace(rootTrace, receiver, tokens);
#undef ERROR_MESSAGE_PREFIX
}
template<typename TAst, TStates State>
Ptr<TAst> ParseWithTokens(TokenList& tokens, const automaton::TraceManager::ITypeCallback* typeCallback, vint codeIndex) const
{
#define ERROR_MESSAGE_PREFIX L"vl::glr::ParserBase<...>::Parse<TAst, TStates>(List<RegexToken>& TraceManager::ITypeCallback*)#"
automaton::TraceManager tm(*executable.Obj(), typeCallback);
auto ast = ParseInternal(tokens, (vint32_t)State, tm, typeCallback, codeIndex);
auto typedAst = ast.Cast<TAst>();
if (!typedAst)
{
auto args = ErrorArgs::UnexpectedAstType(tokens, *executable.Obj(), tm, ast);
OnError(args);
if (args.throwError) CHECK_FAIL(ERROR_MESSAGE_PREFIX L"Unexpected type of the created AST.");
}
return typedAst;
#undef ERROR_MESSAGE_PREFIX
}
template<typename TAst, TStates State>
Ptr<TAst> ParseWithString(const WString& input, const automaton::TraceManager::ITypeCallback* typeCallback, vint codeIndex) const
{
TokenList tokens;
Tokenize(input, tokens, codeIndex);
return ParseWithTokens<TAst, State>(tokens, typeCallback, codeIndex);
}
};
}
}
#endif
/***********************************************************************
.\JSON\GENERATED\JSONAST.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Ast
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_JSON_AST_AST
#define VCZH_PARSER2_BUILTIN_JSON_AST_AST
namespace vl
{
namespace glr
{
namespace json
{
class JsonArray;
class JsonLiteral;
class JsonNode;
class JsonNumber;
class JsonObject;
class JsonObjectField;
class JsonString;
enum class JsonLiteralValue
{
UNDEFINED_ENUM_ITEM_VALUE = -1,
True = 0,
False = 1,
Null = 2,
};
class JsonNode abstract : public vl::glr::ParsingAstBase, vl::reflection::Description<JsonNode>
{
public:
class IVisitor : public virtual vl::reflection::IDescriptable, vl::reflection::Description<IVisitor>
{
public:
virtual void Visit(JsonLiteral* node) = 0;
virtual void Visit(JsonString* node) = 0;
virtual void Visit(JsonNumber* node) = 0;
virtual void Visit(JsonArray* node) = 0;
virtual void Visit(JsonObject* node) = 0;
};
virtual void Accept(JsonNode::IVisitor* visitor) = 0;
};
class JsonLiteral : public JsonNode, vl::reflection::Description<JsonLiteral>
{
public:
JsonLiteralValue value = JsonLiteralValue::UNDEFINED_ENUM_ITEM_VALUE;
void Accept(JsonNode::IVisitor* visitor) override;
};
class JsonString : public JsonNode, vl::reflection::Description<JsonString>
{
public:
vl::glr::ParsingToken content;
void Accept(JsonNode::IVisitor* visitor) override;
};
class JsonNumber : public JsonNode, vl::reflection::Description<JsonNumber>
{
public:
vl::glr::ParsingToken content;
void Accept(JsonNode::IVisitor* visitor) override;
};
class JsonArray : public JsonNode, vl::reflection::Description<JsonArray>
{
public:
vl::collections::List<vl::Ptr<JsonNode>> items;
void Accept(JsonNode::IVisitor* visitor) override;
};
class JsonObjectField : public vl::glr::ParsingAstBase, vl::reflection::Description<JsonObjectField>
{
public:
vl::glr::ParsingToken name;
vl::Ptr<JsonNode> value;
};
class JsonObject : public JsonNode, vl::reflection::Description<JsonObject>
{
public:
vl::collections::List<vl::Ptr<JsonObjectField>> fields;
void Accept(JsonNode::IVisitor* visitor) override;
};
}
}
}
namespace vl
{
namespace reflection
{
namespace description
{
#ifndef VCZH_DEBUG_NO_REFLECTION
DECL_TYPE_INFO(vl::glr::json::JsonNode)
DECL_TYPE_INFO(vl::glr::json::JsonNode::IVisitor)
DECL_TYPE_INFO(vl::glr::json::JsonLiteralValue)
DECL_TYPE_INFO(vl::glr::json::JsonLiteral)
DECL_TYPE_INFO(vl::glr::json::JsonString)
DECL_TYPE_INFO(vl::glr::json::JsonNumber)
DECL_TYPE_INFO(vl::glr::json::JsonArray)
DECL_TYPE_INFO(vl::glr::json::JsonObjectField)
DECL_TYPE_INFO(vl::glr::json::JsonObject)
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::glr::json::JsonNode::IVisitor)
void Visit(vl::glr::json::JsonLiteral* node) override
{
INVOKE_INTERFACE_PROXY(Visit, node);
}
void Visit(vl::glr::json::JsonString* node) override
{
INVOKE_INTERFACE_PROXY(Visit, node);
}
void Visit(vl::glr::json::JsonNumber* node) override
{
INVOKE_INTERFACE_PROXY(Visit, node);
}
void Visit(vl::glr::json::JsonArray* node) override
{
INVOKE_INTERFACE_PROXY(Visit, node);
}
void Visit(vl::glr::json::JsonObject* node) override
{
INVOKE_INTERFACE_PROXY(Visit, node);
}
END_INTERFACE_PROXY(vl::glr::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 JsonAstLoadTypes();
}
}
}
#endif
/***********************************************************************
.\JSON\GENERATED\JSONAST_BUILDER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Ast
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_JSON_AST_AST_BUILDER
#define VCZH_PARSER2_BUILTIN_JSON_AST_AST_BUILDER
namespace vl
{
namespace glr
{
namespace json
{
namespace builder
{
class MakeArray : public vl::glr::ParsingAstBuilder<JsonArray>
{
public:
MakeArray& items(const vl::Ptr<JsonNode>& value);
};
class MakeLiteral : public vl::glr::ParsingAstBuilder<JsonLiteral>
{
public:
MakeLiteral& value(JsonLiteralValue value);
};
class MakeNumber : public vl::glr::ParsingAstBuilder<JsonNumber>
{
public:
MakeNumber& content(const vl::WString& value);
};
class MakeObject : public vl::glr::ParsingAstBuilder<JsonObject>
{
public:
MakeObject& fields(const vl::Ptr<JsonObjectField>& value);
};
class MakeObjectField : public vl::glr::ParsingAstBuilder<JsonObjectField>
{
public:
MakeObjectField& name(const vl::WString& value);
MakeObjectField& value(const vl::Ptr<JsonNode>& value);
};
class MakeString : public vl::glr::ParsingAstBuilder<JsonString>
{
public:
MakeString& content(const vl::WString& value);
};
}
}
}
}
#endif
/***********************************************************************
.\JSON\GENERATED\JSONAST_COPY.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Ast
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_JSON_AST_AST_COPY_VISITOR
#define VCZH_PARSER2_BUILTIN_JSON_AST_AST_COPY_VISITOR
namespace vl
{
namespace glr
{
namespace json
{
namespace copy_visitor
{
/// <summary>A copy visitor, overriding all abstract methods with AST copying code.</summary>
class AstVisitor
: public virtual vl::glr::CopyVisitorBase
, protected virtual JsonNode::IVisitor
{
protected:
void CopyFields(JsonArray* from, JsonArray* to);
void CopyFields(JsonLiteral* from, JsonLiteral* to);
void CopyFields(JsonNode* from, JsonNode* to);
void CopyFields(JsonNumber* from, JsonNumber* to);
void CopyFields(JsonObject* from, JsonObject* to);
void CopyFields(JsonObjectField* from, JsonObjectField* to);
void CopyFields(JsonString* from, JsonString* to);
protected:
virtual void Visit(JsonObjectField* node);
void Visit(JsonLiteral* node) override;
void Visit(JsonString* node) override;
void Visit(JsonNumber* node) override;
void Visit(JsonArray* node) override;
void Visit(JsonObject* node) override;
public:
virtual vl::Ptr<JsonNode> CopyNode(JsonNode* node);
virtual vl::Ptr<JsonObjectField> CopyNode(JsonObjectField* node);
vl::Ptr<JsonArray> CopyNode(JsonArray* node);
vl::Ptr<JsonLiteral> CopyNode(JsonLiteral* node);
vl::Ptr<JsonNumber> CopyNode(JsonNumber* node);
vl::Ptr<JsonObject> CopyNode(JsonObject* node);
vl::Ptr<JsonString> CopyNode(JsonString* node);
};
}
}
}
}
#endif
/***********************************************************************
.\JSON\GENERATED\JSONAST_EMPTY.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Ast
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_JSON_AST_AST_EMPTY_VISITOR
#define VCZH_PARSER2_BUILTIN_JSON_AST_AST_EMPTY_VISITOR
namespace vl
{
namespace glr
{
namespace json
{
namespace empty_visitor
{
/// <summary>An empty visitor, overriding all abstract methods with empty implementations.</summary>
class NodeVisitor : public vl::Object, public JsonNode::IVisitor
{
protected:
// Dispatch (virtual) --------------------------------
public:
// Visitor Members -----------------------------------
void Visit(JsonLiteral* node) override;
void Visit(JsonString* node) override;
void Visit(JsonNumber* node) override;
void Visit(JsonArray* node) override;
void Visit(JsonObject* node) override;
};
}
}
}
}
#endif
/***********************************************************************
.\JSON\GENERATED\JSONAST_JSON.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Ast
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_JSON_AST_AST_JSON_VISITOR
#define VCZH_PARSER2_BUILTIN_JSON_AST_AST_JSON_VISITOR
namespace vl
{
namespace glr
{
namespace json
{
namespace json_visitor
{
/// <summary>A JSON visitor, overriding all abstract methods with AST to JSON serialization code.</summary>
class AstVisitor
: public vl::glr::JsonVisitorBase
, protected virtual JsonNode::IVisitor
{
protected:
virtual void PrintFields(JsonArray* node);
virtual void PrintFields(JsonLiteral* node);
virtual void PrintFields(JsonNode* node);
virtual void PrintFields(JsonNumber* node);
virtual void PrintFields(JsonObject* node);
virtual void PrintFields(JsonObjectField* node);
virtual void PrintFields(JsonString* node);
protected:
void Visit(JsonLiteral* node) override;
void Visit(JsonString* node) override;
void Visit(JsonNumber* node) override;
void Visit(JsonArray* node) override;
void Visit(JsonObject* node) override;
public:
AstVisitor(vl::stream::StreamWriter& _writer);
void Print(JsonNode* node);
void Print(JsonObjectField* node);
};
}
}
}
}
#endif
/***********************************************************************
.\JSON\GENERATED\JSONAST_TRAVERSE.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Ast
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_JSON_AST_AST_TRAVERSE_VISITOR
#define VCZH_PARSER2_BUILTIN_JSON_AST_AST_TRAVERSE_VISITOR
namespace vl
{
namespace glr
{
namespace json
{
namespace traverse_visitor
{
/// <summary>A traverse visitor, overriding all abstract methods with AST visiting code.</summary>
class AstVisitor
: public vl::Object
, protected virtual JsonNode::IVisitor
{
protected:
virtual void Traverse(vl::glr::ParsingToken& token);
virtual void Traverse(vl::glr::ParsingAstBase* node);
virtual void Traverse(JsonArray* node);
virtual void Traverse(JsonLiteral* node);
virtual void Traverse(JsonNode* node);
virtual void Traverse(JsonNumber* node);
virtual void Traverse(JsonObject* node);
virtual void Traverse(JsonObjectField* node);
virtual void Traverse(JsonString* node);
protected:
virtual void Finishing(vl::glr::ParsingAstBase* node);
virtual void Finishing(JsonArray* node);
virtual void Finishing(JsonLiteral* node);
virtual void Finishing(JsonNode* node);
virtual void Finishing(JsonNumber* node);
virtual void Finishing(JsonObject* node);
virtual void Finishing(JsonObjectField* node);
virtual void Finishing(JsonString* node);
protected:
void Visit(JsonLiteral* node) override;
void Visit(JsonString* node) override;
void Visit(JsonNumber* node) override;
void Visit(JsonArray* node) override;
void Visit(JsonObject* node) override;
public:
void InspectInto(JsonNode* node);
void InspectInto(JsonObjectField* node);
};
}
}
}
}
#endif
/***********************************************************************
.\JSON\GENERATED\JSON_ASSEMBLER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Json
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_JSON_AST_ASSEMBLER
#define VCZH_PARSER2_BUILTIN_JSON_AST_ASSEMBLER
namespace vl
{
namespace glr
{
namespace json
{
enum class JsonClasses : vl::vint32_t
{
Array = 0,
Literal = 1,
Node = 2,
Number = 3,
Object = 4,
ObjectField = 5,
String = 6,
};
enum class JsonFields : vl::vint32_t
{
Array_items = 0,
Literal_value = 1,
Number_content = 2,
Object_fields = 3,
ObjectField_name = 4,
ObjectField_value = 5,
String_content = 6,
};
extern const wchar_t* JsonTypeName(JsonClasses type);
extern const wchar_t* JsonCppTypeName(JsonClasses type);
extern const wchar_t* JsonFieldName(JsonFields field);
extern const wchar_t* JsonCppFieldName(JsonFields field);
class JsonAstInsReceiver : public vl::glr::AstInsReceiverBase
{
protected:
vl::Ptr<vl::glr::ParsingAstBase> CreateAstNode(vl::vint32_t type) override;
void SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::Ptr<vl::glr::ParsingAstBase> value) override;
void SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, const vl::regex::RegexToken& token, vl::vint32_t tokenIndex) override;
void SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::vint32_t enumItem) override;
vl::Ptr<vl::glr::ParsingAstBase> ResolveAmbiguity(vl::vint32_t type, vl::collections::Array<vl::Ptr<vl::glr::ParsingAstBase>>& candidates) override;
};
}
}
}
#endif
/***********************************************************************
.\JSON\GENERATED\JSON_LEXER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Json
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_JSON_LEXER
#define VCZH_PARSER2_BUILTIN_JSON_LEXER
namespace vl
{
namespace glr
{
namespace json
{
enum class JsonTokens : vl::vint32_t
{
TRUE_VALUE = 0,
FALSE_VALUE = 1,
NULL_VALUE = 2,
OBJOPEN = 3,
OBJCLOSE = 4,
ARROPEN = 5,
ARRCLOSE = 6,
COMMA = 7,
COLON = 8,
NUMBER = 9,
STRING = 10,
SPACE = 11,
};
constexpr vl::vint JsonTokenCount = 12;
extern bool JsonTokenDeleter(vl::vint token);
extern const wchar_t* JsonTokenId(JsonTokens token);
extern const wchar_t* JsonTokenDisplayText(JsonTokens token);
extern const wchar_t* JsonTokenRegex(JsonTokens token);
extern void JsonLexerData(vl::stream::IStream& outputStream);
}
}
}
#endif
/***********************************************************************
.\JSON\GENERATED\JSONPARSER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Json
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_JSON_PARSER_SYNTAX
#define VCZH_PARSER2_BUILTIN_JSON_PARSER_SYNTAX
namespace vl
{
namespace glr
{
namespace json
{
enum class ParserStates
{
JLiteral = 0,
JField = 7,
JObject = 12,
JArray = 18,
JValue = 24,
JRoot = 29,
};
const wchar_t* ParserRuleName(vl::vint index);
const wchar_t* ParserStateLabel(vl::vint index);
extern void JsonParserData(vl::stream::IStream& outputStream);
class Parser
: public vl::glr::ParserBase<JsonTokens, ParserStates, JsonAstInsReceiver> , protected vl::glr::automaton::TraceManager::ITypeCallback
{
protected:
vl::vint32_t FindCommonBaseClass(vl::vint32_t class1, vl::vint32_t class2) const override;
public:
Parser();
vl::Ptr<vl::glr::json::JsonNode> ParseJRoot(const vl::WString& input, vl::vint codeIndex = -1) const;
vl::Ptr<vl::glr::json::JsonNode> ParseJRoot(vl::collections::List<vl::regex::RegexToken>& tokens, vl::vint codeIndex = -1) const;
};
}
}
}
#endif
/***********************************************************************
.\JSON\GLRJSON.H
***********************************************************************/
/***********************************************************************
Vczh Library++ 3.0
Developer: Zihan Chen(vczh)
Parser::ParsingJson_Parser
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_JSON
#define VCZH_PARSER2_BUILTIN_JSON
namespace vl
{
namespace glr
{
namespace json
{
/// <summary>Deserialize JSON from string.</summary>
/// <returns>The deserialized JSON node.</returns>
/// <param name="input">The JSON code.</param>
/// <param name="parser">The generated parser.</param>
extern Ptr<JsonNode> JsonParse(const WString& input, const Parser& parser);
/// <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\GENERATED\XMLAST.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Ast
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_XML_AST_AST
#define VCZH_PARSER2_BUILTIN_XML_AST_AST
namespace vl
{
namespace glr
{
namespace xml
{
class XmlAttribute;
class XmlCData;
class XmlComment;
class XmlDocument;
class XmlElement;
class XmlInstruction;
class XmlNode;
class XmlText;
class XmlNode abstract : public vl::glr::ParsingAstBase, vl::reflection::Description<XmlNode>
{
public:
class IVisitor : public virtual vl::reflection::IDescriptable, vl::reflection::Description<IVisitor>
{
public:
virtual void Visit(XmlText* node) = 0;
virtual void Visit(XmlCData* node) = 0;
virtual void Visit(XmlComment* node) = 0;
virtual void Visit(XmlElement* node) = 0;
virtual void Visit(XmlInstruction* node) = 0;
virtual void Visit(XmlDocument* node) = 0;
};
virtual void Accept(XmlNode::IVisitor* visitor) = 0;
};
class XmlText : public XmlNode, vl::reflection::Description<XmlText>
{
public:
vl::glr::ParsingToken content;
void Accept(XmlNode::IVisitor* visitor) override;
};
class XmlCData : public XmlNode, vl::reflection::Description<XmlCData>
{
public:
vl::glr::ParsingToken content;
void Accept(XmlNode::IVisitor* visitor) override;
};
class XmlAttribute : public vl::glr::ParsingAstBase, vl::reflection::Description<XmlAttribute>
{
public:
vl::glr::ParsingToken name;
vl::glr::ParsingToken value;
};
class XmlComment : public XmlNode, vl::reflection::Description<XmlComment>
{
public:
vl::glr::ParsingToken content;
void Accept(XmlNode::IVisitor* visitor) override;
};
class XmlElement : public XmlNode, vl::reflection::Description<XmlElement>
{
public:
vl::glr::ParsingToken name;
vl::glr::ParsingToken closingName;
vl::collections::List<vl::Ptr<XmlAttribute>> attributes;
vl::collections::List<vl::Ptr<XmlNode>> subNodes;
void Accept(XmlNode::IVisitor* visitor) override;
};
class XmlInstruction : public XmlNode, vl::reflection::Description<XmlInstruction>
{
public:
vl::glr::ParsingToken name;
vl::collections::List<vl::Ptr<XmlAttribute>> attributes;
void Accept(XmlNode::IVisitor* visitor) override;
};
class XmlDocument : public XmlNode, vl::reflection::Description<XmlDocument>
{
public:
vl::collections::List<vl::Ptr<XmlNode>> prologs;
vl::Ptr<XmlElement> rootElement;
void Accept(XmlNode::IVisitor* visitor) override;
};
}
}
}
namespace vl
{
namespace reflection
{
namespace description
{
#ifndef VCZH_DEBUG_NO_REFLECTION
DECL_TYPE_INFO(vl::glr::xml::XmlNode)
DECL_TYPE_INFO(vl::glr::xml::XmlNode::IVisitor)
DECL_TYPE_INFO(vl::glr::xml::XmlText)
DECL_TYPE_INFO(vl::glr::xml::XmlCData)
DECL_TYPE_INFO(vl::glr::xml::XmlAttribute)
DECL_TYPE_INFO(vl::glr::xml::XmlComment)
DECL_TYPE_INFO(vl::glr::xml::XmlElement)
DECL_TYPE_INFO(vl::glr::xml::XmlInstruction)
DECL_TYPE_INFO(vl::glr::xml::XmlDocument)
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::glr::xml::XmlNode::IVisitor)
void Visit(vl::glr::xml::XmlText* node) override
{
INVOKE_INTERFACE_PROXY(Visit, node);
}
void Visit(vl::glr::xml::XmlCData* node) override
{
INVOKE_INTERFACE_PROXY(Visit, node);
}
void Visit(vl::glr::xml::XmlComment* node) override
{
INVOKE_INTERFACE_PROXY(Visit, node);
}
void Visit(vl::glr::xml::XmlElement* node) override
{
INVOKE_INTERFACE_PROXY(Visit, node);
}
void Visit(vl::glr::xml::XmlInstruction* node) override
{
INVOKE_INTERFACE_PROXY(Visit, node);
}
void Visit(vl::glr::xml::XmlDocument* node) override
{
INVOKE_INTERFACE_PROXY(Visit, node);
}
END_INTERFACE_PROXY(vl::glr::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 XmlAstLoadTypes();
}
}
}
#endif
/***********************************************************************
.\XML\GENERATED\XMLAST_BUILDER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Ast
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_XML_AST_AST_BUILDER
#define VCZH_PARSER2_BUILTIN_XML_AST_AST_BUILDER
namespace vl
{
namespace glr
{
namespace xml
{
namespace builder
{
class MakeAttribute : public vl::glr::ParsingAstBuilder<XmlAttribute>
{
public:
MakeAttribute& name(const vl::WString& value);
MakeAttribute& value(const vl::WString& value);
};
class MakeCData : public vl::glr::ParsingAstBuilder<XmlCData>
{
public:
MakeCData& content(const vl::WString& value);
};
class MakeComment : public vl::glr::ParsingAstBuilder<XmlComment>
{
public:
MakeComment& content(const vl::WString& value);
};
class MakeDocument : public vl::glr::ParsingAstBuilder<XmlDocument>
{
public:
MakeDocument& prologs(const vl::Ptr<XmlNode>& value);
MakeDocument& rootElement(const vl::Ptr<XmlElement>& value);
};
class MakeElement : public vl::glr::ParsingAstBuilder<XmlElement>
{
public:
MakeElement& attributes(const vl::Ptr<XmlAttribute>& value);
MakeElement& closingName(const vl::WString& value);
MakeElement& name(const vl::WString& value);
MakeElement& subNodes(const vl::Ptr<XmlNode>& value);
};
class MakeInstruction : public vl::glr::ParsingAstBuilder<XmlInstruction>
{
public:
MakeInstruction& attributes(const vl::Ptr<XmlAttribute>& value);
MakeInstruction& name(const vl::WString& value);
};
class MakeText : public vl::glr::ParsingAstBuilder<XmlText>
{
public:
MakeText& content(const vl::WString& value);
};
}
}
}
}
#endif
/***********************************************************************
.\XML\GENERATED\XMLAST_COPY.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Ast
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_XML_AST_AST_COPY_VISITOR
#define VCZH_PARSER2_BUILTIN_XML_AST_AST_COPY_VISITOR
namespace vl
{
namespace glr
{
namespace xml
{
namespace copy_visitor
{
/// <summary>A copy visitor, overriding all abstract methods with AST copying code.</summary>
class AstVisitor
: public virtual vl::glr::CopyVisitorBase
, protected virtual XmlNode::IVisitor
{
protected:
void CopyFields(XmlAttribute* from, XmlAttribute* to);
void CopyFields(XmlCData* from, XmlCData* to);
void CopyFields(XmlComment* from, XmlComment* to);
void CopyFields(XmlDocument* from, XmlDocument* to);
void CopyFields(XmlElement* from, XmlElement* to);
void CopyFields(XmlInstruction* from, XmlInstruction* to);
void CopyFields(XmlNode* from, XmlNode* to);
void CopyFields(XmlText* from, XmlText* to);
protected:
virtual void Visit(XmlAttribute* node);
void Visit(XmlText* node) override;
void Visit(XmlCData* node) override;
void Visit(XmlComment* node) override;
void Visit(XmlElement* node) override;
void Visit(XmlInstruction* node) override;
void Visit(XmlDocument* node) override;
public:
virtual vl::Ptr<XmlNode> CopyNode(XmlNode* node);
virtual vl::Ptr<XmlAttribute> CopyNode(XmlAttribute* node);
vl::Ptr<XmlCData> CopyNode(XmlCData* node);
vl::Ptr<XmlComment> CopyNode(XmlComment* node);
vl::Ptr<XmlDocument> CopyNode(XmlDocument* node);
vl::Ptr<XmlElement> CopyNode(XmlElement* node);
vl::Ptr<XmlInstruction> CopyNode(XmlInstruction* node);
vl::Ptr<XmlText> CopyNode(XmlText* node);
};
}
}
}
}
#endif
/***********************************************************************
.\XML\GENERATED\XMLAST_EMPTY.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Ast
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_XML_AST_AST_EMPTY_VISITOR
#define VCZH_PARSER2_BUILTIN_XML_AST_AST_EMPTY_VISITOR
namespace vl
{
namespace glr
{
namespace xml
{
namespace empty_visitor
{
/// <summary>An empty visitor, overriding all abstract methods with empty implementations.</summary>
class NodeVisitor : public vl::Object, public XmlNode::IVisitor
{
protected:
// Dispatch (virtual) --------------------------------
public:
// Visitor Members -----------------------------------
void Visit(XmlText* node) override;
void Visit(XmlCData* node) override;
void Visit(XmlComment* node) override;
void Visit(XmlElement* node) override;
void Visit(XmlInstruction* node) override;
void Visit(XmlDocument* node) override;
};
}
}
}
}
#endif
/***********************************************************************
.\XML\GENERATED\XMLAST_JSON.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Ast
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_XML_AST_AST_JSON_VISITOR
#define VCZH_PARSER2_BUILTIN_XML_AST_AST_JSON_VISITOR
namespace vl
{
namespace glr
{
namespace xml
{
namespace json_visitor
{
/// <summary>A JSON visitor, overriding all abstract methods with AST to JSON serialization code.</summary>
class AstVisitor
: public vl::glr::JsonVisitorBase
, protected virtual XmlNode::IVisitor
{
protected:
virtual void PrintFields(XmlAttribute* node);
virtual void PrintFields(XmlCData* node);
virtual void PrintFields(XmlComment* node);
virtual void PrintFields(XmlDocument* node);
virtual void PrintFields(XmlElement* node);
virtual void PrintFields(XmlInstruction* node);
virtual void PrintFields(XmlNode* node);
virtual void PrintFields(XmlText* node);
protected:
void Visit(XmlText* node) override;
void Visit(XmlCData* node) override;
void Visit(XmlComment* node) override;
void Visit(XmlElement* node) override;
void Visit(XmlInstruction* node) override;
void Visit(XmlDocument* node) override;
public:
AstVisitor(vl::stream::StreamWriter& _writer);
void Print(XmlNode* node);
void Print(XmlAttribute* node);
};
}
}
}
}
#endif
/***********************************************************************
.\XML\GENERATED\XMLAST_TRAVERSE.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Ast
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_XML_AST_AST_TRAVERSE_VISITOR
#define VCZH_PARSER2_BUILTIN_XML_AST_AST_TRAVERSE_VISITOR
namespace vl
{
namespace glr
{
namespace xml
{
namespace traverse_visitor
{
/// <summary>A traverse visitor, overriding all abstract methods with AST visiting code.</summary>
class AstVisitor
: public vl::Object
, protected virtual XmlNode::IVisitor
{
protected:
virtual void Traverse(vl::glr::ParsingToken& token);
virtual void Traverse(vl::glr::ParsingAstBase* node);
virtual void Traverse(XmlAttribute* node);
virtual void Traverse(XmlCData* node);
virtual void Traverse(XmlComment* node);
virtual void Traverse(XmlDocument* node);
virtual void Traverse(XmlElement* node);
virtual void Traverse(XmlInstruction* node);
virtual void Traverse(XmlNode* node);
virtual void Traverse(XmlText* node);
protected:
virtual void Finishing(vl::glr::ParsingAstBase* node);
virtual void Finishing(XmlAttribute* node);
virtual void Finishing(XmlCData* node);
virtual void Finishing(XmlComment* node);
virtual void Finishing(XmlDocument* node);
virtual void Finishing(XmlElement* node);
virtual void Finishing(XmlInstruction* node);
virtual void Finishing(XmlNode* node);
virtual void Finishing(XmlText* node);
protected:
void Visit(XmlText* node) override;
void Visit(XmlCData* node) override;
void Visit(XmlComment* node) override;
void Visit(XmlElement* node) override;
void Visit(XmlInstruction* node) override;
void Visit(XmlDocument* node) override;
public:
void InspectInto(XmlNode* node);
void InspectInto(XmlAttribute* node);
};
}
}
}
}
#endif
/***********************************************************************
.\XML\GENERATED\XML_ASSEMBLER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Xml
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_XML_AST_ASSEMBLER
#define VCZH_PARSER2_BUILTIN_XML_AST_ASSEMBLER
namespace vl
{
namespace glr
{
namespace xml
{
enum class XmlClasses : vl::vint32_t
{
Attribute = 0,
CData = 1,
Comment = 2,
Document = 3,
Element = 4,
Instruction = 5,
Node = 6,
Text = 7,
};
enum class XmlFields : vl::vint32_t
{
Attribute_name = 0,
Attribute_value = 1,
CData_content = 2,
Comment_content = 3,
Document_prologs = 4,
Document_rootElement = 5,
Element_attributes = 6,
Element_closingName = 7,
Element_name = 8,
Element_subNodes = 9,
Instruction_attributes = 10,
Instruction_name = 11,
Text_content = 12,
};
extern const wchar_t* XmlTypeName(XmlClasses type);
extern const wchar_t* XmlCppTypeName(XmlClasses type);
extern const wchar_t* XmlFieldName(XmlFields field);
extern const wchar_t* XmlCppFieldName(XmlFields field);
class XmlAstInsReceiver : public vl::glr::AstInsReceiverBase
{
protected:
vl::Ptr<vl::glr::ParsingAstBase> CreateAstNode(vl::vint32_t type) override;
void SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::Ptr<vl::glr::ParsingAstBase> value) override;
void SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, const vl::regex::RegexToken& token, vl::vint32_t tokenIndex) override;
void SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::vint32_t enumItem) override;
vl::Ptr<vl::glr::ParsingAstBase> ResolveAmbiguity(vl::vint32_t type, vl::collections::Array<vl::Ptr<vl::glr::ParsingAstBase>>& candidates) override;
};
}
}
}
#endif
/***********************************************************************
.\XML\GENERATED\XML_LEXER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Xml
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_XML_LEXER
#define VCZH_PARSER2_BUILTIN_XML_LEXER
namespace vl
{
namespace glr
{
namespace xml
{
enum class XmlTokens : vl::vint32_t
{
INSTRUCTION_OPEN = 0,
INSTRUCTION_CLOSE = 1,
COMPLEX_ELEMENT_OPEN = 2,
SINGLE_ELEMENT_CLOSE = 3,
ELEMENT_OPEN = 4,
ELEMENT_CLOSE = 5,
EQUAL = 6,
NAME = 7,
ATTVALUE = 8,
COMMENT = 9,
CDATA = 10,
TEXT = 11,
SPACE = 12,
};
constexpr vl::vint XmlTokenCount = 13;
extern bool XmlTokenDeleter(vl::vint token);
extern const wchar_t* XmlTokenId(XmlTokens token);
extern const wchar_t* XmlTokenDisplayText(XmlTokens token);
extern const wchar_t* XmlTokenRegex(XmlTokens token);
extern void XmlLexerData(vl::stream::IStream& outputStream);
}
}
}
#endif
/***********************************************************************
.\XML\GENERATED\XMLPARSER.H
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:Xml
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_XML_PARSER_SYNTAX
#define VCZH_PARSER2_BUILTIN_XML_PARSER_SYNTAX
namespace vl
{
namespace glr
{
namespace xml
{
enum class ParserStates
{
XAttribute = 0,
XText = 5,
XCData = 11,
XComment = 14,
XElement = 17,
XSubNode = 28,
XInstruction = 34,
XDocument = 40,
};
const wchar_t* ParserRuleName(vl::vint index);
const wchar_t* ParserStateLabel(vl::vint index);
extern void XmlParserData(vl::stream::IStream& outputStream);
class Parser
: public vl::glr::ParserBase<XmlTokens, ParserStates, XmlAstInsReceiver> , protected vl::glr::automaton::TraceManager::ITypeCallback
{
protected:
vl::vint32_t FindCommonBaseClass(vl::vint32_t class1, vl::vint32_t class2) const override;
public:
Parser();
vl::Ptr<vl::glr::xml::XmlElement> ParseXElement(const vl::WString& input, vl::vint codeIndex = -1) const;
vl::Ptr<vl::glr::xml::XmlElement> ParseXElement(vl::collections::List<vl::regex::RegexToken>& tokens, vl::vint codeIndex = -1) const;
vl::Ptr<vl::glr::xml::XmlDocument> ParseXDocument(const vl::WString& input, vl::vint codeIndex = -1) const;
vl::Ptr<vl::glr::xml::XmlDocument> ParseXDocument(vl::collections::List<vl::regex::RegexToken>& tokens, vl::vint codeIndex = -1) const;
};
}
}
}
#endif
/***********************************************************************
.\XML\GLRXML.H
***********************************************************************/
/***********************************************************************
Vczh Library++ 3.0
Developer: Zihan Chen(vczh)
Parser::ParsingXml
***********************************************************************/
#ifndef VCZH_PARSER2_BUILTIN_XML
#define VCZH_PARSER2_BUILTIN_XML
namespace vl
{
namespace glr
{
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>Deserialize XML document from string.</summary>
/// <returns>The deserialized XML node.</returns>
/// <param name="input">The XML code.</param>
/// <param name="parser">The generated parser.</param>
extern Ptr<XmlDocument> XmlParseDocument(const WString& input, const Parser& parser);
/// <summary>Deserialize XML element from string.</summary>
/// <returns>The deserialized XML node.</returns>
/// <param name="input">The XML code.</param>
/// <param name="parser">The generated parser.</param>
extern Ptr<XmlElement> XmlParseElement(const WString& input, const Parser& parser);
/// <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