Files
GacUI/Import/VlppGlrParserCompiler.cpp
2021-12-28 06:41:40 -08:00

10164 lines
358 KiB
C++

/***********************************************************************
THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY
DEVELOPER: Zihan Chen(vczh)
***********************************************************************/
#include "VlppGlrParserCompiler.h"
/***********************************************************************
.\AST\ASTCPPGEN.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace stream;
/***********************************************************************
GenerateAstFileNames
***********************************************************************/
void GenerateAstFileNames(AstSymbolManager& manager, Ptr<CppParserGenOutput> parserOutput)
{
for (auto file : manager.Files().Values())
{
auto astOutput = MakePtr<CppAstGenOutput>();
astOutput->astH = file->Owner()->Global().name + file->Name() + L".h";
astOutput->astCpp = file->Owner()->Global().name + file->Name() + L".cpp";
astOutput->builderH = file->Owner()->Global().name + file->Name() + L"_Builder.h";
astOutput->builderCpp = file->Owner()->Global().name + file->Name() + L"_Builder.cpp";
astOutput->emptyH = file->Owner()->Global().name + file->Name() + L"_Empty.h";
astOutput->emptyCpp = file->Owner()->Global().name + file->Name() + L"_Empty.cpp";
astOutput->copyH = file->Owner()->Global().name + file->Name() + L"_Copy.h";
astOutput->copyCpp = file->Owner()->Global().name + file->Name() + L"_Copy.cpp";
astOutput->traverseH = file->Owner()->Global().name + file->Name() + L"_Traverse.h";
astOutput->traverseCpp = file->Owner()->Global().name + file->Name() + L"_Traverse.cpp";
astOutput->jsonH = file->Owner()->Global().name + file->Name() + L"_Json.h";
astOutput->jsonCpp = file->Owner()->Global().name + file->Name() + L"_Json.cpp";
parserOutput->astOutputs.Add(file, astOutput);
}
}
/***********************************************************************
Utility
***********************************************************************/
void CollectVisitorsAndConcreteClasses(AstDefFile* file, List<AstClassSymbol*>& visitors, List<AstClassSymbol*>& concreteClasses)
{
for (auto name : file->SymbolOrder())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(file->Symbols()[name]))
{
if (classSymbol->derivedClasses.Count() > 0)
{
visitors.Add(classSymbol);
}
if (!classSymbol->baseClass && classSymbol->derivedClasses.Count() == 0)
{
concreteClasses.Add(classSymbol);
}
}
}
}
/***********************************************************************
Forward Declarations
***********************************************************************/
extern void WriteTypeForwardDefinitions(AstDefFile* file, const WString& prefix, stream::StreamWriter& writer);
extern void WriteTypeDefinitions(AstDefFile* file, const WString& prefix, stream::StreamWriter& writer);
extern void WriteVisitorImpl(AstDefFile* file, const WString& prefix, stream::StreamWriter& writer);
extern void WriteTypeReflectionDeclaration(AstDefFile* file, const WString& prefix, stream::StreamWriter& writer);
extern void WriteTypeReflectionImplementation(AstDefFile* file, const WString& prefix, stream::StreamWriter& writer);
/***********************************************************************
WriteAstHeaderFile
***********************************************************************/
void WriteAstHeaderFile(AstDefFile* file, stream::StreamWriter& writer)
{
WriteFileComment(file->Name(), writer);
auto&& headerGuard = file->Owner()->Global().headerGuard;
if (headerGuard != L"")
{
writer.WriteString(L"#ifndef ");
writer.WriteLine(headerGuard + L"_" + wupper(file->Name()) + L"_AST");
writer.WriteString(L"#define ");
writer.WriteLine(headerGuard + L"_" + wupper(file->Name()) + L"_AST");
}
else
{
writer.WriteLine(L"#pragma once");
}
writer.WriteLine(L"");
for (auto include : file->Owner()->Global().includes)
{
if (include.Length() > 0 && include[0] == L'<')
{
writer.WriteLine(L"#include " + include);
}
else
{
writer.WriteLine(L"#include \"" + include + L"\"");
}
}
writer.WriteLine(L"");
{
WString prefix = WriteNssBegin(file->cppNss, writer);
WriteTypeForwardDefinitions(file, prefix, writer);
WriteTypeDefinitions(file, prefix, writer);
WriteNssEnd(file->cppNss, writer);
}
{
List<WString> refNss;
refNss.Add(L"vl");
refNss.Add(L"reflection");
refNss.Add(L"description");
WString prefix = WriteNssBegin(refNss, writer);
WriteTypeReflectionDeclaration(file, prefix, writer);
WriteNssEnd(refNss, writer);
}
if (headerGuard != L"")
{
writer.WriteString(L"#endif");
}
}
/***********************************************************************
WriteAstCppFile
***********************************************************************/
void WriteAstCppFile(AstDefFile* file, const WString& astHeaderName, stream::StreamWriter& writer)
{
WriteFileComment(file->Name(), writer);
writer.WriteLine(L"#include \"" + astHeaderName + L"\"");
writer.WriteLine(L"");
{
WString prefix = WriteNssBegin(file->cppNss, writer);
writer.WriteLine(L"/***********************************************************************");
writer.WriteLine(L"Visitor Pattern Implementation");
writer.WriteLine(L"***********************************************************************/");
WriteVisitorImpl(file, prefix, writer);
WriteNssEnd(file->cppNss, writer);
}
{
List<WString> refNss;
refNss.Add(L"vl");
refNss.Add(L"reflection");
refNss.Add(L"description");
WString prefix = WriteNssBegin(refNss, writer);
WriteTypeReflectionImplementation(file, prefix, writer);
WriteNssEnd(refNss, writer);
}
}
/***********************************************************************
WriteAstUtilityHeaderFile
***********************************************************************/
void WriteAstUtilityHeaderFile(
AstDefFile* file,
Ptr<CppAstGenOutput> output,
const WString& extraNss,
stream::StreamWriter& writer,
Func<void(const WString&)> callback
)
{
WriteFileComment(file->Name(), writer);
auto&& headerGuard = file->Owner()->Global().headerGuard;
if (headerGuard != L"")
{
writer.WriteString(L"#ifndef ");
writer.WriteLine(headerGuard + L"_" + wupper(file->Name()) + L"_AST_" + wupper(extraNss));
writer.WriteString(L"#define ");
writer.WriteLine(headerGuard + L"_" + wupper(file->Name()) + L"_AST_" + wupper(extraNss));
}
else
{
writer.WriteLine(L"#pragma once");
}
writer.WriteLine(L"");
writer.WriteLine(L"#include \"" + output->astH + L"\"");
writer.WriteLine(L"");
{
List<WString> cppNss;
CopyFrom(cppNss, file->cppNss);
cppNss.Add(extraNss);
WString prefix = WriteNssBegin(cppNss, writer);
callback(prefix);
WriteNssEnd(cppNss, writer);
}
if (headerGuard != L"")
{
writer.WriteString(L"#endif");
}
}
/***********************************************************************
WriteAstUtilityCppFile
***********************************************************************/
void WriteAstUtilityCppFile(
AstDefFile* file,
const WString& utilityHeaderFile,
const WString& extraNss,
stream::StreamWriter& writer,
Func<void(const WString&)> callback
)
{
WriteFileComment(file->Name(), writer);
writer.WriteLine(L"#include \"" + utilityHeaderFile + L"\"");
writer.WriteLine(L"");
{
List<WString> cppNss;
CopyFrom(cppNss, file->cppNss);
cppNss.Add(extraNss);
WString prefix = WriteNssBegin(cppNss, writer);
callback(prefix);
WriteNssEnd(cppNss, writer);
}
}
/***********************************************************************
WriteParserUtilityHeaderFile
***********************************************************************/
void WriteParserUtilityHeaderFile(
AstSymbolManager& manager,
Ptr<CppParserGenOutput> output,
const WString& guardPostfix,
stream::StreamWriter& writer,
Func<void(const WString&)> callback
)
{
WriteFileComment(manager.Global().name, writer);
if (manager.Global().headerGuard != L"")
{
writer.WriteString(L"#ifndef ");
writer.WriteLine(manager.Global().headerGuard + L"_AST_" + guardPostfix);
writer.WriteString(L"#define ");
writer.WriteLine(manager.Global().headerGuard + L"_AST_" + guardPostfix);
}
else
{
writer.WriteLine(L"#pragma once");
}
writer.WriteLine(L"");
for (auto file : manager.Files().Values())
{
writer.WriteLine(L"#include \"" + output->astOutputs[file]->astH + L"\"");
}
writer.WriteLine(L"");
WString prefix = WriteNssBegin(manager.Global().cppNss, writer);
callback(prefix);
WriteNssEnd(manager.Global().cppNss, writer);
if (manager.Global().headerGuard != L"")
{
writer.WriteString(L"#endif");
}
}
/***********************************************************************
WriteParserUtilityCppFile
***********************************************************************/
void WriteParserUtilityCppFile(
AstSymbolManager& manager,
const WString& utilityHeaderFile,
stream::StreamWriter& writer,
Func<void(const WString&)> callback
)
{
WriteFileComment(manager.Global().name, writer);
writer.WriteLine(L"#include \"" + utilityHeaderFile + L"\"");
writer.WriteLine(L"");
WString prefix = WriteNssBegin(manager.Global().cppNss, writer);
callback(prefix);
WriteNssEnd(manager.Global().cppNss, writer);
}
/***********************************************************************
WriteAstFiles
***********************************************************************/
void WriteAstFiles(AstDefFile* file, Ptr<CppAstGenOutput> output, collections::Dictionary<WString, WString>& files)
{
{
WString fileH = GenerateToStream([&](StreamWriter& writer)
{
WriteAstHeaderFile(file, writer);
});
WString fileCpp = GenerateToStream([&](StreamWriter& writer)
{
WriteAstCppFile(file, output->astH, writer);
});
files.Add(output->astH, fileH);
files.Add(output->astCpp, fileCpp);
}
{
WString fileH = GenerateToStream([&](StreamWriter& writer)
{
WriteAstBuilderHeaderFile(file, output, writer);
});
WString fileCpp = GenerateToStream([&](StreamWriter& writer)
{
WriteAstBuilderCppFile(file, output, writer);
});
files.Add(output->builderH, fileH);
files.Add(output->builderCpp, fileCpp);
}
{
WString fileH = GenerateToStream([&](StreamWriter& writer)
{
WriteEmptyVisitorHeaderFile(file, output, writer);
});
WString fileCpp = GenerateToStream([&](StreamWriter& writer)
{
WriteEmptyVisitorCppFile(file, output, writer);
});
files.Add(output->emptyH, fileH);
files.Add(output->emptyCpp, fileCpp);
}
{
WString fileH = GenerateToStream([&](StreamWriter& writer)
{
WriteCopyVisitorHeaderFile(file, output, writer);
});
WString fileCpp = GenerateToStream([&](StreamWriter& writer)
{
WriteCopyVisitorCppFile(file, output, writer);
});
files.Add(output->copyH, fileH);
files.Add(output->copyCpp, fileCpp);
}
{
WString fileH = GenerateToStream([&](StreamWriter& writer)
{
WriteTraverseVisitorHeaderFile(file, output, writer);
});
WString fileCpp = GenerateToStream([&](StreamWriter& writer)
{
WriteTraverseVisitorCppFile(file, output, writer);
});
files.Add(output->traverseH, fileH);
files.Add(output->traverseCpp, fileCpp);
}
{
WString fileH = GenerateToStream([&](StreamWriter& writer)
{
WriteJsonVisitorHeaderFile(file, output, writer);
});
WString fileCpp = GenerateToStream([&](StreamWriter& writer)
{
WriteJsonVisitorCppFile(file, output, writer);
});
files.Add(output->jsonH, fileH);
files.Add(output->jsonCpp, fileCpp);
}
}
void WriteAstFiles(AstSymbolManager& manager, Ptr<CppParserGenOutput> output, collections::Dictionary<WString, WString>& files)
{
for (auto file : manager.Files().Values())
{
WriteAstFiles(file, output->astOutputs[file], files);
}
{
WString fileH = GenerateToStream([&](StreamWriter& writer)
{
WriteAstAssemblerHeaderFile(manager, output, writer);
});
WString fileCpp = GenerateToStream([&](StreamWriter& writer)
{
WriteAstAssemblerCppFile(manager, output, writer);
});
files.Add(output->assemblyH, fileH);
files.Add(output->assemblyCpp, fileCpp);
}
}
}
}
}
/***********************************************************************
.\AST\ASTCPPGEN_ASSEMBLER.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace stream;
extern void PrintCppType(AstDefFile* fileContext, AstSymbol* propSymbol, stream::StreamWriter& writer);
/***********************************************************************
WriteAstAssemblerHeaderFile
***********************************************************************/
void WriteAstAssemblerHeaderFile(AstSymbolManager& manager, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer)
{
WriteParserUtilityHeaderFile(manager, output, L"ASSEMBLER", writer, [&](const WString& prefix)
{
{
vint index = 0;
writer.WriteLine(prefix + L"enum class " + manager.Global().name + L"Classes : vl::vint32_t");
writer.WriteLine(prefix + L"{");
for (auto typeSymbol : manager.Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
output->classIds.Add(classSymbol, (vint32_t)index);
writer.WriteLine(prefix + L"\t" + classSymbol->Name() + L" = " + itow(index) + L",");
index++;
}
}
writer.WriteLine(prefix + L"};");
}
{
vint index = 0;
writer.WriteLine(L"");
writer.WriteLine(prefix + L"enum class " + manager.Global().name + L"Fields : vl::vint32_t");
writer.WriteLine(prefix + L"{");
for (auto typeSymbol : manager.Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
for (auto propSymbol : classSymbol->Props().Values())
{
output->fieldIds.Add(propSymbol, (vint32_t)index);
writer.WriteLine(prefix + L"\t" + classSymbol->Name() + L"_" + propSymbol->Name() + L" = " + itow(index) + L",");
index++;
}
}
}
writer.WriteLine(prefix + L"};");
}
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"extern const wchar_t* " + manager.Global().name + L"TypeName(" + manager.Global().name + L"Classes type);");
writer.WriteLine(prefix + L"extern const wchar_t* " + manager.Global().name + L"CppTypeName(" + manager.Global().name + L"Classes type);");
writer.WriteLine(prefix + L"extern const wchar_t* " + manager.Global().name + L"FieldName(" + manager.Global().name + L"Fields field);");
writer.WriteLine(prefix + L"extern const wchar_t* " + manager.Global().name + L"CppFieldName(" + manager.Global().name + L"Fields field);");
}
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"class " + manager.Global().name + L"AstInsReceiver : public vl::glr::AstInsReceiverBase");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"protected:");
writer.WriteLine(prefix + L"\tvl::Ptr<vl::glr::ParsingAstBase> CreateAstNode(vl::vint32_t type) override;");
writer.WriteLine(prefix + L"\tvoid SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::Ptr<vl::glr::ParsingAstBase> value) override;");
writer.WriteLine(prefix + L"\tvoid SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, const vl::regex::RegexToken& token, vl::vint32_t tokenIndex) override;");
writer.WriteLine(prefix + L"\tvoid SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::vint32_t enumItem) override;");
writer.WriteLine(prefix + L"\tvl::Ptr<vl::glr::ParsingAstBase> ResolveAmbiguity(vl::vint32_t type, vl::collections::Array<vl::Ptr<vl::glr::ParsingAstBase>>& candidates) override;");
writer.WriteLine(prefix + L"};");
}
});
}
/***********************************************************************
WriteAstAssemblerCppFile
***********************************************************************/
void WriteAstAssemblerCppFile(AstSymbolManager& manager, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer)
{
WriteParserUtilityCppFile(manager, output->assemblyH, writer, [&](const WString& prefix)
{
writer.WriteLine(L"");
writer.WriteLine(L"/***********************************************************************");
writer.WriteLine(manager.Global().name + L"AstInsReceiver : public vl::glr::AstInsReceiverBase");
writer.WriteLine(L"***********************************************************************/");
/***********************************************************************
CreateAstNode
***********************************************************************/
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"vl::Ptr<vl::glr::ParsingAstBase> " + manager.Global().name + L"AstInsReceiver::CreateAstNode(vl::vint32_t type)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tauto cppTypeName = " + manager.Global().name + L"CppTypeName((" + manager.Global().name + L"Classes)type);");
writer.WriteLine(prefix + L"\tswitch((" + manager.Global().name + L"Classes)type)");
writer.WriteLine(prefix + L"\t{");
for (auto typeSymbol : manager.Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
if (classSymbol->derivedClasses.Count() == 0)
{
writer.WriteLine(prefix + L"\tcase " + manager.Global().name + L"Classes::" + classSymbol->Name() + L":");
writer.WriteString(prefix + L"\t\treturn new ");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteLine(L"();");
}
}
}
writer.WriteLine(prefix + L"\tdefault:");
writer.WriteLine(prefix + L"\t\treturn vl::glr::AssemblyThrowCannotCreateAbstractType(type, cppTypeName);");
writer.WriteLine(prefix + L"\t}");
writer.WriteLine(prefix + L"}");
}
/***********************************************************************
SetField(Object)
***********************************************************************/
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"void " + manager.Global().name + L"AstInsReceiver::SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::Ptr<vl::glr::ParsingAstBase> value)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tauto cppFieldName = " + manager.Global().name + L"CppFieldName((" + manager.Global().name + L"Fields)field);");
List<AstClassPropSymbol*> props;
for (auto typeSymbol : manager.Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
for (auto [propSymbol, index] : indexed(classSymbol->Props().Values()))
{
if (propSymbol->propType != AstPropType::Token)
{
if (dynamic_cast<AstClassSymbol*>(propSymbol->propSymbol))
{
props.Add(propSymbol);
}
}
}
}
}
if (props.Count() > 0)
{
writer.WriteLine(prefix + L"\tswitch((" + manager.Global().name + L"Fields)field)");
writer.WriteLine(prefix + L"\t{");
for (auto propSymbol : props)
{
auto classSymbol = propSymbol->Parent();
writer.WriteLine(prefix + L"\tcase " + manager.Global().name + L"Fields::" + classSymbol->Name() + L"_" + propSymbol->Name() + L":");
writer.WriteString(prefix + L"\t\treturn vl::glr::AssemblerSetObjectField(&");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteString(L"::");
writer.WriteString(propSymbol->Name());
writer.WriteLine(L", object, field, value, cppFieldName);");
}
writer.WriteLine(prefix + L"\tdefault:");
writer.WriteLine(prefix + L"\t\treturn vl::glr::AssemblyThrowFieldNotObject(field, cppFieldName);");
writer.WriteLine(prefix + L"\t}");
}
else
{
writer.WriteLine(prefix + L"\treturn vl::glr::AssemblyThrowFieldNotObject(field, cppFieldName);");
}
writer.WriteLine(prefix + L"}");
}
/***********************************************************************
SetField(Token)
***********************************************************************/
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"void " + manager.Global().name + L"AstInsReceiver::SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, const vl::regex::RegexToken& token, vl::vint32_t tokenIndex)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tauto cppFieldName = " + manager.Global().name + L"CppFieldName((" + manager.Global().name + L"Fields)field);");
List<AstClassPropSymbol*> props;
for (auto typeSymbol : manager.Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
for (auto [propSymbol, index] : indexed(classSymbol->Props().Values()))
{
if (propSymbol->propType == AstPropType::Token)
{
props.Add(propSymbol);
}
}
}
}
if (props.Count() > 0)
{
writer.WriteLine(prefix + L"\tswitch((" + manager.Global().name + L"Fields)field)");
writer.WriteLine(prefix + L"\t{");
for (auto propSymbol : props)
{
auto classSymbol = propSymbol->Parent();
writer.WriteLine(prefix + L"\tcase " + manager.Global().name + L"Fields::" + classSymbol->Name() + L"_" + propSymbol->Name() + L":");
writer.WriteString(prefix + L"\t\treturn vl::glr::AssemblerSetTokenField(&");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteString(L"::");
writer.WriteString(propSymbol->Name());
writer.WriteLine(L", object, field, token, tokenIndex, cppFieldName);");
}
writer.WriteLine(prefix + L"\tdefault:");
writer.WriteLine(prefix + L"\t\treturn vl::glr::AssemblyThrowFieldNotToken(field, cppFieldName);");
writer.WriteLine(prefix + L"\t}");
}
else
{
writer.WriteLine(prefix + L"\treturn vl::glr::AssemblyThrowFieldNotToken(field, cppFieldName);");
}
writer.WriteLine(prefix + L"}");
}
/***********************************************************************
SetField(Enum)
***********************************************************************/
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"void " + manager.Global().name + L"AstInsReceiver::SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::vint32_t enumItem)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tauto cppFieldName = " + manager.Global().name + L"CppFieldName((" + manager.Global().name + L"Fields)field);");
List<AstClassPropSymbol*> props;
for (auto typeSymbol : manager.Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
for (auto [propSymbol, index] : indexed(classSymbol->Props().Values()))
{
if (propSymbol->propType == AstPropType::Type)
{
if (dynamic_cast<AstEnumSymbol*>(propSymbol->propSymbol))
{
props.Add(propSymbol);
}
}
}
}
}
if (props.Count() > 0)
{
writer.WriteLine(prefix + L"\tswitch((" + manager.Global().name + L"Fields)field)");
writer.WriteLine(prefix + L"\t{");
for (auto propSymbol : props)
{
auto classSymbol = propSymbol->Parent();
writer.WriteLine(prefix + L"\tcase " + manager.Global().name + L"Fields::" + classSymbol->Name() + L"_" + propSymbol->Name() + L":");
writer.WriteString(prefix + L"\t\treturn vl::glr::AssemblerSetEnumField(&");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteString(L"::");
writer.WriteString(propSymbol->Name());
writer.WriteLine(L", object, field, enumItem, cppFieldName);");
}
writer.WriteLine(prefix + L"\tdefault:");
writer.WriteLine(prefix + L"\t\treturn vl::glr::AssemblyThrowFieldNotEnum(field, cppFieldName);");
writer.WriteLine(prefix + L"\t}");
}
else
{
writer.WriteLine(prefix + L"\treturn vl::glr::AssemblyThrowFieldNotEnum(field, cppFieldName);");
}
writer.WriteLine(prefix + L"}");
}
/***********************************************************************
TypeName
***********************************************************************/
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"const wchar_t* " + manager.Global().name + L"TypeName(" + manager.Global().name + L"Classes type)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tconst wchar_t* results[] = {");
Array<AstClassSymbol*> idToClasses(output->classIds.Count());
for (auto [k, v] : output->classIds)
{
idToClasses[v] = k;
}
for (auto classSymbol : idToClasses)
{
writer.WriteLine(prefix + L"\t\tL\"" + classSymbol->Name() + L"\",");
}
writer.WriteLine(prefix + L"\t};");
writer.WriteLine(prefix + L"\tvl::vint index = (vl::vint)type;");
writer.WriteLine(prefix + L"\treturn 0 <= index && index < " + itow(idToClasses.Count()) + L" ? results[index] : nullptr;");
writer.WriteLine(prefix + L"}");
}
/***********************************************************************
CppTypeName
***********************************************************************/
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"const wchar_t* " + manager.Global().name + L"CppTypeName(" + manager.Global().name + L"Classes type)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tconst wchar_t* results[] = {");
Array<AstClassSymbol*> idToClasses(output->classIds.Count());
for (auto [k, v] : output->classIds)
{
idToClasses[v] = k;
}
for (auto classSymbol : idToClasses)
{
writer.WriteString(prefix + L"\t\tL\"");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteLine(L"\",");
}
writer.WriteLine(prefix + L"\t};");
writer.WriteLine(prefix + L"\tvl::vint index = (vl::vint)type;");
writer.WriteLine(prefix + L"\treturn 0 <= index && index < " + itow(idToClasses.Count()) + L" ? results[index] : nullptr;");
writer.WriteLine(prefix + L"}");
}
/***********************************************************************
FieldName
***********************************************************************/
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"const wchar_t* " + manager.Global().name + L"FieldName(" + manager.Global().name + L"Fields field)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tconst wchar_t* results[] = {");
Array<AstClassPropSymbol*> idToFields(output->fieldIds.Count());
for (auto [k, v] : output->fieldIds)
{
idToFields[v] = k;
}
for (auto propSymbol : idToFields)
{
auto classSymbol = propSymbol->Parent();
writer.WriteLine(prefix + L"\t\tL\"" + classSymbol->Name() + L"::" + propSymbol->Name() + L"\",");
}
writer.WriteLine(prefix + L"\t};");
writer.WriteLine(prefix + L"\tvl::vint index = (vl::vint)field;");
writer.WriteLine(prefix + L"\treturn 0 <= index && index < " + itow(idToFields.Count()) + L" ? results[index] : nullptr;");
writer.WriteLine(prefix + L"}");
}
/***********************************************************************
CppFieldName
***********************************************************************/
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"const wchar_t* " + manager.Global().name + L"CppFieldName(" + manager.Global().name + L"Fields field)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tconst wchar_t* results[] = {");
Array<AstClassPropSymbol*> idToFields(output->fieldIds.Count());
for (auto [k, v] : output->fieldIds)
{
idToFields[v] = k;
}
for (auto propSymbol : idToFields)
{
auto classSymbol = propSymbol->Parent();
writer.WriteString(prefix + L"\t\tL\"");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteLine(L"::" + propSymbol->Name() + L"\",");
}
writer.WriteLine(prefix + L"\t};");
writer.WriteLine(prefix + L"\tvl::vint index = (vl::vint)field;");
writer.WriteLine(prefix + L"\treturn 0 <= index && index < " + itow(idToFields.Count()) + L" ? results[index] : nullptr;");
writer.WriteLine(prefix + L"}");
}
/***********************************************************************
ResolveAmbiguity
***********************************************************************/
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"vl::Ptr<vl::glr::ParsingAstBase> " + manager.Global().name + L"AstInsReceiver::ResolveAmbiguity(vl::vint32_t type, vl::collections::Array<vl::Ptr<vl::glr::ParsingAstBase>>& candidates)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tauto cppTypeName = " + manager.Global().name + L"CppTypeName((" + manager.Global().name + L"Classes)type);");
Dictionary<AstClassSymbol*, AstClassSymbol*> resolvables;
for (auto typeSymbol : manager.Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
auto current = classSymbol;
while (current)
{
if (current->ambiguousDerivedClass)
{
resolvables.Add(classSymbol, current->ambiguousDerivedClass);
break;
}
current = current->baseClass;
}
}
}
if (resolvables.Count() > 0)
{
writer.WriteLine(prefix + L"\tswitch((" + manager.Global().name + L"Classes)type)");
writer.WriteLine(prefix + L"\t{");
for (auto typeSymbol : manager.Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
if (resolvables.Keys().Contains(classSymbol))
{
auto ambiguousClassSymbol = resolvables[classSymbol];
writer.WriteLine(prefix + L"\tcase " + manager.Global().name + L"Classes::" + classSymbol->Name() + L":");
writer.WriteString(prefix + L"\t\treturn vl::glr::AssemblerResolveAmbiguity<");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteString(L", ");
PrintCppType(nullptr, ambiguousClassSymbol, writer);
writer.WriteLine(L">(type, candidates, cppTypeName);");
}
}
}
writer.WriteLine(prefix + L"\tdefault:");
writer.WriteLine(prefix + L"\t\treturn vl::glr::AssemblyThrowTypeNotAllowAmbiguity(type, cppTypeName);");
writer.WriteLine(prefix + L"\t}");
}
else
{
writer.WriteLine(prefix + L"\treturn vl::glr::AssemblyThrowTypeNotAllowAmbiguity(type, cppTypeName);");
}
writer.WriteLine(prefix + L"}");
}
});
}
}
}
}
/***********************************************************************
.\AST\ASTCPPGEN_BUILDER.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace stream;
extern void PrintCppType(AstDefFile* fileContext, AstSymbol* propSymbol, stream::StreamWriter& writer);
/***********************************************************************
WriteAstBuilderHeaderFile
***********************************************************************/
void WriteAstBuilderHeaderFile(AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer)
{
WriteAstUtilityHeaderFile(file, output, L"builder", writer, [&](const WString& prefix)
{
for(auto typeSymbol : file->Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
if (classSymbol->Props().Count() > 0)
{
WString className = L"Make" + classSymbol->Name();
writer.WriteString(prefix + L"class " + className);
writer.WriteString(L" : public vl::glr::ParsingAstBuilder<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L">");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"public:");
auto currentClass = classSymbol;
while (currentClass)
{
for (auto propSymbol : currentClass->Props().Values())
{
switch (propSymbol->propType)
{
case AstPropType::Token:
writer.WriteLine(prefix + L"\t" + className + L"& " + propSymbol->Name() + L"(const vl::WString& value);");
break;
case AstPropType::Type:
if (dynamic_cast<AstEnumSymbol*>(propSymbol->propSymbol))
{
writer.WriteString(prefix + L"\t" + className + L"& " + propSymbol->Name() + L"(");
PrintCppType(file, propSymbol->propSymbol, writer);
writer.WriteLine(L" value);");
break;
}
case AstPropType::Array:
writer.WriteString(prefix + L"\t" + className + L"& " + propSymbol->Name() + L"(const vl::Ptr<");
PrintCppType(file, propSymbol->propSymbol, writer);
writer.WriteLine(L">& value);");
break;
}
}
currentClass = currentClass->baseClass;
}
writer.WriteLine(prefix + L"};");
writer.WriteLine(L"");
}
}
}
});
}
/***********************************************************************
WriteAstBuilderCppFile
***********************************************************************/
void WriteAstBuilderCppFile(AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer)
{
WriteAstUtilityCppFile(file, output->builderH, L"builder", writer, [&](const WString& prefix)
{
for (auto typeSymbol : file->Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
if (classSymbol->Props().Count() > 0)
{
WString className = L"Make" + classSymbol->Name();
writer.WriteLine(L"");
writer.WriteLine(L"/***********************************************************************");
writer.WriteLine(className);
writer.WriteLine(L"***********************************************************************/");
auto currentClass = classSymbol;
while (currentClass)
{
for (auto propSymbol : currentClass->Props().Values())
{
writer.WriteLine(L"");
switch (propSymbol->propType)
{
case AstPropType::Token:
writer.WriteLine(prefix + className + L"& " + className + L"::" + propSymbol->Name() + L"(const vl::WString& value)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tnode->" + propSymbol->Name() + L".value = value;");
writer.WriteLine(prefix + L"\treturn *this;");
writer.WriteLine(prefix + L"}");
break;
case AstPropType::Type:
if (dynamic_cast<AstEnumSymbol*>(propSymbol->propSymbol))
{
writer.WriteString(prefix + className + L"& " + className + L"::" + propSymbol->Name() + L"(");
PrintCppType(file, propSymbol->propSymbol, writer);
writer.WriteLine(L" value)");
}
if (dynamic_cast<AstClassSymbol*>(propSymbol->propSymbol))
{
writer.WriteString(prefix + className + L"& " + className + L"::" + propSymbol->Name() + L"(const vl::Ptr<");
PrintCppType(file, propSymbol->propSymbol, writer);
writer.WriteLine(L">& value)");
}
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tnode->" + propSymbol->Name() + L" = value;");
writer.WriteLine(prefix + L"\treturn *this;");
writer.WriteLine(prefix + L"}");
break;
case AstPropType::Array:
writer.WriteString(prefix + className + L"& " + className + L"::" + propSymbol->Name() + L"(const vl::Ptr<");
PrintCppType(file, propSymbol->propSymbol, writer);
writer.WriteLine(L">& value)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tnode->" + propSymbol->Name() + L".Add(value);");
writer.WriteLine(prefix + L"\treturn *this;");
writer.WriteLine(prefix + L"}");
break;
}
}
currentClass = currentClass->baseClass;
}
}
}
}
});
}
}
}
}
/***********************************************************************
.\AST\ASTCPPGEN_CLASSES.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace stream;
/***********************************************************************
WriteTypeForwardDefinitions
***********************************************************************/
void WriteTypeForwardDefinitions(AstDefFile* file, const WString& prefix, stream::StreamWriter& writer)
{
for (auto [name, index] : indexed(file->Symbols().Keys()))
{
if (dynamic_cast<AstClassSymbol*>(file->Symbols().Values()[index]))
{
writer.WriteString(prefix);
writer.WriteString(L"class ");
writer.WriteString(file->classPrefix);
writer.WriteString(name);
writer.WriteLine(L";");
}
}
}
/***********************************************************************
PrintCppType
***********************************************************************/
void PrintNss(List<WString>& nss, stream::StreamWriter& writer)
{
for (auto&& ns : nss)
{
writer.WriteString(ns);
writer.WriteString(L"::");
}
}
enum class PrintTypePurpose
{
TypeName,
ReflectionName,
Value,
};
void PrintAstType(AstDefFile* fileContext, AstPropType propType, AstSymbol* propSymbol, PrintTypePurpose purpose, stream::StreamWriter& writer)
{
if (propType == AstPropType::Token)
{
writer.WriteString(L"vl::glr::ParsingToken");
return;
}
if (propType == AstPropType::Array)
{
writer.WriteString(L"vl::collections::List<vl::Ptr<");
}
else if (purpose == PrintTypePurpose::Value && dynamic_cast<AstClassSymbol*>(propSymbol))
{
writer.WriteString(L"vl::Ptr<");
}
auto file = propSymbol->Owner();
if (purpose == PrintTypePurpose::ReflectionName)
{
PrintNss(file->refNss, writer);
}
else
{
if (fileContext != file)
{
PrintNss(file->cppNss, writer);
}
}
writer.WriteString(file->classPrefix);
writer.WriteString(propSymbol->Name());
if (propType == AstPropType::Array)
{
writer.WriteString(L">>");
}
else if (purpose == PrintTypePurpose::Value && dynamic_cast<AstClassSymbol*>(propSymbol))
{
writer.WriteString(L">");
}
}
void PrintFieldType(AstDefFile* fileContext, AstPropType propType, AstSymbol* propSymbol, stream::StreamWriter& writer)
{
PrintAstType(fileContext, propType, propSymbol, PrintTypePurpose::Value, writer);
}
void PrintCppType(AstDefFile* fileContext, AstSymbol* propSymbol, stream::StreamWriter& writer)
{
PrintAstType(fileContext, AstPropType::Type, propSymbol, PrintTypePurpose::TypeName, writer);
}
/***********************************************************************
WriteTypeDefinitions
***********************************************************************/
void WriteTypeDefinitions(AstDefFile* file, const WString& prefix, stream::StreamWriter& writer)
{
for (auto name : file->SymbolOrder())
{
auto typeSymbol = file->Symbols()[name];
if (auto enumSymbol = dynamic_cast<AstEnumSymbol*>(typeSymbol))
{
writer.WriteLine(L"");
writer.WriteString(prefix);
writer.WriteString(L"enum class ");
writer.WriteString(file->classPrefix);
writer.WriteLine(name);
writer.WriteString(prefix);
writer.WriteLine(L"{");
{
writer.WriteString(prefix);
writer.WriteLine(L"\tUNDEFINED_ENUM_ITEM_VALUE = -1,");
}
for (auto itemName : enumSymbol->ItemOrder())
{
auto itemSymbol = enumSymbol->Items()[itemName];
writer.WriteString(prefix);
writer.WriteString(L"\t");
writer.WriteString(itemName);
writer.WriteString(L" = ");
writer.WriteString(itow(itemSymbol->value));
writer.WriteLine(L",");
}
writer.WriteString(prefix);
writer.WriteLine(L"};");
}
}
for (auto name : file->SymbolOrder())
{
auto typeSymbol = file->Symbols()[name];
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
writer.WriteLine(L"");
writer.WriteString(prefix);
writer.WriteString(L"class ");
writer.WriteString(file->classPrefix);
writer.WriteString(name);
if (classSymbol->derivedClasses.Count() > 0)
{
writer.WriteString(L" abstract");
}
writer.WriteString(L" : public ");
if (classSymbol->baseClass)
{
PrintCppType(file, classSymbol->baseClass, writer);
}
else
{
writer.WriteString(L"vl::glr::ParsingAstBase");
}
writer.WriteString(L", vl::reflection::Description<");
writer.WriteString(file->classPrefix);
writer.WriteString(name);
writer.WriteLine(L">");
writer.WriteString(prefix);
writer.WriteLine(L"{");
writer.WriteString(prefix);
writer.WriteLine(L"public:");
if (classSymbol->derivedClasses.Count() > 0)
{
writer.WriteString(prefix);
writer.WriteLine(L"\tclass IVisitor : public virtual vl::reflection::IDescriptable, vl::reflection::Description<IVisitor>");
writer.WriteString(prefix);
writer.WriteLine(L"\t{");
writer.WriteString(prefix);
writer.WriteLine(L"\tpublic:");
for (auto childSymbol : classSymbol->derivedClasses)
{
writer.WriteString(prefix);
writer.WriteString(L"\t\tvirtual void Visit(");
PrintCppType(file, childSymbol, writer);
writer.WriteLine(L"* node) = 0;");
}
writer.WriteString(prefix);
writer.WriteLine(L"\t};");
writer.WriteLine(L"");
writer.WriteString(prefix);
writer.WriteString(L"\tvirtual void Accept(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"::IVisitor* visitor) = 0;");
writer.WriteLine(L"");
}
for (auto propName : classSymbol->PropOrder())
{
auto propSymbol = classSymbol->Props()[propName];
writer.WriteString(prefix);
writer.WriteString(L"\t");
PrintFieldType(file, propSymbol->propType, propSymbol->propSymbol, writer);
writer.WriteString(L" ");
writer.WriteString(propName);
if (dynamic_cast<AstEnumSymbol*>(propSymbol->propSymbol))
{
writer.WriteString(L" = ");
PrintCppType(file, propSymbol->propSymbol, writer);
writer.WriteString(L"::UNDEFINED_ENUM_ITEM_VALUE");
}
writer.WriteLine(L";");
}
if (classSymbol->baseClass)
{
writer.WriteLine(L"");
writer.WriteString(prefix);
writer.WriteString(L"\tvoid Accept(");
PrintCppType(file, classSymbol->baseClass, writer);
writer.WriteLine(L"::IVisitor* visitor) override;");
}
writer.WriteString(prefix);
writer.WriteLine(L"};");
}
}
}
/***********************************************************************
WriteVisitorImpl
***********************************************************************/
void WriteVisitorImpl(AstDefFile* file, const WString& prefix, stream::StreamWriter& writer)
{
for (auto name : file->SymbolOrder())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(file->Symbols()[name]))
{
if (classSymbol->baseClass)
{
writer.WriteLine(L"");
writer.WriteString(prefix);
writer.WriteString(L"void ");
PrintCppType(file, classSymbol, writer);
writer.WriteString(L"::Accept(");
PrintCppType(file, classSymbol->baseClass, writer);
writer.WriteLine(L"::IVisitor* visitor)");
writer.WriteString(prefix);
writer.WriteLine(L"{");
writer.WriteString(prefix);
writer.WriteLine(L"\tvisitor->Visit(this);");
writer.WriteString(prefix);
writer.WriteLine(L"}");
}
}
}
}
/***********************************************************************
WriteTypeReflectionDeclaration
***********************************************************************/
void WriteTypeReflectionDeclaration(AstDefFile* file, const WString& prefix, stream::StreamWriter& writer)
{
writer.WriteLine(L"#ifndef VCZH_DEBUG_NO_REFLECTION");
for (auto&& name : file->SymbolOrder())
{
auto typeSymbol = file->Symbols()[name];
writer.WriteString(prefix);
writer.WriteString(L"DECL_TYPE_INFO(");
PrintCppType(nullptr, typeSymbol, writer);
writer.WriteLine(L")");
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
if (classSymbol->derivedClasses.Count() > 0)
{
writer.WriteString(prefix);
writer.WriteString(L"DECL_TYPE_INFO(");
PrintCppType(nullptr, typeSymbol, writer);
writer.WriteLine(L"::IVisitor)");
}
}
}
writer.WriteLine(L"");
writer.WriteLine(L"#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA");
writer.WriteLine(L"");
for (auto&& name : file->SymbolOrder())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(file->Symbols()[name]))
{
if (classSymbol->derivedClasses.Count() > 0)
{
writer.WriteString(prefix);
writer.WriteString(L"BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteLine(L"::IVisitor)");
for (auto childSymbol : classSymbol->derivedClasses)
{
writer.WriteString(prefix);
writer.WriteString(L"\tvoid Visit(");
PrintCppType(nullptr, childSymbol, writer);
writer.WriteLine(L"* node) override");
writer.WriteString(prefix);
writer.WriteLine(L"\t{");
writer.WriteString(prefix);
writer.WriteLine(L"\t\tINVOKE_INTERFACE_PROXY(Visit, node);");
writer.WriteString(prefix);
writer.WriteLine(L"\t}");
writer.WriteLine(L"");
}
writer.WriteString(prefix);
writer.WriteString(L"END_INTERFACE_PROXY(");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteLine(L"::IVisitor)");
writer.WriteLine(L"");
}
}
}
writer.WriteLine(L"#endif");
writer.WriteLine(L"#endif");
writer.WriteString(prefix);
writer.WriteLine(L"/// <summary>Load all reflectable AST types, only available when <b>VCZH_DEBUG_NO_REFLECTION</b> is off.</summary>");
writer.WriteString(prefix);
writer.WriteLine(L"/// <returns>Returns true if this operation succeeded.</returns>");
writer.WriteString(prefix);
writer.WriteString(L"extern bool ");
writer.WriteString(file->Owner()->Global().name);
writer.WriteString(file->Name());
writer.WriteLine(L"LoadTypes();");
}
/***********************************************************************
WriteTypeReflectionImplementation
***********************************************************************/
void WriteTypeReflectionImplementation(AstDefFile* file, const WString& prefix, stream::StreamWriter& writer)
{
writer.WriteLine(L"#ifndef VCZH_DEBUG_NO_REFLECTION");
writer.WriteLine(L"");
for (auto&& name : file->SymbolOrder())
{
auto typeSymbol = file->Symbols()[name];
writer.WriteString(prefix);
writer.WriteString(L"IMPL_TYPE_INFO_RENAME(");
PrintCppType(nullptr, typeSymbol, writer);
writer.WriteString(L", ");
PrintAstType(nullptr, AstPropType::Type, typeSymbol, PrintTypePurpose::ReflectionName, writer);
writer.WriteLine(L")");
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
if (classSymbol->derivedClasses.Count() > 0)
{
writer.WriteString(prefix);
writer.WriteString(L"IMPL_TYPE_INFO_RENAME(");
PrintCppType(nullptr, typeSymbol, writer);
writer.WriteString(L"::IVisitor");
writer.WriteString(L", ");
PrintAstType(nullptr, AstPropType::Type, typeSymbol, PrintTypePurpose::ReflectionName, writer);
writer.WriteLine(L"::IVisitor)");
}
}
}
writer.WriteLine(L"");
writer.WriteLine(L"#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA");
for (auto&& name : file->SymbolOrder())
{
auto typeSymbol = file->Symbols()[name];
writer.WriteLine(L"");
if (auto enumSymbol = dynamic_cast<AstEnumSymbol*>(typeSymbol))
{
writer.WriteString(prefix);
writer.WriteString(L"BEGIN_ENUM_ITEM(");
PrintCppType(nullptr, enumSymbol, writer);
writer.WriteLine(L")");
writer.WriteString(prefix);
writer.WriteString(L"\tENUM_ITEM_NAMESPACE(");
PrintCppType(nullptr, enumSymbol, writer);
writer.WriteLine(L")");
for (auto itemName : enumSymbol->ItemOrder())
{
writer.WriteString(prefix);
writer.WriteString(L"\tENUM_NAMESPACE_ITEM(");
writer.WriteString(itemName);
writer.WriteLine(L")");
}
writer.WriteString(prefix);
writer.WriteString(L"END_ENUM_ITEM(");
PrintCppType(nullptr, enumSymbol, writer);
writer.WriteLine(L")");
}
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
writer.WriteString(prefix);
writer.WriteString(L"BEGIN_CLASS_MEMBER(");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteLine(L")");
if (classSymbol->baseClass)
{
writer.WriteString(prefix);
writer.WriteString(L"\tCLASS_MEMBER_BASE(");
PrintCppType(nullptr, classSymbol->baseClass, writer);
writer.WriteLine(L")");
}
else
{
writer.WriteLine(prefix + L"\tCLASS_MEMBER_BASE(vl::glr::ParsingAstBase)");
}
writer.WriteLine(L"");
if (classSymbol->derivedClasses.Count() == 0)
{
writer.WriteString(prefix);
writer.WriteString(L"\tCLASS_MEMBER_CONSTRUCTOR(vl::Ptr<");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteLine(L">(), NO_PARAMETER)");
writer.WriteLine(L"");
}
for (auto propName : classSymbol->PropOrder())
{
auto propSymbol = classSymbol->Props()[propName];
writer.WriteString(prefix);
writer.WriteString(L"\tCLASS_MEMBER_FIELD(");
writer.WriteString(propSymbol->Name());
writer.WriteLine(L")");
}
writer.WriteString(prefix);
writer.WriteString(L"END_CLASS_MEMBER(");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteLine(L")");
}
}
for (auto&& name : file->SymbolOrder())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(file->Symbols()[name]))
{
if (classSymbol->derivedClasses.Count() > 0)
{
writer.WriteLine(L"");
writer.WriteString(prefix);
writer.WriteString(L"BEGIN_INTERFACE_MEMBER(");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteLine(L"::IVisitor)");
for (auto childSymbol : classSymbol->derivedClasses)
{
writer.WriteString(prefix);
writer.WriteString(L"\tCLASS_MEMBER_METHOD_OVERLOAD(Visit, {L\"node\"}, void(");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteString(L"::IVisitor::*)(");
PrintCppType(nullptr, childSymbol, writer);
writer.WriteLine(L"* node))");
}
writer.WriteString(prefix);
writer.WriteString(L"END_INTERFACE_MEMBER(");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteLine(L")");
}
}
}
writer.WriteLine(L"");
writer.WriteLine(L"#endif");
writer.WriteLine(L"");
writer.WriteLine(L"#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA");
writer.WriteString(prefix);
writer.WriteString(L"class ");
writer.WriteString(file->Owner()->Global().name);
writer.WriteString(file->Name());
writer.WriteLine(L"TypeLoader : public vl::Object, public ITypeLoader");
writer.WriteString(prefix);
writer.WriteLine(L"{");
writer.WriteString(prefix);
writer.WriteLine(L"public:");
writer.WriteString(prefix);
writer.WriteLine(L"\tvoid Load(ITypeManager* manager)");
writer.WriteString(prefix);
writer.WriteLine(L"\t{");
for (auto&& name : file->SymbolOrder())
{
auto typeSymbol = file->Symbols()[name];
writer.WriteString(prefix);
writer.WriteString(L"\t\tADD_TYPE_INFO(");
PrintCppType(nullptr, typeSymbol, writer);
writer.WriteLine(L")");
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
if (classSymbol->derivedClasses.Count() > 0)
{
writer.WriteString(prefix);
writer.WriteString(L"\t\tADD_TYPE_INFO(");
PrintCppType(nullptr, classSymbol, writer);
writer.WriteLine(L"::IVisitor)");
}
}
}
writer.WriteString(prefix);
writer.WriteLine(L"\t}");
writer.WriteLine(L"");
writer.WriteString(prefix);
writer.WriteLine(L"\tvoid Unload(ITypeManager* manager)");
writer.WriteString(prefix);
writer.WriteLine(L"\t{");
writer.WriteString(prefix);
writer.WriteLine(L"\t}");
writer.WriteString(prefix);
writer.WriteLine(L"};");
writer.WriteLine(L"#endif");
writer.WriteLine(L"#endif");
writer.WriteLine(L"");
writer.WriteString(prefix);
writer.WriteString(L"bool ");
writer.WriteString(file->Owner()->Global().name);
writer.WriteString(file->Name());
writer.WriteLine(L"LoadTypes()");
writer.WriteString(prefix);
writer.WriteLine(L"{");
writer.WriteLine(L"#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA");
writer.WriteString(prefix);
writer.WriteLine(L"\tif (auto manager = GetGlobalTypeManager())");
writer.WriteString(prefix);
writer.WriteLine(L"\t{");
writer.WriteString(prefix);
writer.WriteString(L"\t\tPtr<ITypeLoader> loader = new ");
writer.WriteString(file->Owner()->Global().name);
writer.WriteString(file->Name());
writer.WriteLine(L"TypeLoader;");
writer.WriteString(prefix);
writer.WriteLine(L"\t\treturn manager->AddTypeLoader(loader);");
writer.WriteString(prefix);
writer.WriteLine(L"\t}");
writer.WriteLine(L"#endif");
writer.WriteString(prefix);
writer.WriteLine(L"\treturn false;");
writer.WriteString(prefix);
writer.WriteLine(L"}");
}
}
}
}
/***********************************************************************
.\AST\ASTCPPGEN_COPYVISITOR.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace stream;
extern void PrintCppType(AstDefFile* fileContext, AstSymbol* propSymbol, stream::StreamWriter& writer);
extern void CollectVisitorsAndConcreteClasses(AstDefFile* file, List<AstClassSymbol*>& visitors, List<AstClassSymbol*>& concreteClasses);
/***********************************************************************
WriteCopyFieldFunctionBody
***********************************************************************/
void WriteCopyFieldFunctionBody(AstDefFile* file, AstClassSymbol* fieldSymbol, const WString& prefix, stream::StreamWriter& writer)
{
if (fieldSymbol->baseClass)
{
writer.WriteString(prefix + L"\tCopyFields(static_cast<");
PrintCppType(file, fieldSymbol->baseClass, writer);
writer.WriteString(L"*>(from), static_cast<");
PrintCppType(file, fieldSymbol->baseClass, writer);
writer.WriteLine(L"*>(to));");
}
for (auto propSymbol : fieldSymbol->Props().Values())
{
switch (propSymbol->propType)
{
case AstPropType::Token:
writer.WriteLine(prefix + L"\tto->" + propSymbol->Name() + L" = from->" + propSymbol->Name() + L";");
break;
case AstPropType::Array:
writer.WriteLine(prefix + L"\tfor (auto&& listItem : from->" + propSymbol->Name() + L")");
writer.WriteLine(prefix + L"\t{");
writer.WriteLine(prefix + L"\t\tto->" + propSymbol->Name() + L".Add(CopyNode(listItem.Obj()));");
writer.WriteLine(prefix + L"\t}");
break;
case AstPropType::Type:
if (dynamic_cast<AstClassSymbol*>(propSymbol->propSymbol))
{
writer.WriteLine(prefix + L"\tto->" + propSymbol->Name() + L" = CopyNode(from->" + propSymbol->Name() + L".Obj());");
}
else
{
writer.WriteLine(prefix + L"\tto->" + propSymbol->Name() + L" = from->" + propSymbol->Name() + L";");
}
break;
}
}
}
/***********************************************************************
WriteCopyVisitorHeaderFile
***********************************************************************/
void WriteCopyVisitorHeaderFile(AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer)
{
WriteAstUtilityHeaderFile(file, output, L"copy_visitor", writer, [&](const WString& prefix)
{
List<AstClassSymbol*> visitors, concreteClasses;
CollectVisitorsAndConcreteClasses(file, visitors, concreteClasses);
writer.WriteLine(prefix + L"/// <summary>A copy visitor, overriding all abstract methods with AST copying code.</summary>");
writer.WriteLine(prefix + L"class " + file->Name() + L"Visitor");
writer.WriteLine(prefix + L"\t: public virtual vl::glr::CopyVisitorBase");
for (auto visitorSymbol : visitors)
{
writer.WriteString(prefix + L"\t, protected virtual ");
PrintCppType(file, visitorSymbol, writer);
writer.WriteLine(L"::IVisitor");
}
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"protected:");
for (auto typeSymbol : file->Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
writer.WriteString(prefix + L"\tvoid CopyFields(");
PrintCppType(file, classSymbol, writer);
writer.WriteString(L"* from, ");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* to);");
}
}
writer.WriteLine(L"");
writer.WriteLine(prefix + L"protected:");
for (auto classSymbol : concreteClasses)
{
writer.WriteString(prefix + L"\tvirtual void Visit(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node);");
}
writer.WriteLine(L"");
for (auto visitorSymbol : visitors)
{
for (auto classSymbol : visitorSymbol->derivedClasses)
{
writer.WriteString(prefix + L"\tvoid Visit(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node) override;");
}
writer.WriteLine(L"");
}
writer.WriteLine(prefix + L"public:");
for (auto classSymbol :
From(visitors)
.Where([](AstClassSymbol* visitor) { return visitor->baseClass == nullptr; })
.Concat(concreteClasses)
)
{
writer.WriteString(prefix + L"\tvirtual vl::Ptr<");
PrintCppType(file, classSymbol, writer);
writer.WriteString(L"> CopyNode(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node);");
}
writer.WriteLine(L"");
for (auto classSymbol :
From(file->Symbols().Values())
.Select([](AstSymbol* derivedClass) { return dynamic_cast<AstClassSymbol*>(derivedClass); })
.Where([](AstClassSymbol* derivedClass) { return derivedClass && derivedClass->baseClass != nullptr; })
)
{
writer.WriteString(prefix + L"\tvl::Ptr<");
PrintCppType(file, classSymbol, writer);
writer.WriteString(L"> CopyNode(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node);");
}
writer.WriteLine(prefix + L"};");
});
}
/***********************************************************************
WriteCopyVisitorCppFile
***********************************************************************/
void WriteCopyVisitorCppFile(AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer)
{
WriteAstUtilityCppFile(file, output->copyH, L"copy_visitor", writer, [&](const WString& prefix)
{
List<AstClassSymbol*> visitors, concreteClasses;
CollectVisitorsAndConcreteClasses(file, visitors, concreteClasses);
for (auto typeSymbol : file->Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
writer.WriteString(prefix + L"void " + file->Name() + L"Visitor::CopyFields(");
PrintCppType(file, classSymbol, writer);
writer.WriteString(L"* from, ");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* to)");
writer.WriteLine(prefix + L"{");
WriteCopyFieldFunctionBody(file, classSymbol, prefix, writer);
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
}
}
for (auto classSymbol : concreteClasses)
{
writer.WriteString(prefix + L"void " + file->Name() + L"Visitor::Visit(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
writer.WriteString(prefix + L"\tauto newNode = vl::MakePtr<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L">();");
writer.WriteLine(prefix + L"\tCopyFields(node, newNode.Obj());");
writer.WriteLine(prefix + L"\tthis->result = newNode;");
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
}
for (auto visitorSymbol : visitors)
{
for (auto classSymbol : visitorSymbol->derivedClasses)
{
writer.WriteString(prefix + L"void " + file->Name() + L"Visitor::Visit(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
if (classSymbol->derivedClasses.Count() == 0)
{
writer.WriteString(prefix + L"\tauto newNode = vl::MakePtr<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L">();");
writer.WriteLine(prefix + L"\tCopyFields(node, newNode.Obj());");
writer.WriteLine(prefix + L"\tthis->result = newNode;");
}
else
{
writer.WriteString(prefix + L"\tnode->Accept(static_cast<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"::IVisitor*>(this));");
}
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
}
}
for (auto classSymbol : visitors)
{
if (!classSymbol->baseClass)
{
writer.WriteString(prefix + L"vl::Ptr<");
PrintCppType(file, classSymbol, writer);
writer.WriteString(L"> " + file->Name() + L"Visitor::CopyNode(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tif (!node) return nullptr;");
writer.WriteString(prefix + L"\tnode->Accept(static_cast<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"::IVisitor*>(this));");
writer.WriteString(prefix + L"\treturn this->result.Cast<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L">();");
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
}
}
for (auto classSymbol : concreteClasses)
{
writer.WriteString(prefix + L"vl::Ptr<");
PrintCppType(file, classSymbol, writer);
writer.WriteString(L"> " + file->Name() + L"Visitor::CopyNode(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tif (!node) return nullptr;");
writer.WriteLine(prefix + L"\tVisit(node);");
writer.WriteString(prefix + L"\treturn this->result.Cast<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L">();");
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
}
for (auto classSymbol :
From(file->Symbols().Values())
.Select([](AstSymbol* derivedClass) { return dynamic_cast<AstClassSymbol*>(derivedClass); })
.Where([](AstClassSymbol* derivedClass) { return derivedClass && derivedClass->baseClass != nullptr; })
)
{
auto rootBaseClass = classSymbol;
while (rootBaseClass->baseClass)
{
rootBaseClass = rootBaseClass->baseClass;
}
writer.WriteString(prefix + L"vl::Ptr<");
PrintCppType(file, classSymbol, writer);
writer.WriteString(L"> " + file->Name() + L"Visitor::CopyNode(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tif (!node) return nullptr;");
writer.WriteString(prefix + L"\treturn CopyNode(static_cast<");
PrintCppType(file, rootBaseClass, writer);
writer.WriteString(L"*>(node)).Cast<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L">();");
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
}
});
}
}
}
}
/***********************************************************************
.\AST\ASTCPPGEN_EMPTYVISITOR.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace stream;
extern void PrintCppType(AstDefFile* fileContext, AstSymbol* propSymbol, stream::StreamWriter& writer);
/***********************************************************************
WriteEmptyVisitorHeaderFile
***********************************************************************/
void WriteEmptyVisitorHeaderFile(AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer)
{
WriteAstUtilityHeaderFile(file, output, L"empty_visitor", writer, [&](const WString& prefix)
{
for (auto name : file->SymbolOrder())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(file->Symbols()[name]))
{
if (classSymbol->derivedClasses.Count() > 0)
{
writer.WriteLine(prefix + L"/// <summary>An empty visitor, overriding all abstract methods with empty implementations.</summary>");
writer.WriteString(prefix + L"class " + name + L"Visitor : public vl::Object, public ");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"::IVisitor");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"protected:");
writer.WriteLine(prefix + L"\t// Dispatch (virtual) --------------------------------");
for (auto childSymbol : classSymbol->derivedClasses)
{
if (childSymbol->derivedClasses.Count() > 0)
{
writer.WriteString(prefix + L"\tvirtual void Dispatch(");
PrintCppType(file, childSymbol, writer);
writer.WriteLine(L"* node) = 0;");
}
}
writer.WriteLine(L"");
writer.WriteLine(prefix + L"public:");
writer.WriteLine(prefix + L"\t// Visitor Members -----------------------------------");
for (auto childSymbol : classSymbol->derivedClasses)
{
writer.WriteString(prefix + L"\tvoid Visit(");
PrintCppType(file, childSymbol, writer);
writer.WriteLine(L"* node) override;");
}
writer.WriteLine(prefix + L"};");
writer.WriteLine(L"");
}
}
}
});
}
/***********************************************************************
WriteEmptyVisitorCppFile
***********************************************************************/
void WriteEmptyVisitorCppFile(AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer)
{
WriteAstUtilityCppFile(file, output->emptyH, L"empty_visitor", writer, [&](const WString& prefix)
{
for (auto name : file->SymbolOrder())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(file->Symbols()[name]))
{
if (classSymbol->derivedClasses.Count() > 0)
{
writer.WriteLine(L"");
writer.WriteLine(L"/***********************************************************************");
writer.WriteLine(classSymbol->Name() + L"Visitor");
writer.WriteLine(L"***********************************************************************/");
writer.WriteLine(L"");
writer.WriteLine(prefix + L"// Visitor Members -----------------------------------");
for (auto childSymbol : classSymbol->derivedClasses)
{
writer.WriteLine(L"");
writer.WriteString(prefix + L"void " + classSymbol->Name() + L"Visitor::Visit(");
PrintCppType(file, childSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
if (childSymbol->derivedClasses.Count() > 0)
{
writer.WriteLine(prefix + L"\tDispatch(node);");
}
writer.WriteLine(prefix + L"}");
}
}
}
}
});
}
}
}
}
/***********************************************************************
.\AST\ASTCPPGEN_JSONVISITOR.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace stream;
extern void PrintCppType(AstDefFile* fileContext, AstSymbol* propSymbol, stream::StreamWriter& writer);
extern void CollectVisitorsAndConcreteClasses(AstDefFile* file, List<AstClassSymbol*>& visitors, List<AstClassSymbol*>& concreteClasses);
/***********************************************************************
WriteVisitFieldFunctionBody
***********************************************************************/
void WritePrintFieldsFunctionBody(AstDefFile* file, AstClassSymbol* fieldSymbol, const WString& prefix, stream::StreamWriter& writer)
{
for (auto propSymbol : fieldSymbol->Props().Values())
{
writer.WriteLine(prefix + L"\tBeginField(L\"" + propSymbol->Name() + L"\");");
switch (propSymbol->propType)
{
case AstPropType::Token:
writer.WriteLine(prefix + L"\tWriteToken(node->" + propSymbol->Name() + L");");
break;
case AstPropType::Array:
writer.WriteLine(prefix + L"\tBeginArray();");
writer.WriteLine(prefix + L"\tfor (auto&& listItem : node->" + propSymbol->Name() + L")");
writer.WriteLine(prefix + L"\t{");
writer.WriteLine(prefix + L"\t\tBeginArrayItem();");
writer.WriteLine(prefix + L"\t\tPrint(listItem.Obj());");
writer.WriteLine(prefix + L"\t\tEndArrayItem();");
writer.WriteLine(prefix + L"\t}");
writer.WriteLine(prefix + L"\tEndArray();");
break;
case AstPropType::Type:
if (auto enumPropSymbol = dynamic_cast<AstEnumSymbol*>(propSymbol->propSymbol))
{
writer.WriteLine(prefix + L"\tswitch (node->" + propSymbol->Name() + L")");
writer.WriteLine(prefix + L"\t{");
for (auto enumItemSymbol : enumPropSymbol->Items().Values())
{
writer.WriteString(prefix + L"\tcase ");
PrintCppType(nullptr, enumPropSymbol, writer);
writer.WriteLine(L"::" + enumItemSymbol->Name() + L":");
writer.WriteLine(prefix + L"\t\tWriteString(L\"" + enumItemSymbol->Name() + L"\");");
writer.WriteLine(prefix + L"\t\tbreak;");
}
writer.WriteLine(prefix + L"\tdefault:");
writer.WriteLine(prefix + L"\t\tWriteNull();");
writer.WriteLine(prefix + L"\t}");
}
if (dynamic_cast<AstClassSymbol*>(propSymbol->propSymbol))
{
writer.WriteLine(prefix + L"\tPrint(node->" + propSymbol->Name() + L".Obj());");
}
break;
}
writer.WriteLine(prefix + L"\tEndField();");
}
}
void WriteNullAndReturn(const WString& prefix, stream::StreamWriter& writer)
{
writer.WriteLine(prefix + L"\tif (!node)");
writer.WriteLine(prefix + L"\t{");
writer.WriteLine(prefix + L"\t\tWriteNull();");
writer.WriteLine(prefix + L"\t\treturn;");
writer.WriteLine(prefix + L"\t}");
}
void WriteVisitFunctionBody(AstDefFile* file, AstClassSymbol* fieldSymbol, const WString& prefix, stream::StreamWriter& writer)
{
WriteNullAndReturn(prefix, writer);
List<AstClassSymbol*> order;
{
auto current = fieldSymbol;
while (current)
{
order.Add(current);
current = current->baseClass;
}
}
writer.WriteLine(prefix + L"\tBeginObject();");
writer.WriteLine(prefix + L"\tWriteType(L\"" + fieldSymbol->Name() + L"\", node);");
for (auto classSymbol : From(order).Reverse())
{
writer.WriteString(prefix + L"\tPrintFields(static_cast<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"*>(node));");
}
writer.WriteLine(prefix + L"\tEndObject();");
}
/***********************************************************************
WriteJsonVisitorHeaderFile
***********************************************************************/
void WriteJsonVisitorHeaderFile(AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer)
{
WriteAstUtilityHeaderFile(file, output, L"json_visitor", writer, [&](const WString& prefix)
{
List<AstClassSymbol*> visitors, concreteClasses;
CollectVisitorsAndConcreteClasses(file, visitors, concreteClasses);
writer.WriteLine(prefix + L"/// <summary>A JSON visitor, overriding all abstract methods with AST to JSON serialization code.</summary>");
writer.WriteLine(prefix + L"class " + file->Name() + L"Visitor");
writer.WriteLine(prefix + L"\t: public vl::glr::JsonVisitorBase");
for (auto visitorSymbol : visitors)
{
writer.WriteString(prefix + L"\t, protected virtual ");
PrintCppType(file, visitorSymbol, writer);
writer.WriteLine(L"::IVisitor");
}
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"protected:");
for (auto typeSymbol : file->Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
writer.WriteString(prefix + L"\tvirtual void PrintFields(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node);");
}
}
writer.WriteLine(L"");
writer.WriteLine(prefix + L"protected:");
for (auto visitorSymbol : visitors)
{
for (auto classSymbol : visitorSymbol->derivedClasses)
{
writer.WriteString(prefix + L"\tvoid Visit(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node) override;");
}
writer.WriteLine(L"");
}
writer.WriteLine(prefix + L"public:");
writer.WriteLine(prefix + L"\t" + file->Name() + L"Visitor(vl::stream::StreamWriter& _writer);");
writer.WriteLine(L"");
for (auto classSymbol :
From(visitors)
.Where([](AstClassSymbol* visitor) { return !visitor->baseClass; })
.Concat(concreteClasses)
)
{
writer.WriteString(prefix + L"\tvoid Print(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node);");
}
writer.WriteLine(prefix + L"};");
});
}
/***********************************************************************
WriteJsonVisitorCppFile
***********************************************************************/
void WriteJsonVisitorCppFile(AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer)
{
WriteAstUtilityCppFile(file, output->jsonH, L"json_visitor", writer, [&](const WString& prefix)
{
List<AstClassSymbol*> visitors, concreteClasses;
CollectVisitorsAndConcreteClasses(file, visitors, concreteClasses);
for (auto typeSymbol : file->Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
writer.WriteString(prefix + L"void " + file->Name() + L"Visitor::PrintFields(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
WritePrintFieldsFunctionBody(file, classSymbol, prefix, writer);
writer.WriteLine(prefix + L"}");
}
}
writer.WriteLine(L"");
for (auto visitorSymbol : visitors)
{
for (auto classSymbol : visitorSymbol->derivedClasses)
{
writer.WriteString(prefix + L"void " + file->Name() + L"Visitor::Visit(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
if (classSymbol->derivedClasses.Count() == 0)
{
WriteVisitFunctionBody(file, classSymbol, prefix, writer);
}
else
{
writer.WriteString(prefix + L"\tnode->Accept(static_cast<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"::IVisitor*>(this));");
}
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
}
}
writer.WriteLine(prefix + file->Name() + L"Visitor::" + file->Name() + L"Visitor(vl::stream::StreamWriter& _writer)");
writer.WriteLine(prefix + L"\t: vl::glr::JsonVisitorBase(_writer)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
for (auto classSymbol : visitors)
{
if (!classSymbol->baseClass)
{
writer.WriteString(prefix + L"void " + file->Name() + L"Visitor::Print(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
WriteNullAndReturn(prefix, writer);
writer.WriteString(prefix + L"\tnode->Accept(static_cast<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"::IVisitor*>(this));");
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
}
}
for (auto classSymbol : concreteClasses)
{
writer.WriteString(prefix + L"void " + file->Name() + L"Visitor::Print(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
WriteVisitFunctionBody(file, classSymbol, prefix, writer);
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
}
});
}
}
}
}
/***********************************************************************
.\AST\ASTCPPGEN_TRAVERSEVISITOR.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace stream;
extern void PrintCppType(AstDefFile* fileContext, AstSymbol* propSymbol, stream::StreamWriter& writer);
extern void CollectVisitorsAndConcreteClasses(AstDefFile* file, List<AstClassSymbol*>& visitors, List<AstClassSymbol*>& concreteClasses);
/***********************************************************************
WriteVisitFieldFunctionBody
***********************************************************************/
void WriteVisitFieldFunctionBody(AstDefFile* file, AstClassSymbol* fieldSymbol, const WString& prefix, stream::StreamWriter& writer)
{
writer.WriteLine(prefix + L"\tif (!node) return;");
List<AstClassSymbol*> order;
{
auto current = fieldSymbol;
while (current)
{
order.Add(current);
current = current->baseClass;
}
}
writer.WriteLine(prefix + L"\tTraverse(static_cast<vl::glr::ParsingAstBase*>(node));");
for (auto classSymbol : From(order).Reverse())
{
writer.WriteString(prefix + L"\tTraverse(static_cast<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"*>(node));");
}
{
auto current = fieldSymbol;
while (current)
{
for (auto propSymbol : current->Props().Values())
{
switch (propSymbol->propType)
{
case AstPropType::Token:
writer.WriteLine(prefix + L"\tTraverse(node->" + propSymbol->Name() + L");");
break;
case AstPropType::Array:
writer.WriteLine(prefix + L"\tfor (auto&& listItem : node->" + propSymbol->Name() + L")");
writer.WriteLine(prefix + L"\t{");
writer.WriteLine(prefix + L"\t\tInspectInto(listItem.Obj());");
writer.WriteLine(prefix + L"\t}");
break;
case AstPropType::Type:
if (dynamic_cast<AstClassSymbol*>(propSymbol->propSymbol))
{
writer.WriteLine(prefix + L"\tInspectInto(node->" + propSymbol->Name() + L".Obj());");
}
break;
}
}
current = current->baseClass;
}
}
for (auto classSymbol : order)
{
writer.WriteString(prefix + L"\tFinishing(static_cast<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"*>(node));");
}
writer.WriteLine(prefix + L"\tFinishing(static_cast<vl::glr::ParsingAstBase*>(node));");
}
/***********************************************************************
WriteTraverseVisitorHeaderFile
***********************************************************************/
void WriteTraverseVisitorHeaderFile(AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer)
{
WriteAstUtilityHeaderFile(file, output, L"traverse_visitor", writer, [&](const WString& prefix)
{
List<AstClassSymbol*> visitors, concreteClasses;
CollectVisitorsAndConcreteClasses(file, visitors, concreteClasses);
writer.WriteLine(prefix + L"/// <summary>A traverse visitor, overriding all abstract methods with AST visiting code.</summary>");
writer.WriteLine(prefix + L"class " + file->Name() + L"Visitor");
writer.WriteLine(prefix + L"\t: public vl::Object");
for (auto visitorSymbol : visitors)
{
writer.WriteString(prefix + L"\t, protected virtual ");
PrintCppType(file, visitorSymbol, writer);
writer.WriteLine(L"::IVisitor");
}
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"protected:");
writer.WriteLine(prefix + L"\tvirtual void Traverse(vl::glr::ParsingToken& token);");
writer.WriteLine(prefix + L"\tvirtual void Traverse(vl::glr::ParsingAstBase* node);");
for (auto typeSymbol : file->Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
writer.WriteString(prefix + L"\tvirtual void Traverse(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node);");
}
}
writer.WriteLine(L"");
writer.WriteLine(prefix + L"protected:");
writer.WriteLine(prefix + L"\tvirtual void Finishing(vl::glr::ParsingAstBase* node);");
for (auto typeSymbol : file->Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
writer.WriteString(prefix + L"\tvirtual void Finishing(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node);");
}
}
writer.WriteLine(L"");
writer.WriteLine(prefix + L"protected:");
for (auto visitorSymbol : visitors)
{
for (auto classSymbol : visitorSymbol->derivedClasses)
{
writer.WriteString(prefix + L"\tvoid Visit(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node) override;");
}
writer.WriteLine(L"");
}
writer.WriteLine(prefix + L"public:");
for (auto classSymbol :
From(visitors)
.Where([](AstClassSymbol* visitor) { return !visitor->baseClass; })
.Concat(concreteClasses)
)
{
writer.WriteString(prefix + L"\tvoid InspectInto(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node);");
}
writer.WriteLine(prefix + L"};");
});
}
/***********************************************************************
WriteTraverseVisitorCppFile
***********************************************************************/
void WriteTraverseVisitorCppFile(AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer)
{
WriteAstUtilityCppFile(file, output->traverseH, L"traverse_visitor", writer, [&](const WString& prefix)
{
List<AstClassSymbol*> visitors, concreteClasses;
CollectVisitorsAndConcreteClasses(file, visitors, concreteClasses);
writer.WriteLine(prefix + L"void " + file->Name() + L"Visitor::Traverse(vl::glr::ParsingToken& token) {}");
writer.WriteLine(prefix + L"void " + file->Name() + L"Visitor::Traverse(vl::glr::ParsingAstBase* node) {}");
for (auto typeSymbol : file->Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
writer.WriteString(prefix + L"void " + file->Name() + L"Visitor::Traverse(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node) {}");
}
}
writer.WriteLine(L"");
writer.WriteLine(prefix + L"void " + file->Name() + L"Visitor::Finishing(vl::glr::ParsingAstBase* node) {}");
for (auto typeSymbol : file->Symbols().Values())
{
if (auto classSymbol = dynamic_cast<AstClassSymbol*>(typeSymbol))
{
writer.WriteString(prefix + L"void " + file->Name() + L"Visitor::Finishing(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node) {}");
}
}
writer.WriteLine(L"");
for (auto visitorSymbol : visitors)
{
for (auto classSymbol : visitorSymbol->derivedClasses)
{
writer.WriteString(prefix + L"void " + file->Name() + L"Visitor::Visit(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
if (classSymbol->derivedClasses.Count() == 0)
{
WriteVisitFieldFunctionBody(file, classSymbol, prefix, writer);
}
else
{
writer.WriteString(prefix + L"\tnode->Accept(static_cast<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"::IVisitor*>(this));");
}
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
}
}
for (auto classSymbol : visitors)
{
if (!classSymbol->baseClass)
{
writer.WriteString(prefix + L"void " + file->Name() + L"Visitor::InspectInto(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tif (!node) return;");
writer.WriteString(prefix + L"\tnode->Accept(static_cast<");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"::IVisitor*>(this));");
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
}
}
for (auto classSymbol : concreteClasses)
{
writer.WriteString(prefix + L"void " + file->Name() + L"Visitor::InspectInto(");
PrintCppType(file, classSymbol, writer);
writer.WriteLine(L"* node)");
writer.WriteLine(prefix + L"{");
WriteVisitFieldFunctionBody(file, classSymbol, prefix, writer);
writer.WriteLine(prefix + L"}");
writer.WriteLine(L"");
}
});
}
}
}
}
/***********************************************************************
.\AST\ASTSYMBOL.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
/***********************************************************************
AstSymbol
***********************************************************************/
AstSymbol::AstSymbol(AstDefFile* _file, const WString& _name)
: ownerFile(_file)
, name(_name)
{
}
/***********************************************************************
AstEnumItemSymbol
***********************************************************************/
AstEnumItemSymbol::AstEnumItemSymbol(AstEnumSymbol* _parent, const WString& name)
: AstSymbol(_parent->Owner(), name)
, parent(_parent)
{
}
/***********************************************************************
AstEnumSymbol
***********************************************************************/
AstEnumSymbol::AstEnumSymbol(AstDefFile* _file, const WString& _name)
: AstSymbol(_file, _name)
{
}
AstEnumItemSymbol* AstEnumSymbol::CreateItem(const WString& itemName, ParsingTextRange codeRange)
{
auto symbol = new AstEnumItemSymbol(this, itemName);
symbol->value = items.items.Count();
if (!items.Add(itemName, symbol))
{
ownerFile->AddError(
ParserErrorType::DuplicatedEnumItem,
codeRange,
ownerFile->Name(),
name,
itemName
);
}
return symbol;
}
/***********************************************************************
AstClassPropSymbol
***********************************************************************/
AstClassPropSymbol::AstClassPropSymbol(AstClassSymbol* _parent, const WString& name)
: AstSymbol(_parent->Owner(), name)
, parent(_parent)
{
}
bool AstClassPropSymbol::SetPropType(AstPropType _type, const WString& typeName, ParsingTextRange codeRange)
{
propType = _type;
if (_type == AstPropType::Token) return true;
auto& symbols = parent->Owner()->Symbols();
vint index = symbols.Keys().IndexOf(typeName);
if (index == -1)
{
ownerFile->AddError(
ParserErrorType::FieldTypeNotExists,
codeRange,
ownerFile->Name(),
parent->Name(),
name
);
return false;
}
propSymbol = symbols.Values()[index];
if (_type == AstPropType::Type) return true;
if (!dynamic_cast<AstClassSymbol*>(propSymbol))
{
ownerFile->AddError(
ParserErrorType::FieldTypeNotClass,
codeRange,
parent->Owner()->Name(),
parent->Name(),
name
);
return false;
}
return true;
}
/***********************************************************************
AstClassSymbol
***********************************************************************/
AstClassSymbol::AstClassSymbol(AstDefFile* _file, const WString& _name)
: AstSymbol(_file, _name)
{
}
bool AstClassSymbol::SetBaseClass(const WString& typeName, ParsingTextRange codeRange)
{
auto& symbols = ownerFile->Symbols();
vint index = symbols.Keys().IndexOf(typeName);
if (index == -1)
{
ownerFile->AddError(
ParserErrorType::BaseClassNotExists,
codeRange,
ownerFile->Name(),
name,
typeName
);
return false;
}
auto newBaseClass = dynamic_cast<AstClassSymbol*>(symbols.Values()[index]);
if (!newBaseClass)
{
ownerFile->AddError(
ParserErrorType::BaseClassNotClass,
codeRange,
ownerFile->Name(),
name,
typeName
);
return false;
}
List<AstClassSymbol*> visited;
visited.Add(newBaseClass);
for (vint i = 0; i < visited.Count(); i++)
{
auto currentSymbol = visited[i];
if (currentSymbol == this)
{
ownerFile->AddError(
ParserErrorType::BaseClassCyclicDependency,
codeRange,
ownerFile->Name(),
name
);
return false;
}
if (currentSymbol->baseClass)
{
visited.Add(currentSymbol->baseClass);
}
}
baseClass = newBaseClass;
newBaseClass->derivedClasses.Add(this);
return true;
}
AstClassSymbol* AstClassSymbol::CreateAmbiguousDerivedClass(ParsingTextRange codeRange)
{
if (!ambiguousDerivedClass)
{
auto derived = ownerFile->CreateClass(name + L"ToResolve", codeRange);
derived->baseClass = this;
derivedClasses.Add(derived);
auto prop = derived->CreateProp(L"candidates", codeRange);
prop->propType = AstPropType::Array;
prop->propSymbol = this;
ambiguousDerivedClass = derived;
}
return ambiguousDerivedClass;
}
AstClassPropSymbol* AstClassSymbol::CreateProp(const WString& propName, ParsingTextRange codeRange)
{
auto symbol = new AstClassPropSymbol(this, propName);
if (!props.Add(propName, symbol))
{
ownerFile->AddError(
ParserErrorType::DuplicatedClassProp,
codeRange,
ownerFile->Name(),
name,
propName
);
}
return symbol;
}
/***********************************************************************
FindCommonBaseClass
***********************************************************************/
AstClassSymbol* FindCommonBaseClass(AstClassSymbol* c1, AstClassSymbol* c2)
{
if (c1 == c2) return c1;
if (!c1) return c2;
if (!c2) return c1;
// find common base classes
vint n1 = 0, n2 = 0;
{
auto c = c1;
while (c)
{
n1++;
c = c->baseClass;
}
}
{
auto c = c2;
while (c)
{
n2++;
c = c->baseClass;
}
}
while (n1 > n2)
{
n1--;
c1 = c1->baseClass;
}
while (n2 > n1)
{
n2--;
c2 = c2->baseClass;
}
while (c1 && c2)
{
if (c1 == c2) return c1;
c1 = c1->baseClass;
c2 = c2->baseClass;
}
return nullptr;
}
/***********************************************************************
FindPropSymbol
***********************************************************************/
AstClassPropSymbol* FindPropSymbol(AstClassSymbol*& type, const WString& name)
{
auto currentType = type;
while (currentType)
{
vint index = currentType->Props().Keys().IndexOf(name);
if (index != -1)
{
return currentType->Props().Values()[index];
}
currentType = currentType->baseClass;
}
return nullptr;
}
/***********************************************************************
AstDefFile
***********************************************************************/
template<typename T>
T* AstDefFile::CreateSymbol(const WString& symbolName, ParsingTextRange codeRange)
{
auto symbol = new T(this, symbolName);
if (!symbols.Add(symbolName, symbol))
{
AddError(
ParserErrorType::DuplicatedSymbol,
codeRange,
name,
symbolName
);
}
else if (!ownerManager->symbolMap.Keys().Contains(symbolName))
{
ownerManager->symbolMap.Add(symbolName, symbol);
}
else
{
AddError(
ParserErrorType::DuplicatedSymbolGlobally,
codeRange,
name,
symbolName,
ownerManager->symbolMap[symbolName]->Owner()->name
);
}
return symbol;
}
AstDefFile::AstDefFile(ParserSymbolManager* _global, AstSymbolManager* _ownerManager, const WString& _name)
: global(_global)
, ownerManager(_ownerManager)
, name(_name)
{
}
bool AstDefFile::AddDependency(const WString& dependency, ParsingTextRange codeRange)
{
if (dependencies.Contains(dependency)) return true;
if (!ownerManager->Files().Keys().Contains(dependency))
{
AddError(
ParserErrorType::FileDependencyNotExists,
codeRange,
name,
dependency
);
return false;
}
List<WString> visited;
visited.Add(dependency);
for (vint i = 0; i < visited.Count(); i++)
{
auto currentName = visited[i];
if (currentName == name)
{
AddError(
ParserErrorType::FileCyclicDependency,
codeRange,
name,
dependency
);
return false;
}
auto current = ownerManager->Files()[currentName];
for (vint j = 0; j < current->dependencies.Count(); j++)
{
auto dep = current->dependencies[j];
if (!visited.Contains(dep))
{
visited.Add(dep);
}
}
}
dependencies.Add(dependency);
return true;
}
AstEnumSymbol* AstDefFile::CreateEnum(const WString& symbolName, ParsingTextRange codeRange)
{
return CreateSymbol<AstEnumSymbol>(symbolName, codeRange);
}
AstClassSymbol* AstDefFile::CreateClass(const WString& symbolName, ParsingTextRange codeRange)
{
return CreateSymbol<AstClassSymbol>(symbolName, codeRange);
}
/***********************************************************************
AstSymbolManager
***********************************************************************/
AstSymbolManager::AstSymbolManager(ParserSymbolManager& _global)
: global(_global)
{
}
AstDefFile* AstSymbolManager::CreateFile(const WString& name)
{
auto file = new AstDefFile(&global, this, name);
if (!files.Add(name, file))
{
file->AddError(
ParserErrorType::DuplicatedFile,
{},
name
);
}
return file;
}
}
}
}
/***********************************************************************
.\AST\ASTSYMBOL_CREATEPARSERGENRULEAST.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
/***********************************************************************
CreateParserGenRuleAst
***********************************************************************/
AstDefFile* CreateParserGenRuleAst(AstSymbolManager& manager)
{
auto _ast = manager.CreateFile(L"RuleAst");
Fill(_ast->cppNss, L"vl", L"glr", L"parsergen");
Fill(_ast->refNss, L"glr", L"parsergen");
_ast->classPrefix = L"Glr";
auto _Syntax = _ast->CreateClass(L"Syntax");
auto _RefSyntax = _ast->CreateClass(L"RefSyntax");
_RefSyntax->SetBaseClass(L"Syntax");
_RefSyntax->CreateProp(L"name")->SetPropType(AstPropType::Token);
_RefSyntax->CreateProp(L"field")->SetPropType(AstPropType::Token);
auto _LiteralSyntax = _ast->CreateClass(L"LiteralSyntax");
_LiteralSyntax->SetBaseClass(L"Syntax");
_LiteralSyntax->CreateProp(L"value")->SetPropType(AstPropType::Token);
auto _UseSyntax = _ast->CreateClass(L"UseSyntax");
_UseSyntax->SetBaseClass(L"Syntax");
_UseSyntax->CreateProp(L"name")->SetPropType(AstPropType::Token);
auto _LoopSyntax = _ast->CreateClass(L"LoopSyntax");
_LoopSyntax->SetBaseClass(L"Syntax");
_LoopSyntax->CreateProp(L"syntax")->SetPropType(AstPropType::Type, L"Syntax");
_LoopSyntax->CreateProp(L"delimiter")->SetPropType(AstPropType::Type, L"Syntax");
auto _OptionalPriority = _ast->CreateEnum(L"OptionalPriority");
_OptionalPriority->CreateItem(L"Equal");
_OptionalPriority->CreateItem(L"PreferTake");
_OptionalPriority->CreateItem(L"PreferSkip");
auto _OptionalSyntax = _ast->CreateClass(L"OptionalSyntax");
_OptionalSyntax->SetBaseClass(L"Syntax");
_OptionalSyntax->CreateProp(L"priority")->SetPropType(AstPropType::Type, L"OptionalPriority");
_OptionalSyntax->CreateProp(L"syntax")->SetPropType(AstPropType::Type, L"Syntax");
auto _SequenceSyntax = _ast->CreateClass(L"SequenceSyntax");
_SequenceSyntax->SetBaseClass(L"Syntax");
_SequenceSyntax->CreateProp(L"first")->SetPropType(AstPropType::Type, L"Syntax");
_SequenceSyntax->CreateProp(L"second")->SetPropType(AstPropType::Type, L"Syntax");
auto _AlternativeSyntax = _ast->CreateClass(L"AlternativeSyntax");
_AlternativeSyntax->SetBaseClass(L"Syntax");
_AlternativeSyntax->CreateProp(L"first")->SetPropType(AstPropType::Type, L"Syntax");
_AlternativeSyntax->CreateProp(L"second")->SetPropType(AstPropType::Type, L"Syntax");
auto _Clause = _ast->CreateClass(L"Clause");
auto _Assignment = _ast->CreateClass(L"Assignment");
_Assignment->CreateProp(L"field")->SetPropType(AstPropType::Token);
_Assignment->CreateProp(L"value")->SetPropType(AstPropType::Token);
auto _CreateClause = _ast->CreateClass(L"CreateClause");
_CreateClause->SetBaseClass(L"Clause");
_CreateClause->CreateProp(L"type")->SetPropType(AstPropType::Token);
_CreateClause->CreateProp(L"syntax")->SetPropType(AstPropType::Type, L"Syntax");
_CreateClause->CreateProp(L"assignments")->SetPropType(AstPropType::Array, L"Assignment");
auto _PartialClause = _ast->CreateClass(L"PartialClause");
_PartialClause->SetBaseClass(L"Clause");
_PartialClause->CreateProp(L"type")->SetPropType(AstPropType::Token);
_PartialClause->CreateProp(L"syntax")->SetPropType(AstPropType::Type, L"Syntax");
_PartialClause->CreateProp(L"assignments")->SetPropType(AstPropType::Array, L"Assignment");
auto _ReuseClause = _ast->CreateClass(L"ReuseClause");
_ReuseClause->SetBaseClass(L"Clause");
_ReuseClause->CreateProp(L"syntax")->SetPropType(AstPropType::Type, L"Syntax");
_ReuseClause->CreateProp(L"assignments")->SetPropType(AstPropType::Array, L"Assignment");
auto _Rule = _ast->CreateClass(L"Rule");
_Rule->CreateProp(L"name")->SetPropType(AstPropType::Token);
_Rule->CreateProp(L"clauses")->SetPropType(AstPropType::Array, L"Clause");
auto _File = _ast->CreateClass(L"SyntaxFile");
_File->CreateProp(L"rules")->SetPropType(AstPropType::Array, L"Rule");
return _ast;
}
}
}
}
/***********************************************************************
.\AST\ASTSYMBOL_CREATEPARSERGENTYPEAST.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
/***********************************************************************
CreateParserGenTypeAst
***********************************************************************/
AstDefFile* CreateParserGenTypeAst(AstSymbolManager& manager)
{
auto _ast = manager.CreateFile(L"TypeAst");
Fill(_ast->cppNss, L"vl", L"glr", L"parsergen");
Fill(_ast->refNss, L"glr", L"parsergen");
_ast->classPrefix = L"Glr";
auto _type = _ast->CreateClass(L"Type");
_type->CreateProp(L"name")->SetPropType(AstPropType::Token);
auto _enumItem = _ast->CreateClass(L"EnumItem");
_enumItem->CreateProp(L"name")->SetPropType(AstPropType::Token);
auto _enum = _ast->CreateClass(L"Enum");
_enum->SetBaseClass(L"Type");
_enum->CreateProp(L"items")->SetPropType(AstPropType::Array, L"EnumItem");
auto _propType = _ast->CreateEnum(L"PropType");
_propType->CreateItem(L"Token");
_propType->CreateItem(L"Type");
_propType->CreateItem(L"Array");
auto _classProp = _ast->CreateClass(L"ClassProp");
_classProp->CreateProp(L"name")->SetPropType(AstPropType::Token);
_classProp->CreateProp(L"propType")->SetPropType(AstPropType::Type, L"PropType");
_classProp->CreateProp(L"propTypeName")->SetPropType(AstPropType::Token);
auto _classAmbiguity = _ast->CreateEnum(L"ClassAmbiguity");
_classAmbiguity->CreateItem(L"No");
_classAmbiguity->CreateItem(L"Yes");
auto _class = _ast->CreateClass(L"Class");
_class->SetBaseClass(L"Type");
_class->CreateProp(L"baseClass")->SetPropType(AstPropType::Token);
_class->CreateProp(L"ambiguity")->SetPropType(AstPropType::Type, L"ClassAmbiguity");
_class->CreateProp(L"props")->SetPropType(AstPropType::Array, L"ClassProp");
auto _file = _ast->CreateClass(L"AstFile");
_file->CreateProp(L"types")->SetPropType(AstPropType::Array, L"Type");
return _ast;
}
}
}
}
/***********************************************************************
.\LEXER\LEXERCPPGEN.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace stream;
using namespace regex;
/***********************************************************************
WriteLexerHeaderFile
***********************************************************************/
void WriteLexerHeaderFile(LexerSymbolManager& manager, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer)
{
WriteFileComment(manager.Global().name, writer);
if (manager.Global().headerGuard != L"")
{
writer.WriteString(L"#ifndef ");
writer.WriteLine(manager.Global().headerGuard + L"_LEXER");
writer.WriteString(L"#define ");
writer.WriteLine(manager.Global().headerGuard + L"_LEXER");
}
else
{
writer.WriteLine(L"#pragma once");
}
writer.WriteLine(L"");
for (auto include : manager.Global().includes)
{
if (include.Length() > 0 && include[0] == L'<')
{
writer.WriteLine(L"#include " + include);
}
else
{
writer.WriteLine(L"#include \"" + include + L"\"");
}
}
writer.WriteLine(L"");
WString prefix = WriteNssBegin(manager.Global().cppNss, writer);
{
vint index = 0;
writer.WriteLine(prefix + L"enum class " + manager.Global().name + L"Tokens : vl::vint32_t");
writer.WriteLine(prefix + L"{");
for (auto tokenName : manager.TokenOrder())
{
auto tokenSymbol = manager.Tokens()[tokenName];
output->tokenIds.Add(tokenSymbol, (vint32_t)index);
writer.WriteLine(prefix + L"\t" + tokenSymbol->Name() + L" = " + itow(index) + L",");
index++;
}
writer.WriteLine(prefix + L"};");
}
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"constexpr vl::vint " + manager.Global().name + L"TokenCount = " + itow(manager.Tokens().Count()) + L";");
writer.WriteLine(prefix + L"extern bool " + manager.Global().name + L"TokenDeleter(vl::vint token);");
writer.WriteLine(prefix + L"extern const wchar_t* " + manager.Global().name + L"TokenId(" + manager.Global().name + L"Tokens token);");
writer.WriteLine(prefix + L"extern const wchar_t* " + manager.Global().name + L"TokenDisplayText(" + manager.Global().name + L"Tokens token);");
writer.WriteLine(prefix + L"extern const wchar_t* " + manager.Global().name + L"TokenRegex(" + manager.Global().name + L"Tokens token);");
WriteLoadDataFunctionHeader(prefix, manager.Global().name + L"LexerData", writer);
}
WriteNssEnd(manager.Global().cppNss, writer);
if (manager.Global().headerGuard != L"")
{
writer.WriteString(L"#endif");
}
}
/***********************************************************************
WriteLexerCppFile
***********************************************************************/
void WriteLexerCppFile(LexerSymbolManager& manager, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer)
{
WriteFileComment(manager.Global().name, writer);
writer.WriteLine(L"#include \"" + output->lexerH + L"\"");
writer.WriteLine(L"");
WString prefix = WriteNssBegin(manager.Global().cppNss, writer);
{
writer.WriteLine(prefix + L"bool " + manager.Global().name + L"TokenDeleter(vl::vint token)");
writer.WriteLine(prefix + L"{");
List<WString> discarded;
for (auto tokenSymbol : manager.Tokens().Values())
{
if (tokenSymbol->discarded)
{
discarded.Add(tokenSymbol->Name());
}
}
if (discarded.Count() > 0)
{
writer.WriteLine(prefix + L"\tswitch((" + manager.Global().name + L"Tokens)token)");
writer.WriteLine(prefix + L"\t{");
for (auto tokenName : discarded)
{
writer.WriteLine(prefix + L"\tcase " + manager.Global().name + L"Tokens::" + tokenName + L":");
}
writer.WriteLine(prefix + L"\t\treturn true;");
writer.WriteLine(prefix + L"\tdefault:");
writer.WriteLine(prefix + L"\t\treturn false;");
writer.WriteLine(prefix + L"\t}");
}
else
{
writer.WriteLine(prefix + L"\treturn false;");
}
writer.WriteLine(prefix + L"}");
}
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"const wchar_t* " + manager.Global().name + L"TokenId(" + manager.Global().name + L"Tokens token)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tstatic const wchar_t* results[] = {");
for (auto tokenName : manager.TokenOrder())
{
writer.WriteLine(prefix + L"\t\tL\"" + tokenName + L"\",");
}
writer.WriteLine(prefix + L"\t};");
writer.WriteLine(prefix + L"\tvl::vint index = (vl::vint)token;");
writer.WriteLine(prefix + L"\treturn 0 <= index && index < " + manager.Global().name + L"TokenCount ? results[index] : nullptr;");
writer.WriteLine(prefix + L"}");
}
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"const wchar_t* " + manager.Global().name + L"TokenDisplayText(" + manager.Global().name + L"Tokens token)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tstatic const wchar_t* results[] = {");
for (auto tokenName : manager.TokenOrder())
{
auto displayText = manager.Tokens()[tokenName]->displayText;
if (displayText == L"")
{
writer.WriteLine(prefix + L"\t\tnullptr,");
}
else
{
writer.WriteString(prefix + L"\t\tL\"");
WriteCppStringBody(displayText, writer);
writer.WriteLine(L"\",");
}
}
writer.WriteLine(prefix + L"\t};");
writer.WriteLine(prefix + L"\tvl::vint index = (vl::vint)token;");
writer.WriteLine(prefix + L"\treturn 0 <= index && index < " + manager.Global().name + L"TokenCount ? results[index] : nullptr;");
writer.WriteLine(prefix + L"}");
}
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"const wchar_t* " + manager.Global().name + L"TokenRegex(" + manager.Global().name + L"Tokens token)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tstatic const wchar_t* results[] = {");
for (auto tokenName : manager.TokenOrder())
{
writer.WriteString(prefix + L"\t\tL\"");
WriteCppStringBody(manager.Tokens()[tokenName]->regex, writer);
writer.WriteLine(L"\",");
}
writer.WriteLine(prefix + L"\t};");
writer.WriteLine(prefix + L"\tvl::vint index = (vl::vint)token;");
writer.WriteLine(prefix + L"\treturn 0 <= index && index < " + manager.Global().name + L"TokenCount ? results[index] : nullptr;");
writer.WriteLine(prefix + L"}");
}
{
MemoryStream lexerData;
{
RegexLexer lexer(
From(manager.TokenOrder())
.Select([&](const WString& name) { return manager.Tokens()[name]->regex; })
);
lexer.Serialize(lexerData);
}
lexerData.SeekFromBegin(0);
writer.WriteLine(L"");
WriteLoadDataFunctionCpp(prefix, manager.Global().name + L"LexerData", lexerData, true, writer);
}
WriteNssEnd(manager.Global().cppNss, writer);
}
/***********************************************************************
WriteLexerFiles
***********************************************************************/
void WriteLexerFiles(LexerSymbolManager& manager, Ptr<CppParserGenOutput> output, collections::Dictionary<WString, WString>& files)
{
WString fileH = GenerateToStream([&](StreamWriter& writer)
{
WriteLexerHeaderFile(manager, output, writer);
});
WString fileCpp = GenerateToStream([&](StreamWriter& writer)
{
WriteLexerCppFile(manager, output, writer);
});
files.Add(output->lexerH, fileH);
files.Add(output->lexerCpp, fileCpp);
}
}
}
}
/***********************************************************************
.\LEXER\LEXERSYMBOL.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
/***********************************************************************
TokenSymbol
***********************************************************************/
TokenSymbol::TokenSymbol(LexerSymbolManager* _ownerManager, const WString& _name)
: ownerManager(_ownerManager)
, name(_name)
{
}
/***********************************************************************
LexerSymbolManager
***********************************************************************/
LexerSymbolManager::LexerSymbolManager(ParserSymbolManager& _global)
: global(_global)
{
}
TokenSymbol* LexerSymbolManager::CreateToken(const WString& _name, const WString& _regex, ParsingTextRange codeRange)
{
auto token = new TokenSymbol(this, _name);
token->regex = _regex;
if (!tokens.Add(_name, token))
{
AddError(
ParserErrorType::DuplicatedToken,
codeRange,
_name
);
}
try
{
auto expr = regex_internal::ParseRegexExpression(wtou32(_regex));
if (!expr->expression->HasNoExtension())
{
AddError(
ParserErrorType::TokenRegexNotPure,
codeRange,
_name
);
}
Array<char32_t> buffer(_regex.Length() + 1);
memset(&buffer[0], 0, sizeof(char32_t) * buffer.Count());
vint writing = 0;
List<regex_internal::Expression*> expanding;
expanding.Add(expr->expression.Obj());
while (expanding.Count() > 0)
{
auto current = expanding[expanding.Count() - 1];
if (auto charset = dynamic_cast<regex_internal::CharSetExpression*>(current))
{
if (charset->ranges.Count() == 1 && !charset->reverse)
{
auto range = charset->ranges[0];
if (range.begin == range.end)
{
expanding.RemoveAt(expanding.Count() - 1);
buffer[writing++] = range.begin;
continue;
}
}
}
else if (auto sequence = dynamic_cast<regex_internal::SequenceExpression*>(current))
{
expanding.RemoveAt(expanding.Count() - 1);
expanding.Add(sequence->right.Obj());
expanding.Add(sequence->left.Obj());
continue;
}
goto FINISHED_CALCULATING_DISPLAY_TEXT;
}
FINISHED_CALCULATING_DISPLAY_TEXT:
if (expanding.Count() == 0)
{
token->displayText = u32tow(&buffer[0]);
if (tokensByDisplayText.Keys().Contains(token->displayText))
{
AddError(
ParserErrorType::DuplicatedTokenByDisplayText,
codeRange,
_name
);
}
else
{
tokensByDisplayText.Add(token->displayText, token);
}
}
}
catch (const regex_internal::RegexException& e)
{
AddError(
ParserErrorType::InvalidTokenRegex,
codeRange,
_name,
(e.Message() + L" : " + itow(e.position) + L" : " + _regex)
);
}
return token;
}
TokenSymbol* LexerSymbolManager::CreateDiscardedToken(const WString& _name, const WString& _regex, ParsingTextRange codeRange)
{
auto token = CreateToken(_name, _regex, codeRange);
token->discarded = true;
return token;
}
}
}
}
/***********************************************************************
.\LEXER\LEXERSYMBOL_CREATEPARSERGENLEXER.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
/***********************************************************************
CreateParserGenAst
***********************************************************************/
void CreateParserGenLexer(LexerSymbolManager& manager)
{
manager.CreateToken(L"AMBIGUOUS", L"ambiguous");
manager.CreateToken(L"CLASS", L"class");
manager.CreateToken(L"ENUM", L"enum");
manager.CreateToken(L"VAR", L"var");
manager.CreateToken(L"TOKEN", L"token");
manager.CreateToken(L"AS", L"as");
manager.CreateToken(L"PARTIAL", L"partial");
manager.CreateToken(L"OPEN_ROUND", L"/(");
manager.CreateToken(L"CLOSE_ROUND", L"/)");
manager.CreateToken(L"OPEN_SQUARE", L"/[");
manager.CreateToken(L"CLOSE_SQUARE", L"/]");
manager.CreateToken(L"OPEN_CURLY", L"/{");
manager.CreateToken(L"CLOSE_CURLY", L"/}");
manager.CreateToken(L"COMMA", L",");
manager.CreateToken(L"COLON", L":");
manager.CreateToken(L"SEMICOLON", L";");
manager.CreateToken(L"INFER", L"::=");
manager.CreateToken(L"ALTERNATIVE", L"/|");
manager.CreateToken(L"USE", L"!");
manager.CreateToken(L"ASSIGN", L"=");
manager.CreateToken(L"POSITIVE", L"/+");
manager.CreateToken(L"NEGATIVE", L"-");
manager.CreateToken(L"ID", L"[a-zA-Z_][a-zA-Z0-9_]*");
manager.CreateToken(L"STRING", L"(\"[^\"]*\")+");
manager.CreateDiscardedToken(L"SPACE", L"/s+");
manager.CreateDiscardedToken(L"COMMENT", L"////[^/r/n]*");
}
}
}
}
/***********************************************************************
.\PARSERGEN\COMPILEAST.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
/***********************************************************************
CompileAst
***********************************************************************/
class CreateAstSymbolVisitor :public Object, public virtual GlrType::IVisitor
{
protected:
AstDefFile* astDefFile;
public:
CreateAstSymbolVisitor(AstDefFile* _astDefFile)
: astDefFile(_astDefFile)
{
}
void Visit(GlrEnum* node) override
{
astDefFile->CreateEnum(node->name.value, node->name.codeRange);
}
void Visit(GlrClass* node) override
{
astDefFile->CreateClass(node->name.value, node->name.codeRange);
}
};
class FillAstSymbolVisitor :public Object, public virtual GlrType::IVisitor
{
protected:
AstDefFile* astDefFile;
public:
FillAstSymbolVisitor(AstDefFile* _astDefFile)
: astDefFile(_astDefFile)
{
}
void Visit(GlrEnum* node) override
{
auto enumSymbol = dynamic_cast<AstEnumSymbol*>(astDefFile->Symbols()[node->name.value]);
for (auto item : node->items)
{
enumSymbol->CreateItem(item->name.value, item->name.codeRange);
}
}
void Visit(GlrClass* node) override
{
auto classSymbol = dynamic_cast<AstClassSymbol*>(astDefFile->Symbols()[node->name.value]);
if (node->baseClass)
{
classSymbol->SetBaseClass(node->baseClass.value, node->baseClass.codeRange);
}
if (node->ambiguity == GlrClassAmbiguity::Yes)
{
classSymbol->CreateAmbiguousDerivedClass(node->name.codeRange);
}
for (auto prop : node->props)
{
auto propSymbol = classSymbol->CreateProp(prop->name.value, prop->name.codeRange);
switch (prop->propType)
{
case GlrPropType::Token:
propSymbol->SetPropType(AstPropType::Token);
break;
case GlrPropType::Type:
propSymbol->SetPropType(AstPropType::Type, prop->propTypeName.value, prop->propTypeName.codeRange);
break;
case GlrPropType::Array:
propSymbol->SetPropType(AstPropType::Array, prop->propTypeName.value, prop->propTypeName.codeRange);
break;
default:;
}
}
}
};
void CompileAst(AstSymbolManager& astManager, AstDefFile* astDefFile, Ptr<GlrAstFile> file)
{
{
CreateAstSymbolVisitor visitor(astDefFile);
for (auto type : file->types)
{
type->Accept(&visitor);
}
}
if (astManager.Global().Errors().Count() == 0)
{
FillAstSymbolVisitor visitor(astDefFile);
for (auto type : file->types)
{
type->Accept(&visitor);
}
}
}
}
}
}
/***********************************************************************
.\PARSERGEN\COMPILELEXER.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace stream;
using namespace regex;
/***********************************************************************
CompileLexer
***********************************************************************/
void CompileLexer(LexerSymbolManager& lexerManager, const WString& input)
{
Regex regexToken(L"^(/s*|(<discard>discard/s)?/s*(<name>[a-zA-Z_]/w*):(<regex>/.+))$");
vint _discard = regexToken.CaptureNames().IndexOf(L"discard");
vint _name = regexToken.CaptureNames().IndexOf(L"name");
vint _regex = regexToken.CaptureNames().IndexOf(L"regex");
StringReader reader(input);
vint lineIndex = 0;
while (!reader.IsEnd())
{
auto line = reader.ReadLine();
ParsingTextRange codeRange = { {lineIndex,0}, {lineIndex,0} };
if (auto match = regexToken.MatchHead(line))
{
if (match->Groups().Keys().Contains(_name))
{
auto tokenName = match->Groups()[_name][0].Value();
auto tokenRegex = match->Groups()[_regex][0].Value();
if (match->Groups().Keys().Contains(_discard))
{
lexerManager.CreateDiscardedToken(tokenName, tokenRegex, codeRange);
}
else
{
lexerManager.CreateToken(tokenName, tokenRegex, codeRange);
}
}
}
else
{
lexerManager.AddError(
ParserErrorType::InvalidTokenDefinition,
codeRange,
line
);
}
lineIndex++;
}
}
}
}
}
/***********************************************************************
.\PARSERGEN\COMPILESYNTAX.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace compile_syntax;
extern void ResolveName(VisitorContext& context, List<Ptr<GlrSyntaxFile>>& files);
extern void ValidatePartialRules(VisitorContext& context, List<Ptr<GlrSyntaxFile>>& files);
extern void CalculateRuleAndClauseTypes(VisitorContext& context);
extern void ValidateTypes(VisitorContext& context, List<Ptr<GlrSyntaxFile>>& files);
extern void ValidateStructure(VisitorContext& context, List<Ptr<GlrSyntaxFile>>& files);
extern void CompileSyntax(VisitorContext& context, List<Ptr<GlrSyntaxFile>>& files);
/***********************************************************************
CompileSyntax
***********************************************************************/
void CompileSyntax(AstSymbolManager& astManager, LexerSymbolManager& lexerManager, SyntaxSymbolManager& syntaxManager, Ptr<CppParserGenOutput> output, collections::List<Ptr<GlrSyntaxFile>>& files)
{
VisitorContext context(astManager, lexerManager, syntaxManager, output);
for (auto file : files)
{
for (auto rule : file->rules)
{
if (context.lexerManager.Tokens().Keys().Contains(rule->name.value))
{
context.syntaxManager.AddError(
ParserErrorType::RuleNameConflictedWithToken,
rule->codeRange,
rule->name.value
);
}
else
{
auto ruleSymbol = context.syntaxManager.CreateRule(rule->name.value, rule->codeRange);
context.astRules.Add(ruleSymbol, rule.Obj());
}
}
}
if (syntaxManager.Global().Errors().Count() > 0) return;
ResolveName(context, files);
if (syntaxManager.Global().Errors().Count() > 0) return;
ValidatePartialRules(context, files);
if (syntaxManager.Global().Errors().Count() > 0) return;
CalculateRuleAndClauseTypes(context);
if (syntaxManager.Global().Errors().Count() > 0) return;
ValidateTypes(context, files);
if (syntaxManager.Global().Errors().Count() > 0) return;
ValidateStructure(context, files);
if (syntaxManager.Global().Errors().Count() > 0) return;
CompileSyntax(context, files);
}
}
}
}
/***********************************************************************
.\PARSERGEN\COMPILESYNTAX_CALCULATETYPES.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace compile_syntax;
/***********************************************************************
ValidatePartialRules
***********************************************************************/
void ValidatePartialRules(VisitorContext& context, List<Ptr<GlrSyntaxFile>>& files)
{
for (auto file : files)
{
for (auto rule : file->rules)
{
List<Ptr<GlrPartialClause>> partialClauses;
CopyFrom(partialClauses, From(rule->clauses).FindType<GlrPartialClause>());
if (partialClauses.Count() == 0) continue;
auto ruleSymbol = context.syntaxManager.Rules()[rule->name.value];
ruleSymbol->isPartial = partialClauses.Count() > 0;
if (partialClauses.Count() != rule->clauses.Count())
{
context.syntaxManager.AddError(
ParserErrorType::RuleMixedPartialClauseWithOtherClause,
rule->codeRange,
ruleSymbol->Name()
);
}
AstClassSymbol* partialType = nullptr;
for (auto clause : partialClauses)
{
vint index = context.clauseTypes.Keys().IndexOf(clause.Obj());
if (index != -1)
{
auto type = context.clauseTypes.Values()[index];
if (!partialType)
{
partialType = type;
}
else if (type && partialType != type)
{
context.syntaxManager.AddError(
ParserErrorType::RuleWithDifferentPartialTypes,
rule->codeRange,
ruleSymbol->Name()
);
break;
}
}
}
}
}
}
/***********************************************************************
CalculateRuleAndClauseTypes
***********************************************************************/
void CalculateRuleAndClauseTypes(VisitorContext& context)
{
// find cyclic dependencies in "Rule ::= !Rule"
auto&& rules = context.syntaxManager.Rules().Values();
PartialOrderingProcessor pop;
pop.InitWithGroup(rules, context.ruleReuseDependencies);
pop.Sort();
// remove cyclic dependended rules from ruleReuseDependencies
List<List<RuleSymbol*>> cyclicReuseDependencies;
for (auto&& component : pop.components)
{
if (component.nodeCount == 1) continue;
for (vint i = 0; i < component.nodeCount - 1; i++)
{
for (vint j = i + 1; j < component.nodeCount; j++)
{
auto r1 = rules[component.firstNode[i]];
auto r2 = rules[component.firstNode[j]];
context.ruleReuseDependencies.Remove(r1, r2);
context.ruleReuseDependencies.Remove(r2, r1);
}
}
List<RuleSymbol*> cyclicRules;
for (vint i = 0; i < component.nodeCount; i++)
{
cyclicRules.Add(rules[component.firstNode[i]]);
}
cyclicReuseDependencies.Add(std::move(cyclicRules));
}
// calculate types for rules from clauses with known types
for (auto rule : rules)
{
for (auto clause : context.astRules[rule]->clauses)
{
vint index = context.clauseTypes.Keys().IndexOf(clause.Obj());
if (index != -1)
{
rule->ruleType = FindCommonBaseClass(rule->ruleType, context.clauseTypes.Values()[index]);
if (!rule->ruleType)
{
context.syntaxManager.AddError(
ParserErrorType::RuleCannotResolveToDeterministicType,
context.astRules[rule]->codeRange,
rule->Name()
);
break;
}
}
}
}
if (context.global.Errors().Count() > 0) return;
// calculate types for rules that contain reuse dependency
for (auto&& component : pop.components)
{
for (vint i = 0; i < component.nodeCount; i++)
{
auto rule = rules[component.firstNode[i]];
vint index = context.ruleReuseDependencies.Keys().IndexOf(rule);
if (index != -1)
{
AstClassSymbol* type = nullptr;
for (auto dep : context.ruleReuseDependencies.GetByIndex(index))
{
type = FindCommonBaseClass(type, dep->ruleType);
}
if (type)
{
rule->ruleType = FindCommonBaseClass(rule->ruleType, type);
if (!rule->ruleType)
{
context.syntaxManager.AddError(
ParserErrorType::RuleCannotResolveToDeterministicType,
context.astRules[rule]->codeRange,
rule->Name()
);
break;
}
}
}
}
}
if (context.global.Errors().Count() > 0) return;
// calculate types for rules that contain cyclic reuse dependency
for (auto&& cyclicRules : cyclicReuseDependencies)
{
AstClassSymbol* type = nullptr;
for (auto rule : cyclicRules)
{
type = FindCommonBaseClass(type, rule->ruleType);
}
if (!type)
{
for (auto rule : cyclicRules)
{
context.syntaxManager.AddError(
ParserErrorType::CyclicDependedRuleTypeIncompatible,
context.astRules[rule]->codeRange,
rule->Name()
);
}
}
else
{
for (auto rule : cyclicRules)
{
rule->ruleType = type;
}
}
}
// prompt errors
for (auto rule : rules)
{
if (!rule->ruleType)
{
context.syntaxManager.AddError(
ParserErrorType::RuleCannotResolveToDeterministicType,
context.astRules[rule]->codeRange,
rule->Name()
);
}
}
// calculate types for reuse clauses
for (auto astRule : context.astRules.Values())
{
for (auto clause : From(astRule->clauses).FindType<GlrReuseClause>())
{
vint index = context.clauseReuseDependencies.Keys().IndexOf(clause.Obj());
if (index == -1)
{
context.syntaxManager.AddError(
ParserErrorType::ReuseClauseContainsNoUseRule,
clause->codeRange,
astRule->name.value
);
}
else
{
AstClassSymbol* type = nullptr;
for (auto dep : context.clauseReuseDependencies.GetByIndex(index))
{
type = FindCommonBaseClass(type, dep->ruleType);
}
if (type)
{
context.clauseTypes.Add(clause.Obj(), type);
}
else
{
context.syntaxManager.AddError(
ParserErrorType::ReuseClauseCannotResolveToDeterministicType,
clause->codeRange,
astRule->name.value
);
}
}
}
}
}
}
}
}
/***********************************************************************
.\PARSERGEN\COMPILESYNTAX_COMPILESYNTAX.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace compile_syntax;
/***********************************************************************
CompileSyntaxVisitor
***********************************************************************/
class CompileSyntaxVisitor
: public Object
, protected virtual GlrSyntax::IVisitor
, protected virtual GlrClause::IVisitor
{
protected:
struct StatePair
{
StateSymbol* begin;
StateSymbol* end;
};
using StatePosMap = Dictionary<StateSymbol*, vint>;
protected:
VisitorContext& context;
RuleSymbol* ruleSymbol;
AstClassSymbol* clauseType;
WString clauseDisplayText;
StatePosMap startPoses;
StatePosMap endPoses;
StatePair result;
StateSymbol* CreateState()
{
return ruleSymbol->Owner()->CreateState(ruleSymbol, ruleSymbol->CurrentClauseId());
}
EdgeSymbol* CreateEdge(StateSymbol* from, StateSymbol* to)
{
return ruleSymbol->Owner()->CreateEdge(from, to);
}
StatePair Build(const Ptr<GlrSyntax>& node)
{
node->Accept(this);
return result;
}
StatePair Build(const Ptr<GlrClause>& node)
{
node->Accept(this);
return result;
}
public:
CompileSyntaxVisitor(
VisitorContext& _context,
RuleSymbol* _ruleSymbol
)
: context(_context)
, ruleSymbol(_ruleSymbol)
{
}
void AssignClause(const Ptr<GlrClause>& node)
{
ruleSymbol->NewClause();
clauseDisplayText = L"";
startPoses.Clear();
endPoses.Clear();
auto pair = Build(node);
ruleSymbol->startStates.Add(pair.begin);
pair.end->endingState = true;
vint l = clauseDisplayText.Length();
for (auto [state, pos] : startPoses)
{
state->label = clauseDisplayText.Left(pos) + L"@ " + clauseDisplayText.Right(l - pos);
}
for (auto [state, pos] : endPoses)
{
state->label = clauseDisplayText.Left(pos) + L" @" + clauseDisplayText.Right(l - pos);
}
}
protected:
void Visit(GlrRefSyntax* node) override
{
{
vint index = context.lexerManager.TokenOrder().IndexOf(node->name.value);
if (index != -1)
{
auto token = context.lexerManager.Tokens()[node->name.value];
StatePair pair;
pair.begin = CreateState();
pair.end = CreateState();
startPoses.Add(pair.begin, clauseDisplayText.Length());
{
auto edge = CreateEdge(pair.begin, pair.end);
edge->input.type = EdgeInputType::Token;
edge->input.token = (vint32_t)index;
if (node->field)
{
auto propSymbol = FindPropSymbol(clauseType, node->field.value);
edge->insAfterInput.Add({ AstInsType::Token });
edge->insAfterInput.Add({ AstInsType::Field,context.output->fieldIds[propSymbol] });
}
}
clauseDisplayText += token->displayText == L"" ? token->Name() : L"\"" + token->displayText + L"\"";
endPoses.Add(pair.end, clauseDisplayText.Length());
result = pair;
return;
}
}
{
vint index = context.syntaxManager.Rules().Keys().IndexOf(node->name.value);
if (index != -1)
{
auto rule = context.syntaxManager.Rules().Values()[index];
StatePair pair;
pair.begin = CreateState();
pair.end = CreateState();
startPoses.Add(pair.begin, clauseDisplayText.Length());
{
auto edge = CreateEdge(pair.begin, pair.end);
edge->input.type = EdgeInputType::Rule;
edge->input.rule = rule;
if (node->field)
{
auto propSymbol = FindPropSymbol(clauseType, node->field.value);
edge->insAfterInput.Add({ AstInsType::Field,context.output->fieldIds[propSymbol] });
}
else if (!rule->isPartial)
{
edge->insAfterInput.Add({ AstInsType::DiscardValue });
}
}
clauseDisplayText += rule->Name();
endPoses.Add(pair.end, clauseDisplayText.Length());
result = pair;
return;
}
}
CHECK_FAIL(L"Should not reach here!");
}
void Visit(GlrLiteralSyntax* node) override
{
vint index = context.literalTokens[node];
auto token = context.lexerManager.Tokens()[context.lexerManager.TokenOrder()[index]];
StatePair pair;
pair.begin = CreateState();
pair.end = CreateState();
startPoses.Add(pair.begin, clauseDisplayText.Length());
{
auto edge = CreateEdge(pair.begin, pair.end);
edge->input.type = EdgeInputType::Token;
edge->input.token = context.literalTokens[node];
}
clauseDisplayText += token->displayText == L"" ? token->Name() : L"\"" + token->displayText + L"\"";
endPoses.Add(pair.end, clauseDisplayText.Length());
result = pair;
}
void Visit(GlrUseSyntax* node) override
{
vint index = context.syntaxManager.Rules().Keys().IndexOf(node->name.value);
if (index == -1)
{
context.syntaxManager.AddError(
ParserErrorType::TokenOrRuleNotExistsInRule,
node->codeRange,
node->name.value
);
return;
}
auto rule = context.syntaxManager.Rules().Values()[index];
StatePair pair;
pair.begin = CreateState();
pair.end = CreateState();
startPoses.Add(pair.begin, clauseDisplayText.Length());
{
auto edge = CreateEdge(pair.begin, pair.end);
edge->input.type = EdgeInputType::Rule;
edge->input.rule = rule;
edge->insAfterInput.Add({ AstInsType::ReopenObject });
}
clauseDisplayText += L"!" + rule->Name();
endPoses.Add(pair.end, clauseDisplayText.Length());
result = pair;
}
void Visit(GlrLoopSyntax* node) override
{
StatePair pair, bodyPair, delimiterPair;
pair.begin = CreateState();
pair.end = CreateState();
startPoses.Add(pair.begin, clauseDisplayText.Length());
clauseDisplayText += L"{ ";
bodyPair = Build(node->syntax);
if (node->delimiter)
{
clauseDisplayText += L" ; ";
delimiterPair = Build(node->delimiter);
}
clauseDisplayText += L" }";
CreateEdge(pair.begin, bodyPair.begin);
CreateEdge(bodyPair.end, pair.end);
CreateEdge(pair.begin, pair.end);
if (node->delimiter)
{
CreateEdge(bodyPair.end, delimiterPair.begin);
CreateEdge(delimiterPair.end, bodyPair.begin);
}
else
{
CreateEdge(bodyPair.end, bodyPair.begin);
}
endPoses.Add(pair.end, clauseDisplayText.Length());
result = pair;
}
void Visit(GlrOptionalSyntax* node) override
{
StatePair pair;
pair.begin = CreateState();
pair.end = CreateState();
startPoses.Add(pair.begin, clauseDisplayText.Length());
switch (node->priority)
{
case GlrOptionalPriority::Equal:
clauseDisplayText += L"[ ";
break;
case GlrOptionalPriority::PreferTake:
clauseDisplayText += L"+[ ";
break;
case GlrOptionalPriority::PreferSkip:
clauseDisplayText += L"-[ ";
break;
default:;
}
auto bodyPair = Build(node->syntax);
clauseDisplayText += L" ]";
auto takeEdge = CreateEdge(pair.begin, bodyPair.begin);
CreateEdge(bodyPair.end, pair.end);
auto skipEdge = CreateEdge(pair.begin, pair.end);
if (node->priority == GlrOptionalPriority::PreferTake)
{
takeEdge->important = true;
}
if (node->priority == GlrOptionalPriority::PreferSkip)
{
skipEdge->important = true;
}
endPoses.Add(pair.end, clauseDisplayText.Length());
result = pair;
}
void Visit(GlrSequenceSyntax* node) override
{
auto firstPair = Build(node->first);
clauseDisplayText += L" ";
auto secondPair = Build(node->second);
CreateEdge(firstPair.end, secondPair.begin);
result = { firstPair.begin,secondPair.end };
}
void Visit(GlrAlternativeSyntax* node) override
{
StatePair pair;
pair.begin = CreateState();
pair.end = CreateState();
startPoses.Add(pair.begin, clauseDisplayText.Length());
clauseDisplayText += L"( ";
auto firstPair = Build(node->first);
clauseDisplayText += L" | ";
auto secondPair = Build(node->second);
clauseDisplayText += L" )";
CreateEdge(pair.begin, firstPair.begin);
CreateEdge(firstPair.end, pair.end);
CreateEdge(pair.begin, secondPair.begin);
CreateEdge(secondPair.end, pair.end);
endPoses.Add(pair.end, clauseDisplayText.Length());
result = pair;
}
StatePair Visit(StatePair pair, GlrAssignment* node)
{
auto withState = CreateState();
auto edge = CreateEdge(pair.end, withState);
auto propSymbol = FindPropSymbol(clauseType, node->field.value);
auto enumSymbol = dynamic_cast<AstEnumSymbol*>(propSymbol->propSymbol);
edge->insBeforeInput.Add({ AstInsType::EnumItem,(vint32_t)enumSymbol->ItemOrder().IndexOf(node->value.value) });
edge->insBeforeInput.Add({ AstInsType::Field,context.output->fieldIds[propSymbol] });
endPoses.Add(withState, clauseDisplayText.Length());
return { pair.begin,withState };
}
void Visit(GlrCreateClause* node) override
{
clauseType = context.clauseTypes[node];
StatePair pair;
pair.begin = CreateState();
pair.end = CreateState();
startPoses.Add(pair.begin, clauseDisplayText.Length());
clauseDisplayText += L"< ";
auto bodyPair = Build(node->syntax);
for (auto assignment : node->assignments)
{
bodyPair = Visit(bodyPair, assignment.Obj());
}
clauseDisplayText += L" >";
{
auto classSymbol = dynamic_cast<AstClassSymbol*>(context.astManager.Symbols()[node->type.value]);
auto edge = CreateEdge(pair.begin, bodyPair.begin);
edge->insBeforeInput.Add({ AstInsType::BeginObject,context.output->classIds[classSymbol] });
}
{
auto edge = CreateEdge(bodyPair.end, pair.end);
edge->insBeforeInput.Add({ AstInsType::EndObject });
}
endPoses.Add(pair.end, clauseDisplayText.Length());
result = pair;
}
void Visit(GlrPartialClause* node) override
{
clauseType = context.clauseTypes[node];
auto bodyPair = Build(node->syntax);
for (auto assignment : node->assignments)
{
bodyPair = Visit(bodyPair, assignment.Obj());
}
result = bodyPair;
}
void Visit(GlrReuseClause* node) override
{
clauseType = context.clauseTypes[node];
StatePair pair;
pair.begin = CreateState();
pair.end = CreateState();
startPoses.Add(pair.begin, clauseDisplayText.Length());
clauseDisplayText += L"<< ";
auto bodyPair = Build(node->syntax);
for (auto assignment : node->assignments)
{
bodyPair = Visit(bodyPair, assignment.Obj());
}
clauseDisplayText += L" >>";
{
auto edge = CreateEdge(pair.begin, bodyPair.begin);
edge->insBeforeInput.Add({ AstInsType::DelayFieldAssignment });
}
{
auto edge = CreateEdge(bodyPair.end, pair.end);
edge->insBeforeInput.Add({ AstInsType::EndObject });
}
endPoses.Add(pair.end, clauseDisplayText.Length());
result = pair;
}
};
/***********************************************************************
CompileSyntax
***********************************************************************/
void CompileSyntax(VisitorContext& context, List<Ptr<GlrSyntaxFile>>& files)
{
for (auto file : files)
{
for (auto rule : file->rules)
{
auto ruleSymbol = context.syntaxManager.Rules()[rule->name.value];
CompileSyntaxVisitor visitor(context, ruleSymbol);
for (auto clause : rule->clauses)
{
visitor.AssignClause(clause);
}
}
}
}
}
}
}
/***********************************************************************
.\PARSERGEN\COMPILESYNTAX_RESOLVENAME.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace compile_syntax;
/***********************************************************************
ResolveNameVisitor
***********************************************************************/
class ResolveNameVisitor
: public Object
, protected virtual GlrSyntax::IVisitor
, protected virtual GlrClause::IVisitor
{
protected:
VisitorContext& context;
RuleSymbol* ruleSymbol;
GlrClause* clause = nullptr;
AstClassSymbol* GetRuleClass(ParsingToken& typeName)
{
vint index = context.astManager.Symbols().Keys().IndexOf(typeName.value);
if (index == -1)
{
context.syntaxManager.AddError(
ParserErrorType::TypeNotExistsInRule,
typeName.codeRange,
ruleSymbol->Name(),
typeName.value
);
return nullptr;
}
auto classSymbol = dynamic_cast<AstClassSymbol*>(context.astManager.Symbols().Values()[index]);
if (!classSymbol)
{
context.syntaxManager.AddError(
ParserErrorType::TypeNotClassInRule,
typeName.codeRange,
ruleSymbol->Name(),
typeName.value
);
}
return classSymbol;
}
public:
ResolveNameVisitor(
VisitorContext& _context,
RuleSymbol* _ruleSymbol
)
: context(_context)
, ruleSymbol(_ruleSymbol)
{
}
void ResolveClause(Ptr<GlrClause> clause)
{
clause->Accept(this);
}
protected:
void Visit(GlrRefSyntax* node) override
{
vint tokenIndex = context.lexerManager.TokenOrder().IndexOf(node->name.value);
vint ruleIndex = context.syntaxManager.Rules().Keys().IndexOf(node->name.value);
if (tokenIndex == -1 && ruleIndex == -1)
{
context.syntaxManager.AddError(
ParserErrorType::TokenOrRuleNotExistsInRule,
node->codeRange,
ruleSymbol->Name(),
node->name.value
);
}
}
void Visit(GlrLiteralSyntax* node) override
{
if (node->value.value.Length() > 2)
{
Array<wchar_t> buffer(node->value.value.Length());
wchar_t* writing = &buffer[0];
for (vint i = 1; i < node->value.value.Length() - 1; i++)
{
wchar_t c = node->value.value[i];
*writing++ = c;
if (c == L'\"')
{
i++;
}
}
*writing = 0;
auto literalValue = WString::Unmanaged(&buffer[0]);
for (auto&& [tokenName, tokenIndex] : indexed(context.lexerManager.TokenOrder()))
{
auto tokenSymbol = context.lexerManager.Tokens()[tokenName];
if (tokenSymbol->displayText==literalValue)
{
context.literalTokens.Add(node, (vint32_t)tokenIndex);
return;
}
}
}
context.syntaxManager.AddError(
ParserErrorType::TokenOrRuleNotExistsInRule,
node->codeRange,
ruleSymbol->Name(),
node->value.value
);
}
void Visit(GlrUseSyntax* node) override
{
vint ruleIndex = context.syntaxManager.Rules().Keys().IndexOf(node->name.value);
if (ruleIndex == -1)
{
context.syntaxManager.AddError(
ParserErrorType::TokenOrRuleNotExistsInRule,
node->codeRange,
ruleSymbol->Name(),
node->name.value
);
}
else if (clause)
{
auto usedRuleSymbol = context.syntaxManager.Rules().Values()[ruleIndex];
if (!context.ruleReuseDependencies.Contains(ruleSymbol, usedRuleSymbol))
{
context.ruleReuseDependencies.Add(ruleSymbol, usedRuleSymbol);
}
if (!context.clauseReuseDependencies.Contains(clause, usedRuleSymbol))
{
context.clauseReuseDependencies.Add(clause, usedRuleSymbol);
}
}
}
void Visit(GlrLoopSyntax* node) override
{
node->syntax->Accept(this);
if (node->delimiter)
{
node->delimiter->Accept(this);
}
}
void Visit(GlrOptionalSyntax* node) override
{
node->syntax->Accept(this);
}
void Visit(GlrSequenceSyntax* node) override
{
node->first->Accept(this);
node->second->Accept(this);
}
void Visit(GlrAlternativeSyntax* node) override
{
node->first->Accept(this);
node->second->Accept(this);
}
void Visit(GlrCreateClause* node) override
{
if (auto classSymbol = GetRuleClass(node->type))
{
context.ruleKnownTypes.Add(ruleSymbol, classSymbol);
context.clauseTypes.Add(node, classSymbol);
}
node->syntax->Accept(this);
}
void Visit(GlrPartialClause* node) override
{
if (auto classSymbol = GetRuleClass(node->type))
{
context.ruleKnownTypes.Add(ruleSymbol, classSymbol);
context.clauseTypes.Add(node, classSymbol);
}
node->syntax->Accept(this);
}
void Visit(GlrReuseClause* node) override
{
clause = node;
node->syntax->Accept(this);
}
};
/***********************************************************************
ResolveName
***********************************************************************/
void ResolveName(VisitorContext& context, List<Ptr<GlrSyntaxFile>>& files)
{
for (auto file : files)
{
for (auto rule : file->rules)
{
auto ruleSymbol = context.syntaxManager.Rules()[rule->name.value];
ResolveNameVisitor visitor(context, ruleSymbol);
for (auto clause : rule->clauses)
{
visitor.ResolveClause(clause);
}
}
}
}
}
}
}
/***********************************************************************
.\PARSERGEN\COMPILESYNTAX_VALIDATESTRUCTURE.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace compile_syntax;
/***********************************************************************
ValidateStructureCountingVisitor
***********************************************************************/
class ValidateStructureCountingVisitor
: public Object
, protected virtual GlrSyntax::IVisitor
, protected virtual GlrClause::IVisitor
{
protected:
VisitorContext& context;
RuleSymbol* ruleSymbol;
GlrClause* clause = nullptr;
vint optionalCounter = 0;
vint loopCounter = 0;
bool lastSyntaxPiece = true;
bool prioritySyntaxOccurred = false;
vint syntaxMinLength = 0;
vint syntaxMinUseRuleCount = 0;
vint syntaxMaxUseRuleCount = 0;
public:
ValidateStructureCountingVisitor(
VisitorContext& _context,
RuleSymbol* _ruleSymbol
)
: context(_context)
, ruleSymbol(_ruleSymbol)
{
}
void ValidateClause(Ptr<GlrClause> clause)
{
optionalCounter = 0;
loopCounter = 0;
lastSyntaxPiece = true;
prioritySyntaxOccurred = false;
clause->Accept(this);
}
protected:
void Visit(GlrRefSyntax* node) override
{
syntaxMinLength = 1;
syntaxMinUseRuleCount = 0;
syntaxMaxUseRuleCount = 0;
if (loopCounter > 0)
{
auto clauseType = context.clauseTypes[clause];
if (node->field)
{
auto prop = FindPropSymbol(clauseType, node->field.value);
if (prop->propType != AstPropType::Array)
{
context.syntaxManager.AddError(
ParserErrorType::NonArrayFieldAssignedInLoop,
node->codeRange,
ruleSymbol->Name(),
clauseType->Name(),
prop->Name()
);
}
}
vint ruleIndex = context.syntaxManager.Rules().Keys().IndexOf(node->name.value);
if (ruleIndex != -1)
{
auto fieldRule = context.syntaxManager.Rules().Values()[ruleIndex];
if (fieldRule->isPartial && fieldRule->assignedNonArrayField)
{
context.syntaxManager.AddError(
ParserErrorType::NonLoopablePartialRuleUsedInLoop,
node->codeRange,
ruleSymbol->Name(),
clauseType->Name(),
fieldRule->Name()
);
}
}
}
}
void Visit(GlrLiteralSyntax* node) override
{
syntaxMinLength = 1;
syntaxMinUseRuleCount = 0;
syntaxMaxUseRuleCount = 0;
}
void Visit(GlrUseSyntax* node) override
{
syntaxMinLength = 1;
syntaxMinUseRuleCount = 1;
syntaxMaxUseRuleCount = 1;
if (loopCounter > 0)
{
context.syntaxManager.AddError(
ParserErrorType::UseRuleUsedInLoopBody,
node->codeRange,
ruleSymbol->Name(),
node->name.value
);
}
if (optionalCounter > 0)
{
context.syntaxManager.AddError(
ParserErrorType::UseRuleUsedInOptionalBody,
node->codeRange,
ruleSymbol->Name(),
node->name.value
);
}
}
void Visit(GlrLoopSyntax* node) override
{
vint bodyMinLength = 0, bodyMaxUseRuleCount = 0;
vint delimiterMinLength = 0, delimiterMaxUseRuleCount = 0;
loopCounter++;
node->syntax->Accept(this);
bodyMinLength = syntaxMinLength;
bodyMaxUseRuleCount = syntaxMaxUseRuleCount;
if (node->delimiter)
{
node->delimiter->Accept(this);
delimiterMinLength = syntaxMinLength;
delimiterMaxUseRuleCount = syntaxMaxUseRuleCount;
}
if (delimiterMinLength + bodyMinLength == 0)
{
context.syntaxManager.AddError(
ParserErrorType::LoopBodyCouldExpandToEmptySequence,
node->codeRange,
ruleSymbol->Name()
);
}
syntaxMinLength = 0;
syntaxMinUseRuleCount = 0;
syntaxMaxUseRuleCount = bodyMaxUseRuleCount * 2 + delimiterMaxUseRuleCount * 2;
loopCounter--;
}
void Visit(GlrOptionalSyntax* node) override
{
if (node->priority != GlrOptionalPriority::Equal)
{
if (prioritySyntaxOccurred)
{
context.syntaxManager.AddError(
ParserErrorType::MultiplePrioritySyntaxInAClause,
node->codeRange,
ruleSymbol->Name()
);
}
else
{
prioritySyntaxOccurred = true;
}
}
optionalCounter++;
node->syntax->Accept(this);
if (syntaxMinLength == 0)
{
context.syntaxManager.AddError(
ParserErrorType::OptionalBodyCouldExpandToEmptySequence,
node->codeRange,
ruleSymbol->Name()
);
}
if (node->priority == GlrOptionalPriority::PreferSkip && lastSyntaxPiece)
{
context.syntaxManager.AddError(
ParserErrorType::NegativeOptionalEndsAClause,
node->codeRange,
ruleSymbol->Name()
);
}
syntaxMinLength = 0;
syntaxMinUseRuleCount = 0;
optionalCounter--;
}
void Visit(GlrSequenceSyntax* node) override
{
node->second->Accept(this);
vint secondMinLength = syntaxMinLength;
vint secondMinUseRuleCount = syntaxMinUseRuleCount;
vint secondMaxUseRuleCount = syntaxMaxUseRuleCount;
bool last = lastSyntaxPiece;
lastSyntaxPiece = last && secondMinLength == 0;
node->first->Accept(this);
vint firstMinLength = syntaxMinLength;
vint firstMinUseRuleCount = syntaxMinUseRuleCount;
vint firstMaxUseRuleCount = syntaxMaxUseRuleCount;
lastSyntaxPiece = last;
syntaxMinLength = firstMinLength + secondMinLength;
syntaxMinUseRuleCount = firstMinUseRuleCount + secondMinUseRuleCount;
syntaxMaxUseRuleCount = firstMaxUseRuleCount + secondMaxUseRuleCount;
}
void Visit(GlrAlternativeSyntax* node) override
{
node->first->Accept(this);
vint firstMinLength = syntaxMinLength;
vint firstMinUseRuleCount = syntaxMinUseRuleCount;
vint firstMaxUseRuleCount = syntaxMaxUseRuleCount;
node->second->Accept(this);
vint secondMinLength = syntaxMinLength;
vint secondMinUseRuleCount = syntaxMinUseRuleCount;
vint secondMaxUseRuleCount = syntaxMaxUseRuleCount;
syntaxMinLength = firstMinLength < secondMinLength ? firstMinLength : secondMinLength;
syntaxMinUseRuleCount = firstMinUseRuleCount < secondMinUseRuleCount ? firstMinUseRuleCount : secondMinUseRuleCount;
syntaxMaxUseRuleCount = firstMaxUseRuleCount > secondMaxUseRuleCount ? firstMaxUseRuleCount : secondMaxUseRuleCount;
}
void CheckAfterClause(GlrClause* node, bool reuseClause)
{
if (syntaxMinLength == 0)
{
context.syntaxManager.AddError(
ParserErrorType::ClauseCouldExpandToEmptySequence,
node->codeRange,
ruleSymbol->Name()
);
}
if (reuseClause)
{
if (syntaxMinUseRuleCount == 0)
{
context.syntaxManager.AddError(
ParserErrorType::ClauseNotCreateObject,
node->codeRange,
ruleSymbol->Name()
);
}
if (syntaxMaxUseRuleCount > 1)
{
context.syntaxManager.AddError(
ParserErrorType::ClauseTooManyUseRule,
node->codeRange,
ruleSymbol->Name()
);
}
}
}
void Visit(GlrCreateClause* node) override
{
clause = node;
node->syntax->Accept(this);
CheckAfterClause(node, false);
}
void Visit(GlrPartialClause* node) override
{
clause = node;
node->syntax->Accept(this);
CheckAfterClause(node, false);
}
void Visit(GlrReuseClause* node) override
{
clause = node;
node->syntax->Accept(this);
CheckAfterClause(node, true);
}
};
/***********************************************************************
ValidateStructureRelationshipVisitor
***********************************************************************/
class ValidateStructureRelationshipVisitor
: public Object
, protected virtual GlrSyntax::IVisitor
, protected virtual GlrClause::IVisitor
{
struct Link
{
GlrRefSyntax* ref = nullptr;
Link* prev = nullptr;
Link* next = nullptr;
Link(GlrRefSyntax* _ref) : ref(_ref) {}
};
struct LinkPair
{
Link* first = nullptr;
Link* last = nullptr;
void EnsureComplete()
{
CHECK_ERROR(!first || !first->prev, L"Illegal Operation!");
CHECK_ERROR(!last || !last->next, L"Illegal Operation!");
}
LinkPair Append(Link* link)
{
EnsureComplete();
if (first)
{
link->prev = last;
last->next = link;
return { first,link };
}
else
{
return { link,link };
}
}
LinkPair Connect(LinkPair pair)
{
EnsureComplete();
pair.EnsureComplete();
if (!first && !pair.first)
{
return {};
}
else if (!first)
{
return pair;
}
else if (!pair.first)
{
return *this;
}
else
{
last->next = pair.first;
pair.first->prev = last;
return { first,pair.last };
}
}
void CutAfter(Link* link, LinkPair& l1, LinkPair& l2)
{
EnsureComplete();
if (!first)
{
CHECK_ERROR(!link, L"Illegal Operation!");
l1 = {};
l2 = {};
}
else if (!link)
{
l2 = *this;
l1 = {};
}
else if (link == last)
{
l1 = *this;
l2 = {};
}
else
{
auto a = first;
auto b = last;
l1 = { a,link };
l2 = { link->next,b };
l1.last->next = nullptr;
l2.first->prev = nullptr;
}
}
operator bool() const
{
return last;
}
};
protected:
VisitorContext& context;
RuleSymbol* ruleSymbol;
GlrClause* clause = nullptr;
LinkPair existingFields;
LinkPair existingPartials;
public:
ValidateStructureRelationshipVisitor(
VisitorContext& _context,
RuleSymbol* _ruleSymbol
)
: context(_context)
, ruleSymbol(_ruleSymbol)
{
}
~ValidateStructureRelationshipVisitor()
{
{
auto c = existingFields.first;
while (c)
{
auto n = c->next;
delete c;
c = n;
}
}
{
auto c = existingPartials.first;
while (c)
{
auto n = c->next;
delete c;
c = n;
}
}
}
void ValidateClause(Ptr<GlrClause> clause)
{
clause->Accept(this);
}
protected:
void Visit(GlrRefSyntax* node) override
{
if (node->field)
{
existingFields = existingFields.Append(new Link(node));
}
vint ruleIndex = context.syntaxManager.Rules().Keys().IndexOf(node->name.value);
if (ruleIndex != -1)
{
auto fieldRule = context.syntaxManager.Rules().Values()[ruleIndex];
if (fieldRule->isPartial)
{
existingPartials= existingPartials.Append(new Link(node));
}
}
}
void Visit(GlrLiteralSyntax* node) override
{
}
void Visit(GlrUseSyntax* node) override
{
}
void Visit(GlrLoopSyntax* node) override
{
node->syntax->Accept(this);
if (node->delimiter)
{
node->delimiter->Accept(this);
}
}
void Visit(GlrOptionalSyntax* node) override
{
node->syntax->Accept(this);
}
void Visit(GlrSequenceSyntax* node) override
{
node->first->Accept(this);
node->second->Accept(this);
}
void Visit(GlrAlternativeSyntax* node) override
{
auto currentFields = existingFields;
auto currentPartials = existingPartials;
node->first->Accept(this);
LinkPair firstFields, firstPartials;
existingFields.CutAfter(currentFields.last, existingFields, firstFields);
existingPartials.CutAfter(currentPartials.last, existingPartials, firstPartials);
node->second->Accept(this);
existingFields = existingFields.Connect(firstFields);
existingPartials = existingPartials.Connect(firstPartials);
}
void CheckAfterClause(GlrClause* node)
{
Dictionary<WString, vint> counters;
auto c = existingFields.first;
while (c)
{
auto fieldName = c->ref->field.value;
vint index = counters.Keys().IndexOf(fieldName);
if (index == -1)
{
counters.Add(fieldName, 1);
}
else
{
counters.Set(fieldName, counters.Values()[index] + 1);
}
c = c->next;
}
auto clauseType = context.clauseTypes[clause];
for (auto [key, value] : counters)
{
auto prop = FindPropSymbol(clauseType, key);
if (prop->propType != AstPropType::Array && value > 1)
{
context.syntaxManager.AddError(
ParserErrorType::FieldAssignedMoreThanOnce,
node->codeRange,
ruleSymbol->Name(),
clauseType->Name(),
prop->Name()
);
}
}
}
void Visit(GlrCreateClause* node) override
{
clause = node;
node->syntax->Accept(this);
CheckAfterClause(node);
}
void Visit(GlrPartialClause* node) override
{
clause = node;
node->syntax->Accept(this);
CheckAfterClause(node);
}
void Visit(GlrReuseClause* node) override
{
clause = node;
node->syntax->Accept(this);
CheckAfterClause(node);
}
};
/***********************************************************************
ValidateStructure
***********************************************************************/
void ValidateStructure(VisitorContext& context, List<Ptr<GlrSyntaxFile>>& files)
{
for (auto file : files)
{
for (auto rule : file->rules)
{
auto ruleSymbol = context.syntaxManager.Rules()[rule->name.value];
ValidateStructureCountingVisitor visitor1(context, ruleSymbol);
for (auto clause : rule->clauses)
{
ValidateStructureRelationshipVisitor visitor2(context, ruleSymbol);
visitor1.ValidateClause(clause);
visitor2.ValidateClause(clause);
}
}
}
}
}
}
}
/***********************************************************************
.\PARSERGEN\COMPILESYNTAX_VALIDATETYPES.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace compile_syntax;
/***********************************************************************
ValidateTypesVisitor
***********************************************************************/
class ValidateTypesVisitor
: public Object
, protected virtual GlrSyntax::IVisitor
, protected virtual GlrClause::IVisitor
{
protected:
VisitorContext& context;
RuleSymbol* ruleSymbol;
GlrClause* clause = nullptr;
AstClassPropSymbol* FindField(AstClassSymbol*& clauseType, ParsingToken& name)
{
clauseType = context.clauseTypes[clause];
if (auto prop = FindPropSymbol(clauseType, name.value))
{
if (prop->propType != AstPropType::Array)
{
ruleSymbol->assignedNonArrayField = true;
}
return prop;
}
else
{
context.syntaxManager.AddError(
ParserErrorType::FieldNotExistsInClause,
name.codeRange,
ruleSymbol->Name(),
clauseType->Name(),
name.value
);
return nullptr;
}
}
bool ConvertibleTo(AstClassSymbol* from, AstClassSymbol* to)
{
while (from)
{
if (from == to) return true;
from = from->baseClass;
}
return false;
}
public:
ValidateTypesVisitor(
VisitorContext& _context,
RuleSymbol* _ruleSymbol
)
: context(_context)
, ruleSymbol(_ruleSymbol)
{
}
void ValidateClause(Ptr<GlrClause> clause)
{
clause->Accept(this);
}
protected:
void Visit(GlrRefSyntax* node) override
{
vint ruleIndex = context.syntaxManager.Rules().Keys().IndexOf(node->name.value);
auto clauseType = context.clauseTypes[clause];
auto fieldRule = ruleIndex == -1 ? nullptr : context.syntaxManager.Rules().Values()[ruleIndex];
if (fieldRule && fieldRule->isPartial)
{
if (!ConvertibleTo(clauseType, fieldRule->ruleType))
{
context.syntaxManager.AddError(
ParserErrorType::ClauseTypeMismatchedToPartialRule,
node->codeRange,
ruleSymbol->Name(),
clauseType->Name(),
fieldRule->Name(),
fieldRule->ruleType->Name()
);
}
}
if (node->field)
{
AstClassSymbol* clauseType = nullptr;
if (auto prop = FindField(clauseType, node->field))
{
if (fieldRule)
{
if (fieldRule->isPartial)
{
context.syntaxManager.AddError(
ParserErrorType::PartialRuleUsedOnField,
node->codeRange,
ruleSymbol->Name(),
clauseType->Name(),
fieldRule->Name(),
node->field.value
);
}
if (auto propClassSymbol = dynamic_cast<AstClassSymbol*>(prop->propSymbol))
{
if (ConvertibleTo(fieldRule->ruleType, propClassSymbol))
{
goto PASS_FIELD_TYPE;
}
}
context.syntaxManager.AddError(
ParserErrorType::RuleTypeMismatchedToField,
node->codeRange,
ruleSymbol->Name(),
clauseType->Name(),
node->field.value,
fieldRule->ruleType->Name()
);
PASS_FIELD_TYPE:;
}
else
{
if (prop->propType != AstPropType::Token)
{
context.syntaxManager.AddError(
ParserErrorType::RuleTypeMismatchedToField,
node->codeRange,
ruleSymbol->Name(),
clauseType->Name(),
node->field.value,
L"token"
);
}
}
}
}
}
void Visit(GlrLiteralSyntax* node) override
{
}
void Visit(GlrUseSyntax* node) override
{
auto fieldRule = context.syntaxManager.Rules()[node->name.value];
if (fieldRule->isPartial)
{
context.syntaxManager.AddError(
ParserErrorType::UseRuleWithPartialRule,
node->codeRange,
ruleSymbol->Name(),
node->name.value
);
}
if (!dynamic_cast<GlrReuseClause*>(clause))
{
context.syntaxManager.AddError(
ParserErrorType::UseRuleInNonReuseClause,
node->codeRange,
ruleSymbol->Name(),
node->name.value
);
}
}
void Visit(GlrLoopSyntax* node) override
{
node->syntax->Accept(this);
if (node->delimiter)
{
node->delimiter->Accept(this);
}
}
void Visit(GlrOptionalSyntax* node) override
{
node->syntax->Accept(this);
}
void Visit(GlrSequenceSyntax* node) override
{
node->first->Accept(this);
node->second->Accept(this);
}
void Visit(GlrAlternativeSyntax* node) override
{
node->first->Accept(this);
node->second->Accept(this);
}
void Visit(GlrAssignment* node)
{
AstClassSymbol* clauseType = nullptr;
if (auto prop = FindField(clauseType, node->field))
{
if (auto enumPropSymbol = dynamic_cast<AstEnumSymbol*>(prop->propSymbol))
{
if (!enumPropSymbol->Items().Keys().Contains(node->value.value))
{
context.syntaxManager.AddError(
ParserErrorType::EnumItemMismatchedToField,
node->codeRange,
ruleSymbol->Name(),
clauseType->Name(),
node->field.value,
node->value.value
);
}
}
else
{
context.syntaxManager.AddError(
ParserErrorType::AssignmentToNonEnumField,
node->codeRange,
ruleSymbol->Name(),
clauseType->Name(),
node->field.value
);
}
}
}
void Visit(GlrCreateClause* node) override
{
clause = node;
node->syntax->Accept(this);
for (auto assignment : node->assignments)
{
Visit(assignment.Obj());
}
}
void Visit(GlrPartialClause* node) override
{
clause = node;
node->syntax->Accept(this);
for (auto assignment : node->assignments)
{
Visit(assignment.Obj());
}
}
void Visit(GlrReuseClause* node) override
{
clause = node;
node->syntax->Accept(this);
for (auto assignment : node->assignments)
{
Visit(assignment.Obj());
}
}
};
/***********************************************************************
ValidateTypes
***********************************************************************/
void ValidateTypes(VisitorContext& context, List<Ptr<GlrSyntaxFile>>& files)
{
for (auto file : files)
{
for (auto rule : file->rules)
{
auto ruleSymbol = context.syntaxManager.Rules()[rule->name.value];
ValidateTypesVisitor visitor(context, ruleSymbol);
for (auto clause : rule->clauses)
{
visitor.ValidateClause(clause);
}
}
}
}
}
}
}
/***********************************************************************
.\PARSERGEN\PARSERCPPGEN.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace stream;
/***********************************************************************
GenerateParserFileNames
***********************************************************************/
Ptr<CppParserGenOutput> GenerateParserFileNames(ParserSymbolManager& manager)
{
auto parserOutput = MakePtr<CppParserGenOutput>();
parserOutput->assemblyH = manager.name + L"_Assembler.h";
parserOutput->assemblyCpp = manager.name + L"_Assembler.cpp";
parserOutput->lexerH = manager.name + L"_Lexer.h";
parserOutput->lexerCpp = manager.name + L"_Lexer.cpp";
return parserOutput;
}
/***********************************************************************
WriteCppStringBody
***********************************************************************/
void WriteCppStringBody(const WString& body, stream::StreamWriter& writer)
{
for (vint i = 0; i < body.Length(); i++)
{
auto c = body[i];
switch (c)
{
case L'\t':
writer.WriteString(L"\\t");
break;
case L'\r':
writer.WriteString(L"\\r");
break;
case L'\n':
writer.WriteString(L"\\n");
break;
case L'\\':
writer.WriteString(L"\\\\");
break;
case L'\"':
writer.WriteString(L"\\\"");
break;
case L'\'':
writer.WriteString(L"\\\'");
break;
default:
writer.WriteChar(c);
}
}
}
/***********************************************************************
Utility
***********************************************************************/
void WriteFileComment(const WString& name, stream::StreamWriter& writer)
{
writer.WriteLine(L"/***********************************************************************");
writer.WriteLine(L"This file is generated by: Vczh Parser Generator");
writer.WriteLine(L"From parser definition:" + name);
writer.WriteLine(L"Licensed under https://github.com/vczh-libraries/License");
writer.WriteLine(L"***********************************************************************/");
writer.WriteLine(L"");
}
WString WriteNssBegin(collections::List<WString>& cppNss, stream::StreamWriter& writer)
{
WString prefix;
for (auto ns : cppNss)
{
writer.WriteLine(prefix + L"namespace " + ns);
writer.WriteLine(prefix + L"{");
prefix += L"\t";
}
return prefix;
}
void WriteNssEnd(collections::List<WString>& cppNss, stream::StreamWriter& writer)
{
vint counter = cppNss.Count();
for (auto ns : cppNss)
{
counter--;
for (vint i = 0; i < counter; i++) writer.WriteChar(L'\t');
writer.WriteLine(L"}");
}
}
extern void WriteLoadDataFunctionHeader(const WString& prefix, const WString& functionName, stream::StreamWriter& writer)
{
writer.WriteLine(prefix + L"extern void " + functionName + L"(vl::stream::IStream& outputStream);");
}
extern void WriteLoadDataFunctionCpp(const WString& prefix, const WString& functionName, stream::MemoryStream& rawData, bool compressData, stream::StreamWriter& writer)
{
MemoryStream compressedData;
if (compressData)
{
CompressStream(rawData, compressedData);
}
else
{
CopyStream(rawData, compressedData);
}
compressedData.SeekFromBegin(0);
vint lengthBeforeCompressing = (vint)rawData.Size();
vint length = (vint)compressedData.Size();
const vint block = 256;
vint remain = length % block;
vint solidRows = length / block;
vint rows = solidRows + (remain ? 1 : 0);
writer.WriteLine(prefix + L"void " + functionName + L"(vl::stream::IStream& outputStream)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tstatic const vl::vint dataLength = " + itow(length) + L"; // " + itow(lengthBeforeCompressing) + L" bytes before compressing");
writer.WriteLine(prefix + L"\tstatic const vl::vint dataBlock = " + itow(block) + L";");
writer.WriteLine(prefix + L"\tstatic const vl::vint dataRemain = " + itow(remain) + L";");
writer.WriteLine(prefix + L"\tstatic const vl::vint dataSolidRows = " + itow(solidRows) + L";");
writer.WriteLine(prefix + L"\tstatic const vl::vint dataRows = " + itow(rows) + L";");
writer.WriteLine(prefix + L"\tstatic const char* compressed[] = {");
{
char buffer[block];
const wchar_t* hex = L"0123456789ABCDEF";
for (vint i = 0; i < rows; i++)
{
vint size = i == solidRows ? remain : block;
vint read = compressedData.Read(buffer, size);
CHECK_ERROR(size == read, L"vl::glr::parsergen::WriteLexerCppFile()#Failed to read compressed data.");
writer.WriteString(prefix + L"\t\t\"");
for (vint j = 0; j < size; j++)
{
vuint8_t byte = buffer[j];
writer.WriteString(L"\\x");
writer.WriteChar(hex[byte / 16]);
writer.WriteChar(hex[byte % 16]);
}
writer.WriteLine(L"\",");
}
}
writer.WriteLine(prefix + L"\t};");
writer.WriteLine(prefix + L"\tvl::glr::DecompressSerializedData(compressed, " + WString(compressData ? L"true" : L"false") + L", dataSolidRows, dataRows, dataBlock, dataRemain, outputStream);");
writer.WriteLine(prefix + L"}");
}
}
}
}
/***********************************************************************
.\PARSERGEN\PARSERSYMBOL.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
/***********************************************************************
Utility
***********************************************************************/
void InitializeParserSymbolManager(ParserSymbolManager& manager)
{
manager.name = L"ParserGen";
Fill(manager.includes, L"../AstBase.h", L"../SyntaxBase.h");
Fill(manager.cppNss, L"vl", L"glr", L"parsergen");
manager.headerGuard = L"VCZH_PARSER2_PARSERGEN";
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEAST.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:RuleAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
/***********************************************************************
Visitor Pattern Implementation
***********************************************************************/
void GlrRefSyntax::Accept(GlrSyntax::IVisitor* visitor)
{
visitor->Visit(this);
}
void GlrLiteralSyntax::Accept(GlrSyntax::IVisitor* visitor)
{
visitor->Visit(this);
}
void GlrUseSyntax::Accept(GlrSyntax::IVisitor* visitor)
{
visitor->Visit(this);
}
void GlrLoopSyntax::Accept(GlrSyntax::IVisitor* visitor)
{
visitor->Visit(this);
}
void GlrOptionalSyntax::Accept(GlrSyntax::IVisitor* visitor)
{
visitor->Visit(this);
}
void GlrSequenceSyntax::Accept(GlrSyntax::IVisitor* visitor)
{
visitor->Visit(this);
}
void GlrAlternativeSyntax::Accept(GlrSyntax::IVisitor* visitor)
{
visitor->Visit(this);
}
void GlrCreateClause::Accept(GlrClause::IVisitor* visitor)
{
visitor->Visit(this);
}
void GlrPartialClause::Accept(GlrClause::IVisitor* visitor)
{
visitor->Visit(this);
}
void GlrReuseClause::Accept(GlrClause::IVisitor* visitor)
{
visitor->Visit(this);
}
}
}
}
namespace vl
{
namespace reflection
{
namespace description
{
#ifndef VCZH_DEBUG_NO_REFLECTION
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrSyntax, glr::parsergen::GlrSyntax)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrSyntax::IVisitor, glr::parsergen::GlrSyntax::IVisitor)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrRefSyntax, glr::parsergen::GlrRefSyntax)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrLiteralSyntax, glr::parsergen::GlrLiteralSyntax)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrUseSyntax, glr::parsergen::GlrUseSyntax)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrLoopSyntax, glr::parsergen::GlrLoopSyntax)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrOptionalPriority, glr::parsergen::GlrOptionalPriority)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrOptionalSyntax, glr::parsergen::GlrOptionalSyntax)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrSequenceSyntax, glr::parsergen::GlrSequenceSyntax)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrAlternativeSyntax, glr::parsergen::GlrAlternativeSyntax)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrClause, glr::parsergen::GlrClause)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrClause::IVisitor, glr::parsergen::GlrClause::IVisitor)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrAssignment, glr::parsergen::GlrAssignment)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrCreateClause, glr::parsergen::GlrCreateClause)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrPartialClause, glr::parsergen::GlrPartialClause)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrReuseClause, glr::parsergen::GlrReuseClause)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrRule, glr::parsergen::GlrRule)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrSyntaxFile, glr::parsergen::GlrSyntaxFile)
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrSyntax)
CLASS_MEMBER_BASE(vl::glr::ParsingAstBase)
END_CLASS_MEMBER(vl::glr::parsergen::GlrSyntax)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrRefSyntax)
CLASS_MEMBER_BASE(vl::glr::parsergen::GlrSyntax)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrRefSyntax>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(name)
CLASS_MEMBER_FIELD(field)
END_CLASS_MEMBER(vl::glr::parsergen::GlrRefSyntax)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrLiteralSyntax)
CLASS_MEMBER_BASE(vl::glr::parsergen::GlrSyntax)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrLiteralSyntax>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(value)
END_CLASS_MEMBER(vl::glr::parsergen::GlrLiteralSyntax)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrUseSyntax)
CLASS_MEMBER_BASE(vl::glr::parsergen::GlrSyntax)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrUseSyntax>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(name)
END_CLASS_MEMBER(vl::glr::parsergen::GlrUseSyntax)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrLoopSyntax)
CLASS_MEMBER_BASE(vl::glr::parsergen::GlrSyntax)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrLoopSyntax>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(syntax)
CLASS_MEMBER_FIELD(delimiter)
END_CLASS_MEMBER(vl::glr::parsergen::GlrLoopSyntax)
BEGIN_ENUM_ITEM(vl::glr::parsergen::GlrOptionalPriority)
ENUM_ITEM_NAMESPACE(vl::glr::parsergen::GlrOptionalPriority)
ENUM_NAMESPACE_ITEM(Equal)
ENUM_NAMESPACE_ITEM(PreferTake)
ENUM_NAMESPACE_ITEM(PreferSkip)
END_ENUM_ITEM(vl::glr::parsergen::GlrOptionalPriority)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrOptionalSyntax)
CLASS_MEMBER_BASE(vl::glr::parsergen::GlrSyntax)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrOptionalSyntax>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(priority)
CLASS_MEMBER_FIELD(syntax)
END_CLASS_MEMBER(vl::glr::parsergen::GlrOptionalSyntax)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrSequenceSyntax)
CLASS_MEMBER_BASE(vl::glr::parsergen::GlrSyntax)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrSequenceSyntax>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(first)
CLASS_MEMBER_FIELD(second)
END_CLASS_MEMBER(vl::glr::parsergen::GlrSequenceSyntax)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrAlternativeSyntax)
CLASS_MEMBER_BASE(vl::glr::parsergen::GlrSyntax)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrAlternativeSyntax>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(first)
CLASS_MEMBER_FIELD(second)
END_CLASS_MEMBER(vl::glr::parsergen::GlrAlternativeSyntax)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrClause)
CLASS_MEMBER_BASE(vl::glr::ParsingAstBase)
END_CLASS_MEMBER(vl::glr::parsergen::GlrClause)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrAssignment)
CLASS_MEMBER_BASE(vl::glr::ParsingAstBase)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrAssignment>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(field)
CLASS_MEMBER_FIELD(value)
END_CLASS_MEMBER(vl::glr::parsergen::GlrAssignment)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrCreateClause)
CLASS_MEMBER_BASE(vl::glr::parsergen::GlrClause)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrCreateClause>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(type)
CLASS_MEMBER_FIELD(syntax)
CLASS_MEMBER_FIELD(assignments)
END_CLASS_MEMBER(vl::glr::parsergen::GlrCreateClause)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrPartialClause)
CLASS_MEMBER_BASE(vl::glr::parsergen::GlrClause)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrPartialClause>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(type)
CLASS_MEMBER_FIELD(syntax)
CLASS_MEMBER_FIELD(assignments)
END_CLASS_MEMBER(vl::glr::parsergen::GlrPartialClause)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrReuseClause)
CLASS_MEMBER_BASE(vl::glr::parsergen::GlrClause)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrReuseClause>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(syntax)
CLASS_MEMBER_FIELD(assignments)
END_CLASS_MEMBER(vl::glr::parsergen::GlrReuseClause)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrRule)
CLASS_MEMBER_BASE(vl::glr::ParsingAstBase)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrRule>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(name)
CLASS_MEMBER_FIELD(clauses)
END_CLASS_MEMBER(vl::glr::parsergen::GlrRule)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrSyntaxFile)
CLASS_MEMBER_BASE(vl::glr::ParsingAstBase)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrSyntaxFile>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(rules)
END_CLASS_MEMBER(vl::glr::parsergen::GlrSyntaxFile)
BEGIN_INTERFACE_MEMBER(vl::glr::parsergen::GlrSyntax::IVisitor)
CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::glr::parsergen::GlrSyntax::IVisitor::*)(vl::glr::parsergen::GlrRefSyntax* node))
CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::glr::parsergen::GlrSyntax::IVisitor::*)(vl::glr::parsergen::GlrLiteralSyntax* node))
CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::glr::parsergen::GlrSyntax::IVisitor::*)(vl::glr::parsergen::GlrUseSyntax* node))
CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::glr::parsergen::GlrSyntax::IVisitor::*)(vl::glr::parsergen::GlrLoopSyntax* node))
CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::glr::parsergen::GlrSyntax::IVisitor::*)(vl::glr::parsergen::GlrOptionalSyntax* node))
CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::glr::parsergen::GlrSyntax::IVisitor::*)(vl::glr::parsergen::GlrSequenceSyntax* node))
CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::glr::parsergen::GlrSyntax::IVisitor::*)(vl::glr::parsergen::GlrAlternativeSyntax* node))
END_INTERFACE_MEMBER(vl::glr::parsergen::GlrSyntax)
BEGIN_INTERFACE_MEMBER(vl::glr::parsergen::GlrClause::IVisitor)
CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::glr::parsergen::GlrClause::IVisitor::*)(vl::glr::parsergen::GlrCreateClause* node))
CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::glr::parsergen::GlrClause::IVisitor::*)(vl::glr::parsergen::GlrPartialClause* node))
CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::glr::parsergen::GlrClause::IVisitor::*)(vl::glr::parsergen::GlrReuseClause* node))
END_INTERFACE_MEMBER(vl::glr::parsergen::GlrClause)
#endif
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
class ParserGenRuleAstTypeLoader : public vl::Object, public ITypeLoader
{
public:
void Load(ITypeManager* manager)
{
ADD_TYPE_INFO(vl::glr::parsergen::GlrSyntax)
ADD_TYPE_INFO(vl::glr::parsergen::GlrSyntax::IVisitor)
ADD_TYPE_INFO(vl::glr::parsergen::GlrRefSyntax)
ADD_TYPE_INFO(vl::glr::parsergen::GlrLiteralSyntax)
ADD_TYPE_INFO(vl::glr::parsergen::GlrUseSyntax)
ADD_TYPE_INFO(vl::glr::parsergen::GlrLoopSyntax)
ADD_TYPE_INFO(vl::glr::parsergen::GlrOptionalPriority)
ADD_TYPE_INFO(vl::glr::parsergen::GlrOptionalSyntax)
ADD_TYPE_INFO(vl::glr::parsergen::GlrSequenceSyntax)
ADD_TYPE_INFO(vl::glr::parsergen::GlrAlternativeSyntax)
ADD_TYPE_INFO(vl::glr::parsergen::GlrClause)
ADD_TYPE_INFO(vl::glr::parsergen::GlrClause::IVisitor)
ADD_TYPE_INFO(vl::glr::parsergen::GlrAssignment)
ADD_TYPE_INFO(vl::glr::parsergen::GlrCreateClause)
ADD_TYPE_INFO(vl::glr::parsergen::GlrPartialClause)
ADD_TYPE_INFO(vl::glr::parsergen::GlrReuseClause)
ADD_TYPE_INFO(vl::glr::parsergen::GlrRule)
ADD_TYPE_INFO(vl::glr::parsergen::GlrSyntaxFile)
}
void Unload(ITypeManager* manager)
{
}
};
#endif
#endif
bool ParserGenRuleAstLoadTypes()
{
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
if (auto manager = GetGlobalTypeManager())
{
Ptr<ITypeLoader> loader = new ParserGenRuleAstTypeLoader;
return manager->AddTypeLoader(loader);
}
#endif
return false;
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEAST_BUILDER.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:RuleAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
namespace builder
{
/***********************************************************************
MakeAlternativeSyntax
***********************************************************************/
MakeAlternativeSyntax& MakeAlternativeSyntax::first(const vl::Ptr<GlrSyntax>& value)
{
node->first = value;
return *this;
}
MakeAlternativeSyntax& MakeAlternativeSyntax::second(const vl::Ptr<GlrSyntax>& value)
{
node->second = value;
return *this;
}
/***********************************************************************
MakeAssignment
***********************************************************************/
MakeAssignment& MakeAssignment::field(const vl::WString& value)
{
node->field.value = value;
return *this;
}
MakeAssignment& MakeAssignment::value(const vl::WString& value)
{
node->value.value = value;
return *this;
}
/***********************************************************************
MakeCreateClause
***********************************************************************/
MakeCreateClause& MakeCreateClause::assignments(const vl::Ptr<GlrAssignment>& value)
{
node->assignments.Add(value);
return *this;
}
MakeCreateClause& MakeCreateClause::syntax(const vl::Ptr<GlrSyntax>& value)
{
node->syntax = value;
return *this;
}
MakeCreateClause& MakeCreateClause::type(const vl::WString& value)
{
node->type.value = value;
return *this;
}
/***********************************************************************
MakeLiteralSyntax
***********************************************************************/
MakeLiteralSyntax& MakeLiteralSyntax::value(const vl::WString& value)
{
node->value.value = value;
return *this;
}
/***********************************************************************
MakeLoopSyntax
***********************************************************************/
MakeLoopSyntax& MakeLoopSyntax::delimiter(const vl::Ptr<GlrSyntax>& value)
{
node->delimiter = value;
return *this;
}
MakeLoopSyntax& MakeLoopSyntax::syntax(const vl::Ptr<GlrSyntax>& value)
{
node->syntax = value;
return *this;
}
/***********************************************************************
MakeOptionalSyntax
***********************************************************************/
MakeOptionalSyntax& MakeOptionalSyntax::priority(GlrOptionalPriority value)
{
node->priority = value;
return *this;
}
MakeOptionalSyntax& MakeOptionalSyntax::syntax(const vl::Ptr<GlrSyntax>& value)
{
node->syntax = value;
return *this;
}
/***********************************************************************
MakePartialClause
***********************************************************************/
MakePartialClause& MakePartialClause::assignments(const vl::Ptr<GlrAssignment>& value)
{
node->assignments.Add(value);
return *this;
}
MakePartialClause& MakePartialClause::syntax(const vl::Ptr<GlrSyntax>& value)
{
node->syntax = value;
return *this;
}
MakePartialClause& MakePartialClause::type(const vl::WString& value)
{
node->type.value = value;
return *this;
}
/***********************************************************************
MakeRefSyntax
***********************************************************************/
MakeRefSyntax& MakeRefSyntax::field(const vl::WString& value)
{
node->field.value = value;
return *this;
}
MakeRefSyntax& MakeRefSyntax::name(const vl::WString& value)
{
node->name.value = value;
return *this;
}
/***********************************************************************
MakeReuseClause
***********************************************************************/
MakeReuseClause& MakeReuseClause::assignments(const vl::Ptr<GlrAssignment>& value)
{
node->assignments.Add(value);
return *this;
}
MakeReuseClause& MakeReuseClause::syntax(const vl::Ptr<GlrSyntax>& value)
{
node->syntax = value;
return *this;
}
/***********************************************************************
MakeRule
***********************************************************************/
MakeRule& MakeRule::clauses(const vl::Ptr<GlrClause>& value)
{
node->clauses.Add(value);
return *this;
}
MakeRule& MakeRule::name(const vl::WString& value)
{
node->name.value = value;
return *this;
}
/***********************************************************************
MakeSequenceSyntax
***********************************************************************/
MakeSequenceSyntax& MakeSequenceSyntax::first(const vl::Ptr<GlrSyntax>& value)
{
node->first = value;
return *this;
}
MakeSequenceSyntax& MakeSequenceSyntax::second(const vl::Ptr<GlrSyntax>& value)
{
node->second = value;
return *this;
}
/***********************************************************************
MakeSyntaxFile
***********************************************************************/
MakeSyntaxFile& MakeSyntaxFile::rules(const vl::Ptr<GlrRule>& value)
{
node->rules.Add(value);
return *this;
}
/***********************************************************************
MakeUseSyntax
***********************************************************************/
MakeUseSyntax& MakeUseSyntax::name(const vl::WString& value)
{
node->name.value = value;
return *this;
}
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEAST_COPY.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:RuleAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
namespace copy_visitor
{
void RuleAstVisitor::CopyFields(GlrAlternativeSyntax* from, GlrAlternativeSyntax* to)
{
CopyFields(static_cast<GlrSyntax*>(from), static_cast<GlrSyntax*>(to));
to->first = CopyNode(from->first.Obj());
to->second = CopyNode(from->second.Obj());
}
void RuleAstVisitor::CopyFields(GlrAssignment* from, GlrAssignment* to)
{
to->field = from->field;
to->value = from->value;
}
void RuleAstVisitor::CopyFields(GlrClause* from, GlrClause* to)
{
}
void RuleAstVisitor::CopyFields(GlrCreateClause* from, GlrCreateClause* to)
{
CopyFields(static_cast<GlrClause*>(from), static_cast<GlrClause*>(to));
for (auto&& listItem : from->assignments)
{
to->assignments.Add(CopyNode(listItem.Obj()));
}
to->syntax = CopyNode(from->syntax.Obj());
to->type = from->type;
}
void RuleAstVisitor::CopyFields(GlrLiteralSyntax* from, GlrLiteralSyntax* to)
{
CopyFields(static_cast<GlrSyntax*>(from), static_cast<GlrSyntax*>(to));
to->value = from->value;
}
void RuleAstVisitor::CopyFields(GlrLoopSyntax* from, GlrLoopSyntax* to)
{
CopyFields(static_cast<GlrSyntax*>(from), static_cast<GlrSyntax*>(to));
to->delimiter = CopyNode(from->delimiter.Obj());
to->syntax = CopyNode(from->syntax.Obj());
}
void RuleAstVisitor::CopyFields(GlrOptionalSyntax* from, GlrOptionalSyntax* to)
{
CopyFields(static_cast<GlrSyntax*>(from), static_cast<GlrSyntax*>(to));
to->priority = from->priority;
to->syntax = CopyNode(from->syntax.Obj());
}
void RuleAstVisitor::CopyFields(GlrPartialClause* from, GlrPartialClause* to)
{
CopyFields(static_cast<GlrClause*>(from), static_cast<GlrClause*>(to));
for (auto&& listItem : from->assignments)
{
to->assignments.Add(CopyNode(listItem.Obj()));
}
to->syntax = CopyNode(from->syntax.Obj());
to->type = from->type;
}
void RuleAstVisitor::CopyFields(GlrRefSyntax* from, GlrRefSyntax* to)
{
CopyFields(static_cast<GlrSyntax*>(from), static_cast<GlrSyntax*>(to));
to->field = from->field;
to->name = from->name;
}
void RuleAstVisitor::CopyFields(GlrReuseClause* from, GlrReuseClause* to)
{
CopyFields(static_cast<GlrClause*>(from), static_cast<GlrClause*>(to));
for (auto&& listItem : from->assignments)
{
to->assignments.Add(CopyNode(listItem.Obj()));
}
to->syntax = CopyNode(from->syntax.Obj());
}
void RuleAstVisitor::CopyFields(GlrRule* from, GlrRule* to)
{
for (auto&& listItem : from->clauses)
{
to->clauses.Add(CopyNode(listItem.Obj()));
}
to->name = from->name;
}
void RuleAstVisitor::CopyFields(GlrSequenceSyntax* from, GlrSequenceSyntax* to)
{
CopyFields(static_cast<GlrSyntax*>(from), static_cast<GlrSyntax*>(to));
to->first = CopyNode(from->first.Obj());
to->second = CopyNode(from->second.Obj());
}
void RuleAstVisitor::CopyFields(GlrSyntax* from, GlrSyntax* to)
{
}
void RuleAstVisitor::CopyFields(GlrSyntaxFile* from, GlrSyntaxFile* to)
{
for (auto&& listItem : from->rules)
{
to->rules.Add(CopyNode(listItem.Obj()));
}
}
void RuleAstVisitor::CopyFields(GlrUseSyntax* from, GlrUseSyntax* to)
{
CopyFields(static_cast<GlrSyntax*>(from), static_cast<GlrSyntax*>(to));
to->name = from->name;
}
void RuleAstVisitor::Visit(GlrAssignment* node)
{
auto newNode = vl::MakePtr<GlrAssignment>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void RuleAstVisitor::Visit(GlrRule* node)
{
auto newNode = vl::MakePtr<GlrRule>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void RuleAstVisitor::Visit(GlrSyntaxFile* node)
{
auto newNode = vl::MakePtr<GlrSyntaxFile>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void RuleAstVisitor::Visit(GlrRefSyntax* node)
{
auto newNode = vl::MakePtr<GlrRefSyntax>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void RuleAstVisitor::Visit(GlrLiteralSyntax* node)
{
auto newNode = vl::MakePtr<GlrLiteralSyntax>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void RuleAstVisitor::Visit(GlrUseSyntax* node)
{
auto newNode = vl::MakePtr<GlrUseSyntax>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void RuleAstVisitor::Visit(GlrLoopSyntax* node)
{
auto newNode = vl::MakePtr<GlrLoopSyntax>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void RuleAstVisitor::Visit(GlrOptionalSyntax* node)
{
auto newNode = vl::MakePtr<GlrOptionalSyntax>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void RuleAstVisitor::Visit(GlrSequenceSyntax* node)
{
auto newNode = vl::MakePtr<GlrSequenceSyntax>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void RuleAstVisitor::Visit(GlrAlternativeSyntax* node)
{
auto newNode = vl::MakePtr<GlrAlternativeSyntax>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void RuleAstVisitor::Visit(GlrCreateClause* node)
{
auto newNode = vl::MakePtr<GlrCreateClause>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void RuleAstVisitor::Visit(GlrPartialClause* node)
{
auto newNode = vl::MakePtr<GlrPartialClause>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void RuleAstVisitor::Visit(GlrReuseClause* node)
{
auto newNode = vl::MakePtr<GlrReuseClause>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
vl::Ptr<GlrSyntax> RuleAstVisitor::CopyNode(GlrSyntax* node)
{
if (!node) return nullptr;
node->Accept(static_cast<GlrSyntax::IVisitor*>(this));
return this->result.Cast<GlrSyntax>();
}
vl::Ptr<GlrClause> RuleAstVisitor::CopyNode(GlrClause* node)
{
if (!node) return nullptr;
node->Accept(static_cast<GlrClause::IVisitor*>(this));
return this->result.Cast<GlrClause>();
}
vl::Ptr<GlrAssignment> RuleAstVisitor::CopyNode(GlrAssignment* node)
{
if (!node) return nullptr;
Visit(node);
return this->result.Cast<GlrAssignment>();
}
vl::Ptr<GlrRule> RuleAstVisitor::CopyNode(GlrRule* node)
{
if (!node) return nullptr;
Visit(node);
return this->result.Cast<GlrRule>();
}
vl::Ptr<GlrSyntaxFile> RuleAstVisitor::CopyNode(GlrSyntaxFile* node)
{
if (!node) return nullptr;
Visit(node);
return this->result.Cast<GlrSyntaxFile>();
}
vl::Ptr<GlrAlternativeSyntax> RuleAstVisitor::CopyNode(GlrAlternativeSyntax* node)
{
if (!node) return nullptr;
return CopyNode(static_cast<GlrSyntax*>(node)).Cast<GlrAlternativeSyntax>();
}
vl::Ptr<GlrCreateClause> RuleAstVisitor::CopyNode(GlrCreateClause* node)
{
if (!node) return nullptr;
return CopyNode(static_cast<GlrClause*>(node)).Cast<GlrCreateClause>();
}
vl::Ptr<GlrLiteralSyntax> RuleAstVisitor::CopyNode(GlrLiteralSyntax* node)
{
if (!node) return nullptr;
return CopyNode(static_cast<GlrSyntax*>(node)).Cast<GlrLiteralSyntax>();
}
vl::Ptr<GlrLoopSyntax> RuleAstVisitor::CopyNode(GlrLoopSyntax* node)
{
if (!node) return nullptr;
return CopyNode(static_cast<GlrSyntax*>(node)).Cast<GlrLoopSyntax>();
}
vl::Ptr<GlrOptionalSyntax> RuleAstVisitor::CopyNode(GlrOptionalSyntax* node)
{
if (!node) return nullptr;
return CopyNode(static_cast<GlrSyntax*>(node)).Cast<GlrOptionalSyntax>();
}
vl::Ptr<GlrPartialClause> RuleAstVisitor::CopyNode(GlrPartialClause* node)
{
if (!node) return nullptr;
return CopyNode(static_cast<GlrClause*>(node)).Cast<GlrPartialClause>();
}
vl::Ptr<GlrRefSyntax> RuleAstVisitor::CopyNode(GlrRefSyntax* node)
{
if (!node) return nullptr;
return CopyNode(static_cast<GlrSyntax*>(node)).Cast<GlrRefSyntax>();
}
vl::Ptr<GlrReuseClause> RuleAstVisitor::CopyNode(GlrReuseClause* node)
{
if (!node) return nullptr;
return CopyNode(static_cast<GlrClause*>(node)).Cast<GlrReuseClause>();
}
vl::Ptr<GlrSequenceSyntax> RuleAstVisitor::CopyNode(GlrSequenceSyntax* node)
{
if (!node) return nullptr;
return CopyNode(static_cast<GlrSyntax*>(node)).Cast<GlrSequenceSyntax>();
}
vl::Ptr<GlrUseSyntax> RuleAstVisitor::CopyNode(GlrUseSyntax* node)
{
if (!node) return nullptr;
return CopyNode(static_cast<GlrSyntax*>(node)).Cast<GlrUseSyntax>();
}
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEAST_EMPTY.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:RuleAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
namespace empty_visitor
{
/***********************************************************************
SyntaxVisitor
***********************************************************************/
// Visitor Members -----------------------------------
void SyntaxVisitor::Visit(GlrRefSyntax* node)
{
}
void SyntaxVisitor::Visit(GlrLiteralSyntax* node)
{
}
void SyntaxVisitor::Visit(GlrUseSyntax* node)
{
}
void SyntaxVisitor::Visit(GlrLoopSyntax* node)
{
}
void SyntaxVisitor::Visit(GlrOptionalSyntax* node)
{
}
void SyntaxVisitor::Visit(GlrSequenceSyntax* node)
{
}
void SyntaxVisitor::Visit(GlrAlternativeSyntax* node)
{
}
/***********************************************************************
ClauseVisitor
***********************************************************************/
// Visitor Members -----------------------------------
void ClauseVisitor::Visit(GlrCreateClause* node)
{
}
void ClauseVisitor::Visit(GlrPartialClause* node)
{
}
void ClauseVisitor::Visit(GlrReuseClause* node)
{
}
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEAST_JSON.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:RuleAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
namespace json_visitor
{
void RuleAstVisitor::PrintFields(GlrAlternativeSyntax* node)
{
BeginField(L"first");
Print(node->first.Obj());
EndField();
BeginField(L"second");
Print(node->second.Obj());
EndField();
}
void RuleAstVisitor::PrintFields(GlrAssignment* node)
{
BeginField(L"field");
WriteToken(node->field);
EndField();
BeginField(L"value");
WriteToken(node->value);
EndField();
}
void RuleAstVisitor::PrintFields(GlrClause* node)
{
}
void RuleAstVisitor::PrintFields(GlrCreateClause* node)
{
BeginField(L"assignments");
BeginArray();
for (auto&& listItem : node->assignments)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
BeginField(L"syntax");
Print(node->syntax.Obj());
EndField();
BeginField(L"type");
WriteToken(node->type);
EndField();
}
void RuleAstVisitor::PrintFields(GlrLiteralSyntax* node)
{
BeginField(L"value");
WriteToken(node->value);
EndField();
}
void RuleAstVisitor::PrintFields(GlrLoopSyntax* node)
{
BeginField(L"delimiter");
Print(node->delimiter.Obj());
EndField();
BeginField(L"syntax");
Print(node->syntax.Obj());
EndField();
}
void RuleAstVisitor::PrintFields(GlrOptionalSyntax* node)
{
BeginField(L"priority");
switch (node->priority)
{
case vl::glr::parsergen::GlrOptionalPriority::Equal:
WriteString(L"Equal");
break;
case vl::glr::parsergen::GlrOptionalPriority::PreferSkip:
WriteString(L"PreferSkip");
break;
case vl::glr::parsergen::GlrOptionalPriority::PreferTake:
WriteString(L"PreferTake");
break;
default:
WriteNull();
}
EndField();
BeginField(L"syntax");
Print(node->syntax.Obj());
EndField();
}
void RuleAstVisitor::PrintFields(GlrPartialClause* node)
{
BeginField(L"assignments");
BeginArray();
for (auto&& listItem : node->assignments)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
BeginField(L"syntax");
Print(node->syntax.Obj());
EndField();
BeginField(L"type");
WriteToken(node->type);
EndField();
}
void RuleAstVisitor::PrintFields(GlrRefSyntax* node)
{
BeginField(L"field");
WriteToken(node->field);
EndField();
BeginField(L"name");
WriteToken(node->name);
EndField();
}
void RuleAstVisitor::PrintFields(GlrReuseClause* node)
{
BeginField(L"assignments");
BeginArray();
for (auto&& listItem : node->assignments)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
BeginField(L"syntax");
Print(node->syntax.Obj());
EndField();
}
void RuleAstVisitor::PrintFields(GlrRule* node)
{
BeginField(L"clauses");
BeginArray();
for (auto&& listItem : node->clauses)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
BeginField(L"name");
WriteToken(node->name);
EndField();
}
void RuleAstVisitor::PrintFields(GlrSequenceSyntax* node)
{
BeginField(L"first");
Print(node->first.Obj());
EndField();
BeginField(L"second");
Print(node->second.Obj());
EndField();
}
void RuleAstVisitor::PrintFields(GlrSyntax* node)
{
}
void RuleAstVisitor::PrintFields(GlrSyntaxFile* node)
{
BeginField(L"rules");
BeginArray();
for (auto&& listItem : node->rules)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
}
void RuleAstVisitor::PrintFields(GlrUseSyntax* node)
{
BeginField(L"name");
WriteToken(node->name);
EndField();
}
void RuleAstVisitor::Visit(GlrRefSyntax* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"RefSyntax", node);
PrintFields(static_cast<GlrSyntax*>(node));
PrintFields(static_cast<GlrRefSyntax*>(node));
EndObject();
}
void RuleAstVisitor::Visit(GlrLiteralSyntax* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"LiteralSyntax", node);
PrintFields(static_cast<GlrSyntax*>(node));
PrintFields(static_cast<GlrLiteralSyntax*>(node));
EndObject();
}
void RuleAstVisitor::Visit(GlrUseSyntax* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"UseSyntax", node);
PrintFields(static_cast<GlrSyntax*>(node));
PrintFields(static_cast<GlrUseSyntax*>(node));
EndObject();
}
void RuleAstVisitor::Visit(GlrLoopSyntax* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"LoopSyntax", node);
PrintFields(static_cast<GlrSyntax*>(node));
PrintFields(static_cast<GlrLoopSyntax*>(node));
EndObject();
}
void RuleAstVisitor::Visit(GlrOptionalSyntax* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"OptionalSyntax", node);
PrintFields(static_cast<GlrSyntax*>(node));
PrintFields(static_cast<GlrOptionalSyntax*>(node));
EndObject();
}
void RuleAstVisitor::Visit(GlrSequenceSyntax* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"SequenceSyntax", node);
PrintFields(static_cast<GlrSyntax*>(node));
PrintFields(static_cast<GlrSequenceSyntax*>(node));
EndObject();
}
void RuleAstVisitor::Visit(GlrAlternativeSyntax* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"AlternativeSyntax", node);
PrintFields(static_cast<GlrSyntax*>(node));
PrintFields(static_cast<GlrAlternativeSyntax*>(node));
EndObject();
}
void RuleAstVisitor::Visit(GlrCreateClause* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"CreateClause", node);
PrintFields(static_cast<GlrClause*>(node));
PrintFields(static_cast<GlrCreateClause*>(node));
EndObject();
}
void RuleAstVisitor::Visit(GlrPartialClause* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"PartialClause", node);
PrintFields(static_cast<GlrClause*>(node));
PrintFields(static_cast<GlrPartialClause*>(node));
EndObject();
}
void RuleAstVisitor::Visit(GlrReuseClause* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"ReuseClause", node);
PrintFields(static_cast<GlrClause*>(node));
PrintFields(static_cast<GlrReuseClause*>(node));
EndObject();
}
RuleAstVisitor::RuleAstVisitor(vl::stream::StreamWriter& _writer)
: vl::glr::JsonVisitorBase(_writer)
{
}
void RuleAstVisitor::Print(GlrSyntax* node)
{
if (!node)
{
WriteNull();
return;
}
node->Accept(static_cast<GlrSyntax::IVisitor*>(this));
}
void RuleAstVisitor::Print(GlrClause* node)
{
if (!node)
{
WriteNull();
return;
}
node->Accept(static_cast<GlrClause::IVisitor*>(this));
}
void RuleAstVisitor::Print(GlrAssignment* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"Assignment", node);
PrintFields(static_cast<GlrAssignment*>(node));
EndObject();
}
void RuleAstVisitor::Print(GlrRule* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"Rule", node);
PrintFields(static_cast<GlrRule*>(node));
EndObject();
}
void RuleAstVisitor::Print(GlrSyntaxFile* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"SyntaxFile", node);
PrintFields(static_cast<GlrSyntaxFile*>(node));
EndObject();
}
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEAST_TRAVERSE.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:RuleAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
namespace traverse_visitor
{
void RuleAstVisitor::Traverse(vl::glr::ParsingToken& token) {}
void RuleAstVisitor::Traverse(vl::glr::ParsingAstBase* node) {}
void RuleAstVisitor::Traverse(GlrAlternativeSyntax* node) {}
void RuleAstVisitor::Traverse(GlrAssignment* node) {}
void RuleAstVisitor::Traverse(GlrClause* node) {}
void RuleAstVisitor::Traverse(GlrCreateClause* node) {}
void RuleAstVisitor::Traverse(GlrLiteralSyntax* node) {}
void RuleAstVisitor::Traverse(GlrLoopSyntax* node) {}
void RuleAstVisitor::Traverse(GlrOptionalSyntax* node) {}
void RuleAstVisitor::Traverse(GlrPartialClause* node) {}
void RuleAstVisitor::Traverse(GlrRefSyntax* node) {}
void RuleAstVisitor::Traverse(GlrReuseClause* node) {}
void RuleAstVisitor::Traverse(GlrRule* node) {}
void RuleAstVisitor::Traverse(GlrSequenceSyntax* node) {}
void RuleAstVisitor::Traverse(GlrSyntax* node) {}
void RuleAstVisitor::Traverse(GlrSyntaxFile* node) {}
void RuleAstVisitor::Traverse(GlrUseSyntax* node) {}
void RuleAstVisitor::Finishing(vl::glr::ParsingAstBase* node) {}
void RuleAstVisitor::Finishing(GlrAlternativeSyntax* node) {}
void RuleAstVisitor::Finishing(GlrAssignment* node) {}
void RuleAstVisitor::Finishing(GlrClause* node) {}
void RuleAstVisitor::Finishing(GlrCreateClause* node) {}
void RuleAstVisitor::Finishing(GlrLiteralSyntax* node) {}
void RuleAstVisitor::Finishing(GlrLoopSyntax* node) {}
void RuleAstVisitor::Finishing(GlrOptionalSyntax* node) {}
void RuleAstVisitor::Finishing(GlrPartialClause* node) {}
void RuleAstVisitor::Finishing(GlrRefSyntax* node) {}
void RuleAstVisitor::Finishing(GlrReuseClause* node) {}
void RuleAstVisitor::Finishing(GlrRule* node) {}
void RuleAstVisitor::Finishing(GlrSequenceSyntax* node) {}
void RuleAstVisitor::Finishing(GlrSyntax* node) {}
void RuleAstVisitor::Finishing(GlrSyntaxFile* node) {}
void RuleAstVisitor::Finishing(GlrUseSyntax* node) {}
void RuleAstVisitor::Visit(GlrRefSyntax* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrSyntax*>(node));
Traverse(static_cast<GlrRefSyntax*>(node));
Traverse(node->field);
Traverse(node->name);
Finishing(static_cast<GlrRefSyntax*>(node));
Finishing(static_cast<GlrSyntax*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void RuleAstVisitor::Visit(GlrLiteralSyntax* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrSyntax*>(node));
Traverse(static_cast<GlrLiteralSyntax*>(node));
Traverse(node->value);
Finishing(static_cast<GlrLiteralSyntax*>(node));
Finishing(static_cast<GlrSyntax*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void RuleAstVisitor::Visit(GlrUseSyntax* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrSyntax*>(node));
Traverse(static_cast<GlrUseSyntax*>(node));
Traverse(node->name);
Finishing(static_cast<GlrUseSyntax*>(node));
Finishing(static_cast<GlrSyntax*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void RuleAstVisitor::Visit(GlrLoopSyntax* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrSyntax*>(node));
Traverse(static_cast<GlrLoopSyntax*>(node));
InspectInto(node->delimiter.Obj());
InspectInto(node->syntax.Obj());
Finishing(static_cast<GlrLoopSyntax*>(node));
Finishing(static_cast<GlrSyntax*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void RuleAstVisitor::Visit(GlrOptionalSyntax* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrSyntax*>(node));
Traverse(static_cast<GlrOptionalSyntax*>(node));
InspectInto(node->syntax.Obj());
Finishing(static_cast<GlrOptionalSyntax*>(node));
Finishing(static_cast<GlrSyntax*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void RuleAstVisitor::Visit(GlrSequenceSyntax* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrSyntax*>(node));
Traverse(static_cast<GlrSequenceSyntax*>(node));
InspectInto(node->first.Obj());
InspectInto(node->second.Obj());
Finishing(static_cast<GlrSequenceSyntax*>(node));
Finishing(static_cast<GlrSyntax*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void RuleAstVisitor::Visit(GlrAlternativeSyntax* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrSyntax*>(node));
Traverse(static_cast<GlrAlternativeSyntax*>(node));
InspectInto(node->first.Obj());
InspectInto(node->second.Obj());
Finishing(static_cast<GlrAlternativeSyntax*>(node));
Finishing(static_cast<GlrSyntax*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void RuleAstVisitor::Visit(GlrCreateClause* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrClause*>(node));
Traverse(static_cast<GlrCreateClause*>(node));
for (auto&& listItem : node->assignments)
{
InspectInto(listItem.Obj());
}
InspectInto(node->syntax.Obj());
Traverse(node->type);
Finishing(static_cast<GlrCreateClause*>(node));
Finishing(static_cast<GlrClause*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void RuleAstVisitor::Visit(GlrPartialClause* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrClause*>(node));
Traverse(static_cast<GlrPartialClause*>(node));
for (auto&& listItem : node->assignments)
{
InspectInto(listItem.Obj());
}
InspectInto(node->syntax.Obj());
Traverse(node->type);
Finishing(static_cast<GlrPartialClause*>(node));
Finishing(static_cast<GlrClause*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void RuleAstVisitor::Visit(GlrReuseClause* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrClause*>(node));
Traverse(static_cast<GlrReuseClause*>(node));
for (auto&& listItem : node->assignments)
{
InspectInto(listItem.Obj());
}
InspectInto(node->syntax.Obj());
Finishing(static_cast<GlrReuseClause*>(node));
Finishing(static_cast<GlrClause*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void RuleAstVisitor::InspectInto(GlrSyntax* node)
{
if (!node) return;
node->Accept(static_cast<GlrSyntax::IVisitor*>(this));
}
void RuleAstVisitor::InspectInto(GlrClause* node)
{
if (!node) return;
node->Accept(static_cast<GlrClause::IVisitor*>(this));
}
void RuleAstVisitor::InspectInto(GlrAssignment* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrAssignment*>(node));
Traverse(node->field);
Traverse(node->value);
Finishing(static_cast<GlrAssignment*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void RuleAstVisitor::InspectInto(GlrRule* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrRule*>(node));
for (auto&& listItem : node->clauses)
{
InspectInto(listItem.Obj());
}
Traverse(node->name);
Finishing(static_cast<GlrRule*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void RuleAstVisitor::InspectInto(GlrSyntaxFile* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrSyntaxFile*>(node));
for (auto&& listItem : node->rules)
{
InspectInto(listItem.Obj());
}
Finishing(static_cast<GlrSyntaxFile*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENRULEPARSER.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:ParserGen
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
void ParserGenRuleParserData(vl::stream::IStream& outputStream)
{
static const vl::vint dataLength = 6495; // 70565 bytes before compressing
static const vl::vint dataBlock = 256;
static const vl::vint dataRemain = 95;
static const vl::vint dataSolidRows = 25;
static const vl::vint dataRows = 26;
static const char* compressed[] = {
"\xA5\x13\x01\x00\x57\x19\x00\x00\x1A\x00\x01\x82\x80\x09\x03\x82\x81\x82\x06\x89\x82\x85\x0A\x80\x81\x85\x0F\x0A\xA5\x0A\x88\x1A\x85\x16\x85\x21\x0A\xC9\x0A\x8C\x38\x01\x87\x7F\x8F\x20\x9F\x8A\x80\x01\x91\x93\x91\x92\x20\xA7\xA8\x9F\x7A\x90\x95\x97\x92\x2F\xA6\x8A\x8B\x9C\x93\x9B\x95\x98\x29\xB6\xAE\x83\x9A\x81\x02\x9C\x98\x3F\xB2\x9E\x97\x91\xA1\x9F\xA1\x9D\x47\xC0\x89\xA2\xA6\x84\x98\x9C\x91\x45\xD0\x8B\xA6\xAD\xA4\xA3\xA8\xA9\x55\xC8\x99\xAA\xAB\xAC\xA7\x80\xA7\x51\xB5\x97\xA2\xBD\xAC\xAB\xAE\xAB\x65\xD8\xA7\xBA\xAB\xB4\xAD\xB6\xAF\x02\xE0\xA3\xAF\xA4\xB7\xB6\xB3\xB8\x68\xF6\xAA\xB8\xBC\xB4\xBE\xB6\xBF\x70\x81\xB2\xA9\xB5\xB8\xC3\xBA\xC1\x79\x86\xFB\xA8\xCD\xBC\xC7\xBE\xC7\x81\xA4\x89\xD0\xC7\xC2\xC9\xC6\xCB\x8F\x98\xD1\xC3\xCA\xBD\xC0\xCB\xC5\x9A\x95\xDC\xCA\xCE\xC8\x02\x9F\x84\xA7\x84\xE3\x82\x0D\x99\xB3\x91\x01\xAD\xF3\xAE\xD3\xD2\xDD\xDA\xD4\x85\x04\x31\xF7\xC9\x8C\x80\xD6\x84\x03\xBA\x83\x87\x01\xE2\x85\x8E\xDE\xDB\x9D\xA3\x88\x86\x89\xD1\xE4\xDB\xDD\xD0\xCE\xC8\xE4\xD4\xBD\xEB\xE6\xE9\xD1\xD4\xD7\xFA",
"\xE3\xEF\xCD\xD3\xD1\xDE\xD6\xDD\xE1\xD0\xD0\xF0\xF3\xEF\x93\xE7\xE2\xF9\xE1\xF3\xED\xF7\xF1\xE6\xF1\xE9\xF2\xF7\xCC\xF9\xCC\x05\xC4\xEF\xEC\xEA\xFE\xF4\xFC\xF9\xF9\x00\xB5\x71\x81\x66\xF6\x5B\x63\x82\x81\x02\x89\x84\x83\x81\xA2\x4C\x85\x7A\x83\xA5\x4B\x09\x7E\x7F\x06\x4C\x03\x86\x79\x0D\x17\x80\x87\x7A\xD8\x5D\x8C\x76\x41\x0E\x1A\x87\x67\x03\x13\x90\x03\x85\x04\x13\x92\x02\x8B\x82\x0A\x88\x8C\x8B\x8B\x2E\xB1\x8D\x81\x8B\x33\xB0\x85\x8E\x8C\x0F\xB4\x89\x8E\x8D\x3B\xB8\x88\x7A\x8E\x3F\xBC\x81\x92\x8F\x1C\x9F\x8E\x86\x7E\x47\x94\x89\x91\x81\x37\x8D\x9D\x8E\x93\x43\x90\x95\x90\x92\x46\x95\x94\x97\x95\x4A\x96\x99\x94\x96\x4C\x8F\x90\x6B\x04\x2B\x84\x9D\x7C\x05\x61\x92\x9D\x7D\x97\x51\x9E\x99\x9B\x9A\x53\x9B\x9E\x98\x9A\x6D\xB0\x97\x9B\x86\x73\x80\x91\x9C\x9D\xFF\x76\x95\x9E\x90\x77\xBA\x99\x9C\x9F\x0A\x55\x05\x9A\x9A\x7D\x80\xAF\x9E\x98\x87\xA6\x99\xA0\xA1\x7B\x91\x66\x07\xA0\x6C\x8D\xAA\xA3\x7E\x72\x8B\xA1\xA6\xA5\x85\x88\xA4\xA4\x9E\x9B\xBE\x9D\xA6\xA1\x9F\x9A\xAB\x90\xA7\xA3\x9E\xA5\xA8\xA8\x49\x97\x00\xA5\xA6",
"\x93\xA7\xA2\xAA\x96\x95\xA1\xAD\xA8\xAC\xA4\x82\x48\x07\xAA\x92\x8C\xA8\xA5\xAE\x97\xB2\xAA\xAE\xAF\xBD\xAE\xA3\xAC\x97\xB5\x84\xB6\xA8\xAD\xC7\x86\xB8\xA8\xB2\xCB\x8A\xBF\xA9\x40\x19\x38\xA9\x42\x43\xCC\x7D\x7B\x06\xB4\xC0\xAC\xAF\xAF\x40\x1C\x18\xB3\x41\x07\x13\x9E\x03\x84\x44\xC7\x46\x40\x0A\xB7\xCC\x8F\xBF\x99\xB1\xEB\x89\xBD\xB9\xB3\xEF\xAA\xB1\x08\xBA\x58\xA2\x04\xBD\xBC\xC3\xB8\xBB\xB5\xBA\xF9\xB1\xA2\xB3\xBE\xCE\xBD\xB9\x7B\x08\xF7\xA4\x07\xBE\x44\xE5\xBF\xB1\xB0\xBF\x00\xC0\x06\x0B\xBD\x27\x13\x84\x45\xC2\x02\x69\x03\x86\x0A\xF7\xBE\xBC\xC3\xC2\x01\xCD\xCA\xC5\xC7\x1C\xFA\xB5\x6B\x0A\x19\xEC\xBF\xC6\xC8\xDA\xA1\xC7\xCA\x79\x2C\x25\xCE\xBB\xCA\x26\xF1\xCF\xCA\xCC\xF0\xB0\xC3\xCF\xCD\x35\xF4\xCA\xBA\x45\x14\xE0\xC9\xCB\xCF\xBC\x80\xDB\xAF\xD0\xFB\x6E\x0E\xC9\xCE\x38\xEA\xB6\xCC\xD2\x4C\xCA\xDA\xCE\xC0\x49\xD0\xDD\xD2\xD4\x4E\xD1\xDE\xC4\xBB\x2F\x07\xDA\xB8\x0C\x5A\xD4\xDE\xD7\xD5\x56\xEA\xCF\xD0\xD8\x53\xE4\xD5\xD5\xD9\x62\xEE\xB1\x0D\xD7\x66\xDF\xD9\xD8\xDA\x42\xD9\xB1\xD3\xDC\x44\xCA\xC1\xDE\xDD\xFD",
"\x72\x0C\xDB\xDB\x67\xFD\xDE\xDB\xDD\x1B\xC0\xEE\xCC\xDD\x72\xF5\xD1\xE1\x7F\x33\x3B\xD2\xE0\xCA\x84\xF8\xD6\xE3\xE0\x8F\xCC\xE1\xE7\xD2\x7E\xED\xD6\xE4\xDF\x7F\xCD\xE7\xE1\x42\x34\x0A\xEA\xE4\xE4\x85\xE1\xEE\xE2\xE8\x9B\xE4\xE0\xEB\xE8\xA8\xE5\xE3\x41\x0D\xF7\xB6\x07\xBF\x0D\x9E\xD3\xEC\xB8\x0E\xF7\xB9\x03\x86\x0E\x13\xBB\x03\x84\x0F\xB1\xE6\xE2\xE6\xEF\x94\xD5\x6D\x0F\xBD\x3E\x37\xBF\x0D\xEF\xA9\xE7\xE2\x40\x10\xF7\x81\x13\x86\x10\x13\x98\x4D\xCC\x00\x44\x08\xFA\xEB\xF5\xCA\xD9\xFF\xED\xF2\xDB\xD8\xFD\xF6\xF6\xC1\xD7\xEB\xE1\xF8\x98\xE2\xFF\xE6\x9B\x45\x37\xB6\x13\xBD\x47\x16\xF0\xF8\xBB\x48\x37\xBA\x47\xF4\x4A\x13\x8B\x13\x84\x4C\x2E\xF0\x01\x13\x13\x8E\x1A\xFC\xF9\xE3\x63\x6D\xF9\x03\x81\x81\xB0\x45\x80\x6E\xE7\x6F\x0B\x84\x50\x0F\x7E\x01\x87\x85\x72\x04\x87\x7C\x00\x92\x8E\x80\x0A\x86\x86\x82\x08\x92\x77\x65\x51\x07\x5E\x29\x37\x5B\x0A\x0D\x97\x83\x78\x54\x07\x5F\x2A\x13\x46\x0A\x13\x57\x0B\x84\x58\x01\x85\x0C\x80\x7D\x82\x1A\x8E\x84\xF7\x13\x81\x86\x08\x8F\x81\x73\x35\x98\x87\x0B\xEE\x59\x0B\x7B\x5A\x0F",
"\x5E\x5B\x0D\x86\x0D\xFD\x3C\x0B\x7B\x5D\x0B\x42\x5E\x13\x43\x17\x13\x40\x0C\xFD\x61\x0B\x42\x62\x02\x8A\x0E\xB3\x80\x87\x1D\xB2\x86\x7B\x34\x96\x8B\x10\xB9\x86\x7C\x2E\x91\x86\x8B\x37\x9D\x8A\xEF\x63\x02\x8A\x31\x94\x8F\x32\x64\x13\x41\x19\x65\x8F\x8A\x2D\x93\x88\x8B\x55\x87\x8F\x15\xEF\x72\x84\x37\xA6\x88\x8E\x75\x83\x22\x19\x77\x57\x0D\x7B\x68\x0C\x8D\x61\x85\x35\x1A\x77\x5A\x0D\x09\x6B\x0B\x42\x6C\x13\x41\x1B\x00\x98\x83\x2D\xB6\x8D\x8D\x72\x8E\x91\x24\xEF\x84\x8F\x39\x9F\x78\x00\x6E\x0C\x90\x18\x8D\x94\x93\x4B\x99\x8B\x92\x77\x95\x92\x24\xF8\x86\x93\x4F\xA4\x93\x94\xA2\x9D\x92\x29\xA9\x9D\x61\x37\x1A\x97\x91\x81\x91\x94\x27\xA1\x9E\x93\x38\xA7\x92\x95\xB6\x8C\x94\x24\xB7\x94\x97\x55\xB5\x91\x8F\xBC\x9B\x96\xF6\x70\x0F\x95\x81\x31\x0D\x98\xC1\x92\x97\x26\xCB\x90\x97\x59\x82\x9F\x97\xA5\x99\x94\x34\xA8\x93\x9A\x5C\x80\x9A\x97\x6D\x52\x0C\x32\xD8\x9E\x98\x65\x8D\x99\x21\x73\x0A\x20\x6C\x63\x36\x0E\x71\xBD\x39\x0F\xE6\x8C\x98\x28\xA5\x3C\x0F\x74\xBB\x3F\x0F\xEE\x83\x22\x20\x71\x92\x21\x42\x34\x99\x20\x88\x17",
"\x9D\x35\xBD\x92\x9A\x5F\xBE\x9D\x9F\x00\xB7\x9B\x3E\xCF\x9F\x9E\x81\x85\xA1\x9A\x06\xA1\xA0\x42\x8B\xAA\x5D\x45\x1B\x98\x00\x8C\x0F\xA3\x41\xD4\x9E\x97\x46\x12\xA2\xA1\x14\xB8\xA2\x35\x8C\xAB\xA3\x8C\x89\xA7\x32\x8E\x17\xA3\x47\x96\x9F\x10\x91\x9C\xA4\x9F\x23\xBE\xA3\x49\x84\xAA\xA2\x5A\x90\x17\xA1\x91\x06\xA6\x4A\xB3\xAD\xA3\x9A\xA8\xA3\xA5\xDE\x8B\x9D\x4E\xC9\x9D\x9B\x9E\xA3\x3A\x12\x13\x53\x12\x4C\xB6\xAC\xA5\x94\x84\xAB\xA7\x58\x54\x13\x50\xB7\xA4\xA6\xA6\x87\xAE\xA7\xDF\x91\xAA\x4E\xD0\xA3\xAA\x75\xBC\xA6\xAA\x01\x35\x13\x43\x96\x1B\xA9\xA2\xB8\xA7\x7C\x97\x1D\xA8\x52\x83\xA3\xAD\x89\x8F\xA8\xAB\x64\xA7\x7C\x26\x62\xA4\xAA\xEF\x59\x14\xAD\x68\xA6\xAE\x53\xF3\xAE\xAB\xA6\xB5\xA9\x5F\x9A\x0F\xA3\x26\x70\xA2\xAB\xAB\xBD\xAC\x9B\x71\xAD\xA7\x5D\xF4\xA5\xAC\xC1\x85\xB6\x5D\x9C\x13\x41\x27\x7C\xA5\xAB\xBF\xA9\xA9\xB0\x02\xBE\x10\x63\xFE\xAD\xB1\xCA\x94\xB7\xB2\x80\xAE\xB3\xC9\x1F\x13\xB3\xCC\x96\xB6\xB3\x98\xAF\xB3\x7E\x20\x1D\xB2\xD1\x9F\xB7\x92\xA1\x05\xB6\x5C\x83\xBC\xB5\xC3\x9F\xA8\xB2\xAF\xA6\x22\x28\x2A",
"\xB6\xB1\xFE\x23\x14\xB6\x46\xA4\xB1\x5B\xA0\xBC\xB6\xD3\xA1\xB6\x3C\xA4\x0F\xA1\x29\x38\xB1\xB7\xD3\xAB\xB6\xB5\x76\xA8\xBB\x59\x9A\xB5\xB6\xD8\xAA\x5E\x14\x13\x47\x14\x71\xC9\xBB\xB6\xDF\xBD\xB7\xB8\xD5\xB8\xBA\x73\xCB\xB9\x48\x54\x13\xBC\xBB\xBF\xAD\xB8\x73\xB9\xBD\xB5\xEC\xA2\xBE\xB8\xE7\xA1\xBC\x79\x8B\x79\x15\x09\x6A\x17\xBB\xBA\xBB\xB9\x7C\x8E\xBB\x14\x7D\xA6\x3E\x15\xF6\xA9\x3D\x2C\x79\xBB\xBD\xF3\x74\x14\xBF\x99\x37\x16\x3E\xBA\x1A\x9F\x5E\x3A\x98\x18\x00\xD4\xBA\x7C\xE5\xBB\xC0\xE5\xA0\x33\x18\x13\x44\x18\x7C\x8C\xCB\x3F\x62\x13\xC6\xC1\x14\xC8\xBD\x7F\x8D\xC6\xBD\x0D\xE3\xBD\xB8\xEA\xA0\xC7\x75\xE9\xB1\x20\x63\x17\xC5\xC3\x22\xD6\xBA\x8A\xDA\xBF\xC2\x05\xFE\x77\x18\x27\xDC\xC2\x8C\xAD\xC0\xBD\xDE\x88\x1F\xA1\xC9\x11\xC4\x8D\xF3\xBA\xC3\x14\xEC\xC3\x20\xCA\x0F\xA0\x21\x2C\x36\x21\xDC\x23\x2C\x26\x46\xC4\x30\x92\xE1\x2B\xC9\x23\xEB\x21\xC9\x9D\x2D\xCA\x92\xCF\xCC\xC9\x95\x04\xCE\x20\x12\x43\x2C\x94\xA4\x32\xCB\x28\xD4\xCE\xC9\x28\x37\xCB\x40\x78\x3A\xCB\x2A\xE8\x23\xCB\xDE\x3D\xC8\x97\xD6\xCA\x20\x32",
"\x65\xC8\xCC\x25\x28\xCF\x79\x6A\xC9\xCC\x36\xC9\x21\xCB\x84\x32\xCC\x4D\x74\xC3\xCF\x2F\xD3\xC9\xCC\x0A\x38\xCD\x67\x7A\xCB\xCF\x33\xE6\xC9\xCE\x87\xC1\x26\x98\x82\x29\x42\x4B\x74\x26\x38\x06\x31\x5B\x9B\xFF\xC8\xD0\x38\xE1\x24\xD0\x85\xCA\xD2\x42\x4B\x3A\x61\x47\xCA\x26\x44\x93\xDE\xC8\xA0\xF7\xC1\x2D\x45\xC1\x24\xCC\x84\x26\xD4\x00\x6E\xC9\xD5\x40\xE5\xD6\xD5\x63\x2A\xD5\xA3\xC0\x5E\xD3\x84\x12\xD5\xD5\x09\x3C\xD3\xC6\x35\xD6\x20\x50\xF4\xD3\x25\x90\xC3\x22\xBD\x63\x20\x38\x4B\xE0\x25\x39\x02\x28\xDA\x77\x41\xD2\x20\x30\x44\xD9\xD1\xC7\xCA\x22\xAA\xBC\xD3\x20\x67\xC4\x35\xD8\x94\xD7\xD0\xB4\x9F\x28\xD3\x4C\xDC\xDB\xDB\xFF\x1D\xDA\xB7\xE2\xD9\xD2\x72\xC5\xD6\xDC\x7B\xCA\xD6\xA0\xA4\x38\xDC\x3E\xDE\xDA\xDB\xC6\xDF\x22\xAA\xA8\xD3\xD0\x70\xED\xDE\xCF\xA2\xC5\x26\xAA\xAC\xD5\xDF\x78\xE1\xDE\xDE\xE0\xCA\xDD\x58\x77\xD6\xD0\x7F\xC4\xE2\xDF\xB0\xD9\xCC\xC0\x86\xE1\xE0\x85\x33\xD5\xD3\xC0\xCA\x23\xAD\xFD\xD9\xDA\x90\x07\xE0\xDE\x15\xF2\xDF\xA6\xBC\x54\xDA\x81\x3E\xD4\xE2\xF9\xD8\xE1\xC8\x96\xEB\xE1\x8C\xFF\xDC\xE1",
"\x28\xE6\xE6\xC0\xA1\xDB\xCD\x82\xE6\xE7\xE2\x20\x33\xDF\xC0\xA5\xE3\xE5\x6F\xFE\xDB\xDF\x33\xE9\xE5\xCD\xA7\xEA\xE5\x84\xE0\xE5\xE5\x95\xCF\xE5\xC3\xA4\xDC\xE5\x3A\xEE\xE3\xE7\x30\xFA\xE1\x42\x0F\xEB\xD7\x88\xF6\xD1\xE7\x42\xFA\xE4\xD0\x9A\xD9\xD6\x8E\xCE\xED\xD7\x61\x38\xDB\xCE\xDA\xE3\xEA\x28\x5D\xE1\x20\xB7\x4F\xDA\xBF\xCA\xDC\x27\xAF\xC0\x06\xDA\x9D\x3C\xEA\xD1\xA5\x2A\xED\x3E\xE8\x25\xED\xEF\xC4\xE6\xD4\xEB\xE2\xE5\xAE\xF6\xE1\xEA\x78\xE8\xEB\xD0\xD8\xC0\xEA\xBD\xF3\xEE\xED\x08\xE9\x20\xBD\xEC\xD4\xE6\xBB\xFC\xE3\xE7\x38\xE5\xE8\xE0\xF5\xE4\xEE\xB9\xFD\xE4\xE8\x0A\xFF\xED\xDC\xF7\xE8\xF0\x9F\xC4\xF2\xF2\x93\xE9\xEB\x3F\x32\xD6\xEA\x94\x0C\xD8\x5A\x7D\xE6\xF2\xE6\x9A\xFA\xD4\x5D\xE0\x66\xEC\x1F\xF7\xF1\xDE\xA2\xFB\xEF\x81\x2B\xDE\x3B\xA4\xEA\x23\xE0\xB0\xFD\xF4\x81\x3C\xDA\xF5\x95\xF0\xF3\xCF\x8D\xFA\xE8\xBE\xCA\xF3\xF2\x9B\xEE\xE1\xE7\xA5\x2F\xF2\x00\x13\xE0\xF7\x86\xE5\xF7\xF0\xA1\x25\xF9\xD4\xF4\xF7\xE6\x96\xFE\x3A\xCC\xB1\xDD\xCD\x57\xFA\xF4\x34\x2B\xF8\xD6\x41\x4C\xE7\xF5\xAB\xC3\x27\xF8\xD2\xFB\xE2",
"\xA3\xDE\xFE\xE3\xAC\xE0\xD8\xEE\x93\xE3\x9C\xD6\xE3\x25\xF8\x71\x62\xEE\xE4\xE8\xF1\xEE\xFA\x83\x2E\xF9\xF3\x2D\xF9\xF4\xBC\xE7\xF0\xEB\x98\xF1\xEF\xD8\xD7\xFF\xF9\xAB\x79\x7F\xD3\x71\x79\x01\x8B\x78\x31\x75\x7D\xBF\x79\x79\xB5\x71\x10\xAF\x77\x1E\xA3\x7B\x80\x00\x0D\x80\xEE\x6A\x80\xD0\x7B\x74\xCB\x70\x12\xC5\x70\x7E\x0E\x85\x78\x02\x82\x7E\xBF\x6E\x79\x9F\x68\x7F\x06\x84\x79\xFB\x7F\x78\xBE\x74\x80\xB9\x76\x10\xB3\x7B\x81\x15\x86\x10\xB7\x70\x80\x29\x8E\x7A\x22\x80\x7C\xD9\x7B\x7B\x23\x81\x7C\x16\x83\x7E\x20\x8F\x74\x09\x81\x77\xCA\x7A\x83\xC4\x71\x82\xEF\x7B\x75\xE0\x63\x7F\x3C\x1B\x6C\x47\x87\x6D\xE7\x75\x84\x49\x8D\x19\xC5\x74\x17\x0F\x8C\x7F\xEF\x61\x85\x05\x80\x7C\xFE\x77\x82\x36\x86\x85\x1C\x87\x83\x03\x89\x85\x14\x85\x85\x93\x79\x78\x28\x85\x82\x7E\x76\x82\x32\x8D\x83\x53\x8B\x85\x34\x81\x7D\x2C\x80\x86\xFD\x70\x81\xDC\x72\x32\x66\x7A\x81\x13\x8F\x86\x52\x8E\x6D\x3F\x8F\x81\x41\x89\x10\xF5\x74\x13\xF1\x7F\x6E\xAA\x64\x76\x68\x26\x76\xD3\x60\x21\x66\x76\x84\xDE\x1F\x87\x78\x8A\x10\x16\x28\x86\xE3\x6A",
"\x86\x5F\x81\x83\x02\x1A\x88\x8E\x75\x86\x96\x84\x86\xC9\x7A\x10\x21\x2E\x88\xE5\x60\x89\x76\x86\x86\x02\x1D\x88\x63\x89\x7F\x54\x82\x89\x0C\x86\x7D\x06\x14\x89\x24\x84\x8A\x9E\x80\x88\x6C\x84\x13\xAA\x6B\x89\xA3\x87\x83\xA5\x89\x89\xFF\x77\x1E\xAA\x62\x8A\x5E\x8F\x89\x97\x8D\x81\x82\x78\x8A\x03\x1A\x8A\xFA\x7C\x8A\x77\x89\x69\x5D\x88\x7D\x9A\x83\x83\x91\x88\x89\xBE\x8A\x82\xC0\x81\x8A\xCA\x8C\x8B\xCC\x8C\x85\x08\x8A\x7D\xC1\x81\x8D\x69\x85\x8C\x85\x62\x86\x9D\x11\x8B\xD8\x8F\x88\xDA\x89\x6E\xD5\x8D\x8D\x8C\x8F\x8D\x9D\x81\x8E\xB0\x8F\x8A\x76\x69\x8A\xE6\x87\x6E\xAD\x8B\x88\xB7\x89\x8E\x09\x12\x8B\xBB\x89\x8D\x6E\x8E\x8A\xF1\x8B\x8E\x03\x1A\x8B\xC8\x74\x8C\xF7\x80\x8F\x58\x88\x8C\x09\x12\x8C\xB5\x8E\x8F\xA6\x81\x81\xCF\x81\x10\xF4\x8D\x8F\xB4\x8F\x8E\xC6\x8A\x8E\xA3\x65\x21\xED\x8B\x67\x05\x94\x8D\x39\x8A\x87\xCC\x72\x71\x09\x90\x00\x04\x9E\x90\xEE\x8D\x82\x03\x11\x87\x83\x84\x7E\xA0\x74\x7D\xF3\x83\x91\x75\x86\x8F\x07\x92\x92\x86\x84\x92\xC6\x7B\x91\xFC\x80\x83\xD3\x8A\x85\x20\x97\x10\x17\x8F\x11\xCD\x7B\x91",
"\x1D\x98\x8E\xF8\x66\x8B\x06\x16\x7A\x72\x8E\x92\x7D\x8A\x8F\x02\x1B\x90\x32\x96\x90\x33\x91\x86\x1E\x80\x71\x3B\x8B\x7E\x18\x98\x81\x0A\x1A\x2A\x43\x8E\x93\x03\x12\x88\x2D\x9D\x94\x03\x15\x88\x11\x95\x95\x37\x9F\x0F\xC5\x7A\x95\x6C\x70\x6E\x74\x16\x76\x2C\x9F\x76\x10\x86\x95\x40\x24\x88\x1B\x98\x96\x42\x2A\x96\x53\x99\x7F\xC2\x82\x8F\xD5\x20\x84\x19\x99\x10\x60\x94\x75\x73\x9F\x94\x38\x92\x6D\xE6\x75\x93\x01\x14\x22\x74\x90\x95\x09\x10\x2E\x26\x92\x91\x9C\x8F\x91\xFF\x87\x8E\xA0\x81\x10\x3B\x99\x98\x88\x9D\x8B\x16\x90\x22\x28\x9D\x93\x48\x95\x99\x91\x9B\x8F\x93\x97\x74\x49\x9E\x83\x10\x91\x78\xEC\x87\x98\x14\x9E\x91\xE2\x89\x8F\x5B\x95\x94\x99\x91\x74\x90\x9B\x86\xA4\x9E\x99\x98\x90\x9A\x29\x90\x8E\x8B\x90\x00\x2B\x82\x97\xD7\x8E\x9A\x94\x9D\x90\x7E\x92\x9B\x1B\x96\x94\x6D\x89\x9A\xCB\x8D\x8C\x63\x60\x93\xA7\x9C\x78\xB8\x91\x9B\x2F\x88\x8B\xBF\x13\x9C\x95\x8B\x99\xF8\x8E\x82\xBB\x9A\x9C\xAB\x85\x9C\x07\x97\x9C\xB4\x90\x8D\xB6\x9A\x99\x96\x9A\x9A\x01\x91\x7E\x03\x90\x9D\xC3\x82\x9D\x54\x92\x10\x12\x84\x94\x0A",
"\x9E\x9D\x15\x9A\x9D\x67\x86\x8D\xD6\x93\x8B\x34\x9E\x98\xA3\x9B\x9D\xC8\x9D\x9D\xD7\x98\x9A\xCC\x90\x90\xE9\x94\x8E\x27\x93\x9F\xC4\x9D\x9E\x07\x93\x9E\xA5\x91\x10\x31\x9D\x9B\xF5\x9A\x98\x2B\x9D\x95\x19\x8A\x93\xE6\x92\x9A\xD5\x91\x10\x65\x9D\x96\x2E\x94\x87\xE4\x90\x00\xBC\x9F\x9A\x04\xA3\xA0\xDB\x82\x7C\x81\x9B\x97\x3C\x8A\x9E\x00\xA9\xA0\x3C\x9F\x9F\x04\x16\xA0\x42\x8C\xA1\x1C\x9E\xA1\xEE\x9B\xA0\x21\xA9\xA1\x5E\x93\xA2\xF8\x92\x99\xFA\x9B\x9C\xD9\x9A\x94\x55\x7A\xA2\x39\x9F\x96\x97\x92\x10\x2A\x25\x98\x03\x10\x98\x7A\x9B\xA2\x83\x9D\x97\xB1\x9C\xA3\x4C\x9B\x87\x06\x14\x98\x4A\x89\x9B\x42\xAD\x74\x58\x92\x10\x46\xAE\x84\xE3\x84\x1A\xBD\x16\x72\x51\xAB\x73\x53\xA6\x78\xC5\x79\xA3\x84\x15\x7C\x28\x23\x16\x55\xA9\x7F\xC5\x74\x2E\x59\xA0\x29\xC5\x7F\x28\xEC\x75\x8E\x65\xA9\x10\xD7\x27\xA6\x06\x12\x28\x6A\xA3\x10\x6C\xA1\xA6\xAB\x95\x97\xF0\x96\x76\xD4\x2E\xA4\xD3\x21\x16\xC5\x7D\x2D\x6D\xA2\x10\xE7\x2B\xA7\x01\x1D\xA7\x70\xA6\x2E\x61\x1B\x0B\x64\x73\x21\xAA\x68\x88\x3C\x14\x76\x87\xA8\x1B\x4D\x89\x6C\x7C\x99",
"\x10\x88\xA3\x12\x8A\xAA\x4F\x92\xAF\xA8\x06\x11\xA9\x86\xA4\xA9\x99\xA0\xA9\x8D\xA1\x10\x93\xAC\xA9\x09\x12\x67\x5D\xA5\xA2\x09\x13\x1C\xD3\x3B\xA8\xA5\xAB\xA9\x97\xAC\xA8\xA9\xA7\xAA\xFA\x46\xAA\x79\x99\x95\xAF\xAA\xAA\x03\x18\xA8\xB0\xAC\x95\x76\x93\xAB\xAE\xA0\xAA\x06\x17\xAB\x8E\xA9\xAB\xBC\xA3\x10\xC5\x7F\xA9\xAB\xA9\x10\xC3\xA6\xA9\xB5\xAC\xAA\x06\x17\xAC\xC0\xA5\xAC\xCB\xA4\xAB\x02\x18\xA8\xCC\xA6\x10\xA8\xAF\xAC\xBB\xAE\xAC\xC2\xA0\xAD\x01\x12\xAD\xDA\xA0\x00\x88\xA0\x94\xC4\xA9\xAC\x33\xA1\xAB\x02\x15\xAD\x03\x12\x67\xE0\xA8\xAC\xD1\xAB\x94\xBF\xA4\xAD\xFA\x49\xAE\xCD\xA2\xAE\x3F\x9D\xAD\xDF\xA4\xAF\xEC\xAE\xA9\xEA\xAB\xAD\xFA\x48\xA8\x72\x68\xA8\xFE\xAB\xAF\xFA\x4B\x82\x2B\x82\x67\x02\xB2\x7B\x06\xBF\x8B\x08\xBE\xAE\xC1\xA5\xAE\xFA\x42\x67\xE6\xAC\xB0\x0B\xB1\x10\x0F\xB2\xB1\xFA\x43\xB1\x00\x06\xB1\x0D\x88\xA8\x19\xBA\xAC\xF7\x9B\xAE\xB7\x8A\xB1\xFA\x4B\xB1\x1F\xBC\x86\x88\xA1\xAE\x1E\xB4\xAE\x14\xB1\xB1\x00\x02\x67\x26\xBA\xAF\xD7\xA2\xAF\xB8\xAA\xB0\xD8\xAD\xAE\xB2\xAA\xB2\x2D\xBE\xAD\xF6\xA9\x10",
"\x01\xA7\xB3\x88\xA1\x87\x3C\xB9\x8C\x2F\xB7\xB2\xAD\x98\xB2\x17\xBD\xB0\x18\xA4\xB4\x16\xB2\x67\xBC\x9F\xB3\xA1\xA6\xA6\x48\xBA\x4F\x3E\xB9\xAF\x38\xB9\x9F\x4F\xBA\xB2\x3B\xB2\xB5\x3D\xB9\xB3\x2E\xA5\xB5\x33\xBD\xA1\x41\xBE\xB2\xDB\x7A\xB5\x03\x1B\xB4\x58\xBE\xB4\x31\xB5\xB3\x5D\xB0\x00\x51\xB1\xAF\x42\xB6\x9A\x5F\xB3\xB5\x86\x9C\xB5\x30\xBC\x68\x62\xBE\xB6\x72\xBD\xB6\x5E\xB7\xB7\x60\xB1\x92\x75\xB5\x9E\x6F\xB8\xA8\x49\xA1\x10\xF5\x7B\xA5\x06\x18\xA5\xD5\x6F\xA4\x01\x1F\xA6\x43\xB7\xB6\x10\xB9\xB6\x8A\xB4\xB7\x7F\xB1\x28\x40\xBA\xB7\x70\xBE\xA6\x66\xB4\xB3\x8D\xB3\xB7\x01\x12\x67\x8F\xBC\xA0\x7D\xBB\xB2\x92\xB4\xB5\x8C\xB9\xB2\x69\xBC\xB9\x97\xB8\xAF\x6C\xBB\xB7\x02\x1D\xB9\x6A\xBF\xB9\xAC\xB4\xB6\xA9\xB5\xB9\xAB\xB7\xBA\xA6\x15\xB6\x09\x1C\xBA\x6B\xB2\xB3\x9A\xB0\x00\xAF\xBE\xBA\xB4\xBC\xB4\x6B\xA7\xB4\xA3\xB5\xB4\x2A\xBD\xBB\x91\xB7\xBB\xBF\xB6\xBB\xC1\xB7\x91\xC3\xB6\xB1\xC6\xB4\xB9\x88\xAC\xBA\x57\xB1\xBB\xD1\xB2\xBC\x98\xB4\xBA\xBB\xBF\xBC\xCD\xBA\x4F\xD2\xBE\xBB\xCC\xB7\xBD\xC4\xBE\xB8\x93\xBB\xBD\x2A",
"\xB4\xA6\x06\x12\x95\x06\x11\x76\x91\x6C\xB1\x02\x12\x67\x23\x1E\x06\xA6\x64\x76\x88\xA1\x31\x9D\xAF\x06\xF1\xB2\xB5\x06\x3D\xA9\x70\x07\xBF\xD3\x3E\x7E\x8D\xA1\x07\xFC\xBD\xA8\xAC\xBD\x26\x23\x1B\x82\x04\xC4\xBB\x6D\x2A\xB4\x9D\xA0\x00\x72\x01\xC0\xE7\xAC\xA2\x49\x83\x07\x0E\xCD\xBE\x0A\x1A\xBE\x4D\x84\x07\x13\xC8\xBA\x45\xAB\xC0\x75\x09\xC1\xE1\xB2\x6C\x0B\xC6\x07\x1E\xC2\x67\xBC\x3D\xA9\x77\x03\xC2\x0A\x13\x3C\x9D\xA8\x07\x28\xC9\x10\xC5\x3D\xA9\x79\x0E\xC1\xA3\xAD\x39\x9D\xAA\x07\x32\xCA\x10\x34\xCD\xA8\x7B\x07\xC3\x09\x1A\x3B\x9D\xAC\x07\x3C\xC6\x10\x3E\xCD\xA8\x7D\x01\xC4\x03\x10\x3D\x9D\xAE\x07\x46\xC2\x10\x48\xCD\xA8\x7F\x0E\xC1\x6D\x7D\x3E\x9D\xA0\x08\x1E\xCE\xAB\x01\x17\x3F\x9D\xA1\x08\x55\xCA\x10\xF9\x3D\xA9\x82\x0B\xC5\x09\x1D\xC5\x8D\xA3\x08\x1E\xCB\x0C\x0B\xCA\x6A\x63\x5A\x6A\x1A\x8B\xC0\xA0\xB3\x1E\x23\x1E\xB0\x52\xBF\xC6\xEC\xB8\x25\xA2\xA2\xB5\x71\x83\x12\xC5\x78\x6E\xCA\x13\xC7\x1F\xC2\x10\x56\xCC\x13\x01\xAA\xC7\xD6\xBB\xB9\x52\xB0\x94\x23\x15\x7F\x82\xC9\x10\x84\xBF\xC0\xB1\xBD\x80\x23\x17",
"\x9C\x89\xCB\xBC\x45\x62\xB5\x86\xB9\x84\x16\xC4\xC1\x09\x1A\xA7\xBA\xB2\x10\x1A\x80\xC7\x09\x16\xBE\x4D\x8E\xBF\x8C\xC6\x10\xC3\x6B\xC9\x01\x1D\xA4\x98\xC9\xB6\x85\xA5\x5D\xFD\xAB\xC0\xBE\x43\xAA\x6B\xCA\x10\xF9\xB4\xB4\x27\x33\xAA\x68\xC1\x11\xF7\x23\x2F\xD3\x33\xAA\x77\xCA\x10\x0F\x33\x3D\xB5\xCA\x10\x7F\xC3\x12\xF4\xB4\xCB\xEC\x23\xAA\x86\xC3\x11\xFA\x33\xAA\x8E\xCA\x10\x16\x30\xCC\xC7\xCA\x10\x95\xC7\x84\x18\x33\x3D\x24\x31\xBB\xE6\x13\xAA\xA0\xC9\x84\x3C\x34\xB4\x46\x38\xCD\xE9\x1F\xC7\x4F\x8D\x1F\x5C\x30\xCE\x97\x15\x7C\x6D\x73\x12\x7A\x30\xCD\xEE\x20\x94\xB7\xC1\x39\xA5\xC3\xBC\x2B\x89\xCE\x0A\x19\x38\x2A\xB7\x32\x0D\x8F\xCE\xBE\x34\x30\xD3\x31\xA0\xF4\xC9\x10\xAE\x37\xCF\xEC\x21\x87\xB1\xC9\x10\xB6\x3D\xB4\xE3\x13\xCB\xA3\xCC\xB7\xB1\xB3\x12\x2A\xC3\xC9\xE3\x13\x31\x06\x1C\xCB\x83\xCC\x13\xCE\x38\xD0\xFB\x1D\xCD\x0B\xD0\xB9\xBD\xAB\xC0\xE9\x38\xD1\x49\x2B\x36\x20\xDC\xD1\x03\x19\xCC\x09\x13\x3F\x10\xDB\x1F\xAC\x33\xD2\x9E\xB7\x8B\x23\x1C\x3F\x2C\xDE\x26\x07\xD9\xD2\x0C\xD5\xB8\x0B\xCC\x41\x31\xD6\x42",
"\xB1\xBF\xD0\x1B\xDD\xD2\x06\x1B\xCD\x47\x8A\x42\x31\xD1\x44\xB1\xB7\xD1\x34\xD6\xB7\x03\x1B\xC8\x49\x8E\x4B\xBC\x91\xB8\x65\x72\x4D\x4E\xD5\xD0\x06\x17\x44\x31\xD6\x1E\x1F\xD7\xD4\x7F\x91\xC7\x0A\x1F\x44\x55\xD9\x1E\x28\xD3\x10\xA3\xAE\xD4\xBD\xC9\x10\x6B\x4D\xD5\x97\x1E\x3F\x31\xDE\xD4\xC3\xCA\x10\x83\x46\xD6\x99\x1E\x41\x69\xD7\xAF\x3C\x1B\x48\x6E\xD1\x19\x28\x41\xD7\x2E\xDA\x10\xC7\x45\xD7\x95\x1F\x43\x78\xD6\xD3\x9D\xA5\x07\x7C\xC8\x4E\xB1\xB9\x44\x7F\xD3\x10\x40\xDC\x13\x7B\x0C\xC7\xF0\x41\xBB\x51\x41\xD3\x83\xBE\xCA\xD2\x4A\xD4\x8C\x9B\xC0\x81\x0A\x3F\xD3\xC4\xAA\x8D\xA3\x4F\xEC\xC0\x2F\x99\xD8\x76\x4B\xD2\x4D\xA0\xD1\x10\xC7\x9D\x26\x83\x02\xB5\xE6\x17\x9C\xFF\xC6\x10\xF6\x4D\xD9\xEA\x2C\xBA\xAB\xD3\x10\x86\x09\x60\xF9\x29\xD8\xB1\xD2\x10\x89\x0A\x3F\xE8\xB5\x9B\x8D\xAA\x08\xFA\x37\xC9\x01\x1B\xDB\xA1\xD2\x50\x1A\x82\xD5\x03\x1E\x50\x7C\xD0\x1A\x7B\x41\xD3\x1A\x8A\xCF\x03\x15\x52\xC9\xD5\x1A\x85\x4C\x1B\x1A\x9F\xBD\x47\x82\x54\xD1\xD3\x12\xAE\x4C\xDC\xC2\xCB\xC0\x61\x59\xDD\x0A\x11\x4E\xDC\xD3\xAE\x4D",
"\x8B\x57\xE0\xD9\x10\x77\x0C\xC7\x1A\x8D\xCC\x09\x1C\x59\xE7\xD6\x10\x8B\xD3\xDE\x80\xDD\xA8\xB7\x51\xD3\xD2\x51\xBB\x8D\xD8\xD5\x2F\x9F\xC9\x0B\xCD\x5E\x31\xDD\x0A\x52\xB7\xDA\x31\xD5\xA7\x9C\xCB\xC0\xAF\x08\xDA\xE9\x17\x08\x13\x24\xE0\xD8\xB9\x84\xFB\x56\xCE\x99\x19\x4F\xB1\xBC\xE0\xAD\xBD\xA9\xB3\x08\xE0\x97\x1E\xDB\xD3\x34\xE1\x6B\xD9\x10\xB5\x08\xE1\x99\x18\xDC\x44\xB4\xE1\x26\xD6\x10\x02\x60\xE1\x91\x11\x51\x1B\xEC\x86\x23\x19\x0B\x20\xE1\x19\x16\x5B\xE2\x09\x19\xD9\x23\x1B\x0B\x52\xB6\x60\xB1\xB1\x52\x32\xEF\xD3\x0B\xCF\x0B\x52\xB1\x0C\x52\xB0\xDD\x44\xBA\xC9\xDF\x7B\xC0\x10\x6E\xDA\x95\x1F\x52\xD3\x34\xE4\x99\xB9\x84\x12\x68\xE4\xA0\x11\x53\xB1\xBC\xE4\x3E\xDD\x84\x16\x60\xE5\xA5\x18\xDD\x43\xED\xDD\x9D\xA6\x62\x58\xE3\x12\x4A\x5B\xE4\x72\xD3\x12\x30\x6F\xE5\x0A\x1A\x55\x62\xE9\xD7\x09\x17\x63\x66\xE9\x10\x5C\x59\xE6\xF3\xDD\x84\x39\x63\x3D\x41\x61\xBB\xDF\xDB\xE5\xFC\xDD\xA9\xCC\x03\x21\xCD\x02\xB5\x6B\x53\x3D\xA8\xC1\x10\x69\xAD\xA8\xCF\x0A\x3F\x81\xE0\x00\x54\xEC\x13\xD0\x02\xB5\xD2\x07\x2F\xA2\xC2",
"\x10\x83\xED\x84\xD3\x0A\x3F\x8F\xE1\x10\x89\xE3\x12\xD4\x02\xB5\xD6\x07\x2F\x60\xA5\xE4\x9D\xA7\x0D\xB4\xD0\x1A\x6F\x51\xBB\x9D\xED\xE4\x47\x8A\x0D\xA1\xE5\x1A\xE6\xD9\xB6\xA5\xE5\xE5\x49\x8D\x0D\xA9\xE3\x12\x92\x54\xEA\x5C\xED\xA8\xE0\x01\xEB\x0A\x14\x5A\xB4\xE4\xDE\x49\x83\x0E\xB8\xE9\x10\xB3\x5B\xEB\xF0\x93\x12\xE6\x0F\xEB\x06\x11\x5C\xC2\xE3\x10\x34\xEA\x10\xE9\x0A\x4F\xEC\x02\xB5\xD0\x59\xEC\x02\x19\xD8\x23\x1E\x0E\xFA\x41\x0F\x52\xBE\x5D\xB1\xBA\xCB\xEB\xBD\xA9\xF3\x0F\xE2\x95\x1F\x5E\xDB\xEA\xD5\x09\x15\x0F\xE0\xE0\x1A\xAC\x0A\x4F\xDC\xE5\xD3\x4D\x87\x0F\xE7\xE5\x1A\x07\xE3\xEE\xAD\xAD\xA8\xF9\x0F\xEE\x23\x1F\xE0\xA6\xC0\x00\xEB\xE6\x93\x9D\xAB\x0F\xF6\xEA\x10\x17\xE2\xEF\xC3\xEA\x10\xFD\x0F\xEF\x1E\xE2\xB5\xFB\xE1\x10\xCB\xEE\x11\x52\xB1\x00\xCA\x6A\x6A\x27\xE9\xEF\x09\xF0\x00\xD4\xE2\x4E\x0F\xFA\x10\x05\x07\xF1\x09\x1E\xE2\xB1\xB1\xCF\x7C\xAB\xC0\x07\x0A\x6C\x6C\x9A\x2E\x1E\xF1\x10\xFC\xCD\xA8\x08\x0A\xF1\x2A\x82\xF2\xFD\x17\xF2\x03\x13\xF1\x63\x5A\xD0\x1F\xFD\xA9\x0B\x0C\xF2\x91\x32\xF3\x26\xFB\xC0",
"\x0C\x0A\xF2\x63\xB6\xF3\xFB\x18\x30\xDD\xED\xA8\x0F\x0A\x6C\x91\xC3\x10\x36\xEA\xB2\x40\xF8\xB6\x4D\x83\x01\x44\xFD\x1F\xBE\x0C\xC7\x49\xF4\xD2\x49\x87\x01\x4D\xF3\x1E\xC2\x0A\x4F\x51\xF1\x10\x1D\xE6\x10\x1B\x05\xF5\x15\x68\xF5\x63\xEA\x10\x1F\x0E\xF5\x49\x2C\xE6\x69\xB9\xF5\x08\x9D\xA9\x23\x04\xF6\x5A\x26\xC6\x48\xF2\xCD\x0B\xC7\x02\x6C\xF1\x10\x2B\x0C\xF3\x02\x1E\x0C\x60\xF9\xE7\x8D\xAD\x02\x73\xF0\x00\x31\x06\xF7\x01\x11\x0D\xFA\x45\xCC\x03\x1F\xCB\x8D\xA3\x03\x3E\xFC\x3D\x12\xD3\x10\x2D\x3D\xA9\x34\x09\xF8\x02\x15\x03\x80\xFE\x26\xD5\xC6\x10\xD7\xCD\xA8\xE6\x17\x03\x93\xF6\x1E\x97\xF3\x10\xCF\xCD\xA8\x39\x00\xF9\xDA\x3D\xF8\x06\x15\xF9\x4D\x8E\x4B\x1A\xD5\xE0\x9D\xAA\x03\xCA\x63\xAA\xE6\x19\xE9\x31\xD9\xFA\x25\x9D\xA8\x3F\x0D\xFA\xFD\x18\x0D\x7C\xC2\xFB\xFB\xDD\xA8\x44\x06\xFB\xE3\x1C\x0D\xB9\xF4\xEE\x06\x19\x04\xBE\xFB\x1F\xB7\xE4\xDD\x09\x1A\xFB\xCE\xD2\x10\x4E\x05\xFC\x49\x25\x0E\x18\xF5\x11\xC2\xF3\x10\x53\x0E\xFC\x5A\x2A\x0E\xD1\xF9\xFC\x15\xD3\x12\x58\x06\xFD\x58\x2F\x0E\xC1\xF6\xDD\x3C\x1D\x05\xDE",
"\xFE\x26\xDF\xE1\xFB\xDB\xFA\x10\x62\x05\xFE\xE6\x1E\xEE\xE8\xF3\xEF\x4D\x87\x06\xEC\xF9\x1E\xFE\xEF\xFE\x1D\xDD\xA9\x6C\x03\xFF\xF5\x11\xFE\xF7\xFF\xBF\xFA\xF9\x19\x03\x05\xEF\x7A\x7D\x12\x73\x10\x76\x03\xFF\x71\x0C\x21\x7E\xFE\x65\x69\x05\x6B\x07\x07\x81\x65\x15\x79\x0A\x84\xDF\x4D\x54\x40\x0E\x00\xA0\x0F\xD0\x71\x80\xA7\x45\x53\x45\x05\x0A\x85\x1A\x4C\x78\x06\x89\x7B\xBD\x6C\x03\xA3\x08\xAA\x7F\x01\xEC\x6E\x41\x0F\x04\x22\x82\x21\x1D\x7B\x0F\x8B\xF0\x06\x08\x25\x05\x7F\x99\x03\xF2\x63\x7A\x16\x8B\xC0\x1B\x05\xF9\x60\x05\x93\x7B\xED\x74\x81\x4E\x52\x0A\x65\x7F\x29\x13\x7C\x72\x7F\x03\x95\x79\x84\x09\x0A\x65\x7E\x2B\x13\x7C\x75\x7A\x08\x8B\x60\x58\x05\xFE\x35\x07\xE4\x6F\x01\x02\x82\x21\x03\x82\x13\x75\xFE\x3C\x07\xE4\x68\x7C\x31\x69\x6B\x09\x09\x72\x68\xF9\x69\x0E\x2F\x1B\x7C\xE9\x0C\x0B\x83\x09\x6F\x6D\xA8\x40\x06\xE8\x77\x24\x62\x82\x20\x22\x69\x2E\x82\x50\x6B\x83\x40\x16\x67\x6C\x86\x92\x2E\x82\x81\x04\xFA\x4D\x41\x30\x07\x83\xC2\x03\xF2\x5A\x7D\xE9\x1B\xCE\x06\x09\x1D\x8E\x72\x67\x85\x18\x13\x7C\x1C\x07",
"\x06\xF0\x83\x18\x8B\x60\xC7\x07\x0C\xA7\x19\x1C\x6F\x06\x92\x6E\x40\x2C\x84\x02\x0D\x0F\xA7\x7C\x69\x2B\xD2\x06\x0A\x16\x91\x83\xD4\x21\xA0\x46\x08\xD8\x1D\xA9\x66\x0C\x32\x00\x83\x97\x0C\x13\x86\x08\x32\x8D\x84\x4A\x06\x22\x8C\x17\xA2\x83\x20\x34\x1D\x4E\x82\x4D\x2B\x86\x41\x18\x1D\xAC\x82\xA0\x2E\x84\xC6\x7B\xC0\x4B\x07\x19\x8C\x06\x93\x79\xF4\x53\x1F\x99\x64\x0B\x9D\x56\x33\x07\x83\xCF\x03\xF2\x6C\x7D\xE9\x10\x0B\xA3\x87\x02\x71\x06\xA7\x86\x5D\x03\x63\x81\x05\x0C\x93\x86\x40\x2B\x86\x02\x0C\x17\x83\x6E\x4B\x25\xC2\x06\x09\x25\x8E\x86\x96\x24\xA7\x42\x08\x4D\x88\x0D\xD4\x27\x0B\x66\x86\x9D\x52\x1A\x09\x86\x78\x1F\x0D\x83\x0B\xF1\x11\x85\x96\x27\x1C\x86\x08\xA3\x6D\x0D\x9D\x26\x3A\x9D\x85\x8D\x53\x1A\x27\x82\x6A\x03\xF9\x3B\x03\x19\x8C\x1E\x09\x0F\x0F\x87\x42\x6B\x07\x06\xD7\x07\xE4\x7C\x01\x67\x84\x1D\x82\x08\x52\x89\x84\x59\x07\x38\x8A\x17\x4D\x63\x20\x02\x89\x23\x4E\x4B\x09\x8B\xF2\x0E\x84\x96\x22\x7A\x06\x09\xAB\x6D\x84\x5A\x07\x19\x9B\x06\xA0\x81\x33\x14\x88\x81\x01\x3F\x68\x84\x35\x3B\x88\x01\x0B\x7D",
"\x1E\x89\x4E\x22\x12\xC1\x79\x13\x5D\x06\x29\x81\x21\x3D\x01\xF2\x75\x12\x9E\x75\xA3\x42\x07\x29\x8E\x20\x02\x02\x96\x85\xDD\x0D\x57\x39\x11\x89\x03\x0F\x08\x34\x89\x86\x6A\x10\x6C\x04\x4E\x82\x08\x4C\x02\xD9\x2D\x3B\x96\x86\xEA\x3C\x09\x3C\x1F\x89\x01\x0A\x0A\x02\x8A\x85\x04\x14\x8D\x73\x11\x56\x07\x48\x88\x00\x1D\x7E\xF9\x46\x10\x4D\x89\x85\x6D\x54\xFB\x01\x2A\x9E\x03\x9D\x81\xB6\x67\x60\xF2\x7B\x0F\x63\x04\x2B\xAC\x77\x24\x45\x00\x26\x36\xEB\x69\x0F\x68\x02\x2C\xBE\x63\x05\x6A\x00\x66\x89\x7F\x0D\x03\x6A\x8A\xEB\x4B\x61\x07\x0E\x16\xE3\x0E\x1C\x11\x8B\x00\x03\xEB\x43\x08\x0A\x05\x17\xFB\x0F\x1D\x18\x8B\x04\x84\x93\x7D\x8B\x24\x1C\x07\x00\x8F\x02\x7E\x00\x83\x8A\x4B\x01\x04\xC3\x8A\xF6\x09\x8C\x96\x06\x04\x78\x8E\x04\x83\x08\x14\x0E\x18\xEE\x13\x22\x11\x8C\x0B\x65\x05\x15\x8C\xF3\x00\x09\x18\x8D\xA7\x52\x01\x9B\x89\x3D\x15\x04\xBC\x8D\x02\x83\x0B\x0D\x15\x8C\x3C\x06\xD4\x2A\x34\x4D\x04\x1A\x8B\x62\x0F\x15\x8C\x43\x02\x35\x8A\x09\x4F\x0D\x1A\x9D\x55\x11\x15\x8C\x4A\x02\x36\x89\x08\x52\x08\x17\xD3\x83\x40\x0C",
"\x02\x95\x89\x0A\x3A\x8C\x83\x05\x04\xDF\x8B\x40\x16\x8A\xBE\x8A\x20\x13\x03\xCA\x88\x05\x43\x8F\x40\x07\x82\xC6\x8A\x20\x08\x8F\x05\x6A\x05\x15\x8F\x17\x0E\x8E\x02\x0B\x16\x25\x7E\x29\x66\x10\x1D\x88\x26\x9D\x24\xDC\x8F\x38\x90\x88\x6A\x2E\x1D\x83\x09\xF5\x1D\x54\x61\x06\x83\x67\x19\xAF\x62\x10\x20\x88\x4F\x02\x03\xD8\x89\x20\x24\x03\xF8\x80\x00\x38\x07\x19\x98\x62\x06\x0D\x7E\x1D\x54\x33\x0A\x1E\xEC\x14\x7E\x83\x08\xEE\x8B\x24\x27\x02\x0F\x68\x06\x74\x8D\x2E\x07\x83\x62\x63\x20\x3A\x8F\x46\x5A\x06\x7D\x8E\xBB\x09\x90\xED\x8B\x81\x6B\x02\x0F\x6C\x06\x74\x8E\x2E\x07\x83\x30\x6F\x3B\xA0\x0D\x39\x3C\xC6\x1D\x92\x87\x83\x79\x29\x08\x44\x91\x37\x86\x67\xB3\x35\x5D\x4C\x66\x91\xFA\x68\x45\xA0\x6B\x4A\x51\x1D\xE0\x5D\xA4\x52\x5F\x2C\x91\x6D\x6A\x90\xBC\x5A\xC1\x3B\x5F\x8C\x89\x42\xAB\x63\x42\x09\x55\xE4\x43\x21\x05\x54\xD9\x23\x66\x3F\x91\x46\x82\x0F\xD5\x0E\x1A\x77\x48\x5E\x43\x5E\x7D\x65\x46\x8A\x7B\x26\x48\xA8\x4E\x09\x93\x94\x09\x25\x5F\x35\x3A\x91\x28\x9A\xA9\x7C\x62\x53\x0D\x37\xEE\x5B\x24\x27\x8A\x97\x0B\x25",
"\xA8\x0B\xA8\x5C\x09\x5F\x92\x4B\xAC\x62\x61\x4A\xD9\x51\x31\xDB\x25\x54\x67\x93\x24\x29\x92\x1E\x94\xB4\x65\x90\xF8\x4E\x93\x4A\x93\x12\x7A\x91\xDB\x62\x27\x8B\x60\x9D\x95\x6C\x76\x93\x4C\xBA\x93\xE9\x10\x27\xC7\x41\xDB\x28\x63\x7F\x92\x4D\xB1\x63\x40\x9C\x26\xCB\x93\x5A\x93\x0B\x7F\x63\xCF\x3A\x8B\x21\x90\xF2\x6C\x63\xA2\x85\x0E\xAE\x0D\xF8\x3B\x33\x71\x6A\x10\x14\x95\x42\x00",
};
vl::glr::DecompressSerializedData(compressed, true, dataSolidRows, dataRows, dataBlock, dataRemain, outputStream);
}
const wchar_t* RuleParserRuleName(vl::vint index)
{
static const wchar_t* results[] = {
L"OptionalBody",
L"Syntax0",
L"Syntax1",
L"Syntax2",
L"Syntax",
L"Assignment",
L"Clause",
L"Rule",
L"File",
};
return results[index];
}
const wchar_t* RuleParserStateLabel(vl::vint index)
{
static const wchar_t* results[] = {
L"[0][OptionalBody] BEGIN ",
L"[1][OptionalBody] END [ENDING]",
L"[2][OptionalBody]\"[\" @ Syntax \"]\"",
L"[3][OptionalBody]\"[\" Syntax \"]\" @",
L"[4][OptionalBody]\"[\" Syntax @ \"]\"",
L"[5][Syntax0] BEGIN ",
L"[6][Syntax0] END [ENDING]",
L"[7][Syntax0]< \"!\" @ ID >",
L"[8][Syntax0]< \"!\" ID @ >",
L"[9][Syntax0]< \"+\" @ OptionalBody >",
L"[10][Syntax0]< \"+\" OptionalBody @ >",
L"[11][Syntax0]< \"-\" @ OptionalBody >",
L"[12][Syntax0]< \"-\" OptionalBody @ >",
L"[13][Syntax0]< \"{\" @ Syntax [ \";\" Syntax ] \"}\" >",
L"[14][Syntax0]< \"{\" Syntax @ [ \";\" Syntax ] \"}\" >",
L"[15][Syntax0]< \"{\" Syntax [ \";\" @ Syntax ] \"}\" >",
L"[16][Syntax0]< \"{\" Syntax [ \";\" Syntax @ ] \"}\" >",
L"[17][Syntax0]< \"{\" Syntax [ \";\" Syntax ] \"}\" @ >",
L"[18][Syntax0]< ID @ [ \":\" ID ] >",
L"[19][Syntax0]< ID [ \":\" @ ID ] >",
L"[20][Syntax0]< ID [ \":\" ID @ ] >",
L"[21][Syntax0]< OptionalBody @ >",
L"[22][Syntax0]< STRING @ >",
L"[23][Syntax0]<< \"(\" !Syntax \")\" @ >>",
L"[24][Syntax0]<< \"(\" !Syntax @ \")\" >>",
L"[25][Syntax0]<< \"(\" @ !Syntax \")\" >>",
L"[26][Syntax1] BEGIN ",
L"[27][Syntax1] END [ENDING]",
L"[28][Syntax1]< Syntax1 @ Syntax0 >",
L"[29][Syntax1]< Syntax1 Syntax0 @ >",
L"[30][Syntax1]<< !Syntax0 @ >>",
L"[31][Syntax2] BEGIN ",
L"[32][Syntax2] END [ENDING]",
L"[33][Syntax2]< Syntax2 \"|\" @ Syntax1 >",
L"[34][Syntax2]< Syntax2 \"|\" Syntax1 @ >",
L"[35][Syntax2]< Syntax2 @ \"|\" Syntax1 >",
L"[36][Syntax2]<< !Syntax1 @ >>",
L"[37][Syntax] BEGIN ",
L"[38][Syntax] END [ENDING]",
L"[39][Syntax]<< !Syntax2 @ >>",
L"[40][Assignment] BEGIN ",
L"[41][Assignment] END [ENDING]",
L"[42][Assignment]< ID \"=\" @ ID >",
L"[43][Assignment]< ID \"=\" ID @ >",
L"[44][Assignment]< ID @ \"=\" ID >",
L"[45][Clause] BEGIN ",
L"[46][Clause] END [ENDING]",
L"[47][Clause]< Syntax \"as\" \"partial\" @ ID [ \"{\" { Assignment ; \",\" } \"}\" ] >",
L"[48][Clause]< Syntax \"as\" \"partial\" ID @ [ \"{\" { Assignment ; \",\" } \"}\" ] >",
L"[49][Clause]< Syntax \"as\" \"partial\" ID [ \"{\" @ { Assignment ; \",\" } \"}\" ] >",
L"[50][Clause]< Syntax \"as\" \"partial\" ID [ \"{\" { Assignment ; \",\" @ } \"}\" ] >",
L"[51][Clause]< Syntax \"as\" \"partial\" ID [ \"{\" { Assignment ; \",\" } \"}\" @ ] >",
L"[52][Clause]< Syntax \"as\" \"partial\" ID [ \"{\" { Assignment @ ; \",\" } \"}\" ] >",
L"[53][Clause]< Syntax \"as\" @ \"partial\" ID [ \"{\" { Assignment ; \",\" } \"}\" ] >",
L"[54][Clause]< Syntax \"as\" @ ID [ \"{\" { Assignment ; \",\" } \"}\" ] >",
L"[55][Clause]< Syntax \"as\" ID @ [ \"{\" { Assignment ; \",\" } \"}\" ] >",
L"[56][Clause]< Syntax \"as\" ID [ \"{\" @ { Assignment ; \",\" } \"}\" ] >",
L"[57][Clause]< Syntax \"as\" ID [ \"{\" { Assignment ; \",\" @ } \"}\" ] >",
L"[58][Clause]< Syntax \"as\" ID [ \"{\" { Assignment ; \",\" } \"}\" @ ] >",
L"[59][Clause]< Syntax \"as\" ID [ \"{\" { Assignment @ ; \",\" } \"}\" ] >",
L"[60][Clause]< Syntax @ \"as\" \"partial\" ID [ \"{\" { Assignment ; \",\" } \"}\" ] >",
L"[61][Clause]< Syntax @ \"as\" ID [ \"{\" { Assignment ; \",\" } \"}\" ] >",
L"[62][Clause]< Syntax @ [ \"{\" { Assignment ; \",\" } \"}\" ] >",
L"[63][Clause]< Syntax [ \"{\" @ { Assignment ; \",\" } \"}\" ] >",
L"[64][Clause]< Syntax [ \"{\" { Assignment ; \",\" @ } \"}\" ] >",
L"[65][Clause]< Syntax [ \"{\" { Assignment ; \",\" } \"}\" @ ] >",
L"[66][Clause]< Syntax [ \"{\" { Assignment @ ; \",\" } \"}\" ] >",
L"[67][Rule] BEGIN ",
L"[68][Rule] END [ENDING]",
L"[69][Rule]< ID @ { \"::=\" Clause } \";\" >",
L"[70][Rule]< ID { \"::=\" @ Clause } \";\" >",
L"[71][Rule]< ID { \"::=\" Clause @ } \";\" >",
L"[72][Rule]< ID { \"::=\" Clause } \";\" @ >",
L"[73][File] BEGIN ",
L"[74][File] END [ENDING]",
L"[75][File]< Rule @ { Rule } >",
L"[76][File]< Rule { Rule @ } >",
};
return results[index];
}
RuleParser::RuleParser()
: vl::glr::ParserBase<ParserGenTokens, RuleParserStates, ParserGenAstInsReceiver>(&ParserGenTokenDeleter, &ParserGenLexerData, &ParserGenRuleParserData)
{
};
vl::vint32_t RuleParser::FindCommonBaseClass(vl::vint32_t class1, vl::vint32_t class2) const
{
return -1;
};
vl::Ptr<vl::glr::parsergen::GlrSyntaxFile> RuleParser::ParseFile(const vl::WString& input, vl::vint codeIndex) const
{
return ParseWithString<vl::glr::parsergen::GlrSyntaxFile, RuleParserStates::File>(input, this, codeIndex);
};
vl::Ptr<vl::glr::parsergen::GlrSyntaxFile> RuleParser::ParseFile(vl::collections::List<vl::regex::RegexToken>& tokens, vl::vint codeIndex) const
{
return ParseWithTokens<vl::glr::parsergen::GlrSyntaxFile, RuleParserStates::File>(tokens, this, codeIndex);
};
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEAST.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:TypeAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
/***********************************************************************
Visitor Pattern Implementation
***********************************************************************/
void GlrEnum::Accept(GlrType::IVisitor* visitor)
{
visitor->Visit(this);
}
void GlrClass::Accept(GlrType::IVisitor* visitor)
{
visitor->Visit(this);
}
}
}
}
namespace vl
{
namespace reflection
{
namespace description
{
#ifndef VCZH_DEBUG_NO_REFLECTION
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrType, glr::parsergen::GlrType)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrType::IVisitor, glr::parsergen::GlrType::IVisitor)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrEnumItem, glr::parsergen::GlrEnumItem)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrEnum, glr::parsergen::GlrEnum)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrPropType, glr::parsergen::GlrPropType)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrClassProp, glr::parsergen::GlrClassProp)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrClassAmbiguity, glr::parsergen::GlrClassAmbiguity)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrClass, glr::parsergen::GlrClass)
IMPL_TYPE_INFO_RENAME(vl::glr::parsergen::GlrAstFile, glr::parsergen::GlrAstFile)
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrType)
CLASS_MEMBER_BASE(vl::glr::ParsingAstBase)
CLASS_MEMBER_FIELD(name)
END_CLASS_MEMBER(vl::glr::parsergen::GlrType)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrEnumItem)
CLASS_MEMBER_BASE(vl::glr::ParsingAstBase)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrEnumItem>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(name)
END_CLASS_MEMBER(vl::glr::parsergen::GlrEnumItem)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrEnum)
CLASS_MEMBER_BASE(vl::glr::parsergen::GlrType)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrEnum>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(items)
END_CLASS_MEMBER(vl::glr::parsergen::GlrEnum)
BEGIN_ENUM_ITEM(vl::glr::parsergen::GlrPropType)
ENUM_ITEM_NAMESPACE(vl::glr::parsergen::GlrPropType)
ENUM_NAMESPACE_ITEM(Token)
ENUM_NAMESPACE_ITEM(Type)
ENUM_NAMESPACE_ITEM(Array)
END_ENUM_ITEM(vl::glr::parsergen::GlrPropType)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrClassProp)
CLASS_MEMBER_BASE(vl::glr::ParsingAstBase)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrClassProp>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(name)
CLASS_MEMBER_FIELD(propType)
CLASS_MEMBER_FIELD(propTypeName)
END_CLASS_MEMBER(vl::glr::parsergen::GlrClassProp)
BEGIN_ENUM_ITEM(vl::glr::parsergen::GlrClassAmbiguity)
ENUM_ITEM_NAMESPACE(vl::glr::parsergen::GlrClassAmbiguity)
ENUM_NAMESPACE_ITEM(No)
ENUM_NAMESPACE_ITEM(Yes)
END_ENUM_ITEM(vl::glr::parsergen::GlrClassAmbiguity)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrClass)
CLASS_MEMBER_BASE(vl::glr::parsergen::GlrType)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrClass>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(baseClass)
CLASS_MEMBER_FIELD(ambiguity)
CLASS_MEMBER_FIELD(props)
END_CLASS_MEMBER(vl::glr::parsergen::GlrClass)
BEGIN_CLASS_MEMBER(vl::glr::parsergen::GlrAstFile)
CLASS_MEMBER_BASE(vl::glr::ParsingAstBase)
CLASS_MEMBER_CONSTRUCTOR(vl::Ptr<vl::glr::parsergen::GlrAstFile>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(types)
END_CLASS_MEMBER(vl::glr::parsergen::GlrAstFile)
BEGIN_INTERFACE_MEMBER(vl::glr::parsergen::GlrType::IVisitor)
CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::glr::parsergen::GlrType::IVisitor::*)(vl::glr::parsergen::GlrEnum* node))
CLASS_MEMBER_METHOD_OVERLOAD(Visit, {L"node"}, void(vl::glr::parsergen::GlrType::IVisitor::*)(vl::glr::parsergen::GlrClass* node))
END_INTERFACE_MEMBER(vl::glr::parsergen::GlrType)
#endif
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
class ParserGenTypeAstTypeLoader : public vl::Object, public ITypeLoader
{
public:
void Load(ITypeManager* manager)
{
ADD_TYPE_INFO(vl::glr::parsergen::GlrType)
ADD_TYPE_INFO(vl::glr::parsergen::GlrType::IVisitor)
ADD_TYPE_INFO(vl::glr::parsergen::GlrEnumItem)
ADD_TYPE_INFO(vl::glr::parsergen::GlrEnum)
ADD_TYPE_INFO(vl::glr::parsergen::GlrPropType)
ADD_TYPE_INFO(vl::glr::parsergen::GlrClassProp)
ADD_TYPE_INFO(vl::glr::parsergen::GlrClassAmbiguity)
ADD_TYPE_INFO(vl::glr::parsergen::GlrClass)
ADD_TYPE_INFO(vl::glr::parsergen::GlrAstFile)
}
void Unload(ITypeManager* manager)
{
}
};
#endif
#endif
bool ParserGenTypeAstLoadTypes()
{
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
if (auto manager = GetGlobalTypeManager())
{
Ptr<ITypeLoader> loader = new ParserGenTypeAstTypeLoader;
return manager->AddTypeLoader(loader);
}
#endif
return false;
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEAST_BUILDER.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:TypeAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
namespace builder
{
/***********************************************************************
MakeAstFile
***********************************************************************/
MakeAstFile& MakeAstFile::types(const vl::Ptr<GlrType>& value)
{
node->types.Add(value);
return *this;
}
/***********************************************************************
MakeClass
***********************************************************************/
MakeClass& MakeClass::ambiguity(GlrClassAmbiguity value)
{
node->ambiguity = value;
return *this;
}
MakeClass& MakeClass::baseClass(const vl::WString& value)
{
node->baseClass.value = value;
return *this;
}
MakeClass& MakeClass::props(const vl::Ptr<GlrClassProp>& value)
{
node->props.Add(value);
return *this;
}
MakeClass& MakeClass::name(const vl::WString& value)
{
node->name.value = value;
return *this;
}
/***********************************************************************
MakeClassProp
***********************************************************************/
MakeClassProp& MakeClassProp::name(const vl::WString& value)
{
node->name.value = value;
return *this;
}
MakeClassProp& MakeClassProp::propType(GlrPropType value)
{
node->propType = value;
return *this;
}
MakeClassProp& MakeClassProp::propTypeName(const vl::WString& value)
{
node->propTypeName.value = value;
return *this;
}
/***********************************************************************
MakeEnum
***********************************************************************/
MakeEnum& MakeEnum::items(const vl::Ptr<GlrEnumItem>& value)
{
node->items.Add(value);
return *this;
}
MakeEnum& MakeEnum::name(const vl::WString& value)
{
node->name.value = value;
return *this;
}
/***********************************************************************
MakeEnumItem
***********************************************************************/
MakeEnumItem& MakeEnumItem::name(const vl::WString& value)
{
node->name.value = value;
return *this;
}
/***********************************************************************
MakeType
***********************************************************************/
MakeType& MakeType::name(const vl::WString& value)
{
node->name.value = value;
return *this;
}
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEAST_COPY.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:TypeAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
namespace copy_visitor
{
void TypeAstVisitor::CopyFields(GlrAstFile* from, GlrAstFile* to)
{
for (auto&& listItem : from->types)
{
to->types.Add(CopyNode(listItem.Obj()));
}
}
void TypeAstVisitor::CopyFields(GlrClass* from, GlrClass* to)
{
CopyFields(static_cast<GlrType*>(from), static_cast<GlrType*>(to));
to->ambiguity = from->ambiguity;
to->baseClass = from->baseClass;
for (auto&& listItem : from->props)
{
to->props.Add(CopyNode(listItem.Obj()));
}
}
void TypeAstVisitor::CopyFields(GlrClassProp* from, GlrClassProp* to)
{
to->name = from->name;
to->propType = from->propType;
to->propTypeName = from->propTypeName;
}
void TypeAstVisitor::CopyFields(GlrEnum* from, GlrEnum* to)
{
CopyFields(static_cast<GlrType*>(from), static_cast<GlrType*>(to));
for (auto&& listItem : from->items)
{
to->items.Add(CopyNode(listItem.Obj()));
}
}
void TypeAstVisitor::CopyFields(GlrEnumItem* from, GlrEnumItem* to)
{
to->name = from->name;
}
void TypeAstVisitor::CopyFields(GlrType* from, GlrType* to)
{
to->name = from->name;
}
void TypeAstVisitor::Visit(GlrEnumItem* node)
{
auto newNode = vl::MakePtr<GlrEnumItem>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void TypeAstVisitor::Visit(GlrClassProp* node)
{
auto newNode = vl::MakePtr<GlrClassProp>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void TypeAstVisitor::Visit(GlrAstFile* node)
{
auto newNode = vl::MakePtr<GlrAstFile>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void TypeAstVisitor::Visit(GlrEnum* node)
{
auto newNode = vl::MakePtr<GlrEnum>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
void TypeAstVisitor::Visit(GlrClass* node)
{
auto newNode = vl::MakePtr<GlrClass>();
CopyFields(node, newNode.Obj());
this->result = newNode;
}
vl::Ptr<GlrType> TypeAstVisitor::CopyNode(GlrType* node)
{
if (!node) return nullptr;
node->Accept(static_cast<GlrType::IVisitor*>(this));
return this->result.Cast<GlrType>();
}
vl::Ptr<GlrEnumItem> TypeAstVisitor::CopyNode(GlrEnumItem* node)
{
if (!node) return nullptr;
Visit(node);
return this->result.Cast<GlrEnumItem>();
}
vl::Ptr<GlrClassProp> TypeAstVisitor::CopyNode(GlrClassProp* node)
{
if (!node) return nullptr;
Visit(node);
return this->result.Cast<GlrClassProp>();
}
vl::Ptr<GlrAstFile> TypeAstVisitor::CopyNode(GlrAstFile* node)
{
if (!node) return nullptr;
Visit(node);
return this->result.Cast<GlrAstFile>();
}
vl::Ptr<GlrClass> TypeAstVisitor::CopyNode(GlrClass* node)
{
if (!node) return nullptr;
return CopyNode(static_cast<GlrType*>(node)).Cast<GlrClass>();
}
vl::Ptr<GlrEnum> TypeAstVisitor::CopyNode(GlrEnum* node)
{
if (!node) return nullptr;
return CopyNode(static_cast<GlrType*>(node)).Cast<GlrEnum>();
}
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEAST_EMPTY.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:TypeAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
namespace empty_visitor
{
/***********************************************************************
TypeVisitor
***********************************************************************/
// Visitor Members -----------------------------------
void TypeVisitor::Visit(GlrEnum* node)
{
}
void TypeVisitor::Visit(GlrClass* node)
{
}
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEAST_JSON.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:TypeAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
namespace json_visitor
{
void TypeAstVisitor::PrintFields(GlrAstFile* node)
{
BeginField(L"types");
BeginArray();
for (auto&& listItem : node->types)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
}
void TypeAstVisitor::PrintFields(GlrClass* node)
{
BeginField(L"ambiguity");
switch (node->ambiguity)
{
case vl::glr::parsergen::GlrClassAmbiguity::No:
WriteString(L"No");
break;
case vl::glr::parsergen::GlrClassAmbiguity::Yes:
WriteString(L"Yes");
break;
default:
WriteNull();
}
EndField();
BeginField(L"baseClass");
WriteToken(node->baseClass);
EndField();
BeginField(L"props");
BeginArray();
for (auto&& listItem : node->props)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
}
void TypeAstVisitor::PrintFields(GlrClassProp* node)
{
BeginField(L"name");
WriteToken(node->name);
EndField();
BeginField(L"propType");
switch (node->propType)
{
case vl::glr::parsergen::GlrPropType::Array:
WriteString(L"Array");
break;
case vl::glr::parsergen::GlrPropType::Token:
WriteString(L"Token");
break;
case vl::glr::parsergen::GlrPropType::Type:
WriteString(L"Type");
break;
default:
WriteNull();
}
EndField();
BeginField(L"propTypeName");
WriteToken(node->propTypeName);
EndField();
}
void TypeAstVisitor::PrintFields(GlrEnum* node)
{
BeginField(L"items");
BeginArray();
for (auto&& listItem : node->items)
{
BeginArrayItem();
Print(listItem.Obj());
EndArrayItem();
}
EndArray();
EndField();
}
void TypeAstVisitor::PrintFields(GlrEnumItem* node)
{
BeginField(L"name");
WriteToken(node->name);
EndField();
}
void TypeAstVisitor::PrintFields(GlrType* node)
{
BeginField(L"name");
WriteToken(node->name);
EndField();
}
void TypeAstVisitor::Visit(GlrEnum* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"Enum", node);
PrintFields(static_cast<GlrType*>(node));
PrintFields(static_cast<GlrEnum*>(node));
EndObject();
}
void TypeAstVisitor::Visit(GlrClass* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"Class", node);
PrintFields(static_cast<GlrType*>(node));
PrintFields(static_cast<GlrClass*>(node));
EndObject();
}
TypeAstVisitor::TypeAstVisitor(vl::stream::StreamWriter& _writer)
: vl::glr::JsonVisitorBase(_writer)
{
}
void TypeAstVisitor::Print(GlrType* node)
{
if (!node)
{
WriteNull();
return;
}
node->Accept(static_cast<GlrType::IVisitor*>(this));
}
void TypeAstVisitor::Print(GlrEnumItem* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"EnumItem", node);
PrintFields(static_cast<GlrEnumItem*>(node));
EndObject();
}
void TypeAstVisitor::Print(GlrClassProp* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"ClassProp", node);
PrintFields(static_cast<GlrClassProp*>(node));
EndObject();
}
void TypeAstVisitor::Print(GlrAstFile* node)
{
if (!node)
{
WriteNull();
return;
}
BeginObject();
WriteType(L"AstFile", node);
PrintFields(static_cast<GlrAstFile*>(node));
EndObject();
}
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEAST_TRAVERSE.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:TypeAst
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
namespace traverse_visitor
{
void TypeAstVisitor::Traverse(vl::glr::ParsingToken& token) {}
void TypeAstVisitor::Traverse(vl::glr::ParsingAstBase* node) {}
void TypeAstVisitor::Traverse(GlrAstFile* node) {}
void TypeAstVisitor::Traverse(GlrClass* node) {}
void TypeAstVisitor::Traverse(GlrClassProp* node) {}
void TypeAstVisitor::Traverse(GlrEnum* node) {}
void TypeAstVisitor::Traverse(GlrEnumItem* node) {}
void TypeAstVisitor::Traverse(GlrType* node) {}
void TypeAstVisitor::Finishing(vl::glr::ParsingAstBase* node) {}
void TypeAstVisitor::Finishing(GlrAstFile* node) {}
void TypeAstVisitor::Finishing(GlrClass* node) {}
void TypeAstVisitor::Finishing(GlrClassProp* node) {}
void TypeAstVisitor::Finishing(GlrEnum* node) {}
void TypeAstVisitor::Finishing(GlrEnumItem* node) {}
void TypeAstVisitor::Finishing(GlrType* node) {}
void TypeAstVisitor::Visit(GlrEnum* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrType*>(node));
Traverse(static_cast<GlrEnum*>(node));
for (auto&& listItem : node->items)
{
InspectInto(listItem.Obj());
}
Traverse(node->name);
Finishing(static_cast<GlrEnum*>(node));
Finishing(static_cast<GlrType*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void TypeAstVisitor::Visit(GlrClass* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrType*>(node));
Traverse(static_cast<GlrClass*>(node));
Traverse(node->baseClass);
for (auto&& listItem : node->props)
{
InspectInto(listItem.Obj());
}
Traverse(node->name);
Finishing(static_cast<GlrClass*>(node));
Finishing(static_cast<GlrType*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void TypeAstVisitor::InspectInto(GlrType* node)
{
if (!node) return;
node->Accept(static_cast<GlrType::IVisitor*>(this));
}
void TypeAstVisitor::InspectInto(GlrEnumItem* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrEnumItem*>(node));
Traverse(node->name);
Finishing(static_cast<GlrEnumItem*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void TypeAstVisitor::InspectInto(GlrClassProp* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrClassProp*>(node));
Traverse(node->name);
Traverse(node->propTypeName);
Finishing(static_cast<GlrClassProp*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
void TypeAstVisitor::InspectInto(GlrAstFile* node)
{
if (!node) return;
Traverse(static_cast<vl::glr::ParsingAstBase*>(node));
Traverse(static_cast<GlrAstFile*>(node));
for (auto&& listItem : node->types)
{
InspectInto(listItem.Obj());
}
Finishing(static_cast<GlrAstFile*>(node));
Finishing(static_cast<vl::glr::ParsingAstBase*>(node));
}
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGENTYPEPARSER.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:ParserGen
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
void ParserGenTypeParserData(vl::stream::IStream& outputStream)
{
static const vl::vint dataLength = 2267; // 29656 bytes before compressing
static const vl::vint dataBlock = 256;
static const vl::vint dataRemain = 219;
static const vl::vint dataSolidRows = 8;
static const vl::vint dataRows = 9;
static const char* compressed[] = {
"\xD8\x73\x00\x00\xD3\x08\x00\x00\x1A\x00\x01\x82\x80\x08\x03\x82\x81\x82\x06\x89\x82\x84\x0A\x83\x06\x84\x09\x0A\x99\x0A\x81\x1A\x80\x16\x84\x16\x0A\xC0\x05\x09\x8F\x7D\x8E\x8F\x8E\x0A\x80\x1F\x9F\x81\x93\x92\x8F\x92\x26\xFF\x68\x86\x9B\x93\x91\x96\x92\x0A\xA9\xAA\x91\x99\x97\x97\x92\x9A\x2C\xB8\xAE\x9A\x90\x9C\x8D\x9A\x9E\x37\xBE\xB9\x82\xAB\x9C\xA1\x9E\x83\x32\xB6\xA0\x80\xAB\xA6\xA1\xA0\xA4\x3F\xCE\x8D\xA1\x96\x81\x00\xA7\x99\x52\xD8\x90\xA3\xAB\xAD\xA1\xAF\xA3\x03\xC9\x97\xAA\xAA\xA9\xB1\xA9\xAF\x4F\xE6\x9C\xAA\xBE\xAC\xB4\xB0\x81\x62\xD9\xA4\xB3\xB3\xB5\xBA\xB8\xBB\x68\xD3\xAE\xA9\xB0\xBF\xB3\xBC\xBD\x7D\xEB\x81\xCD\xB3\xC7\xB5\x81\xB8\x79\xE5\x85\xDC\xB1\x86\xA9\x84\xC7\x89\xF4\xB7\xB3\xC1\xC8\xBF\xBE\xC5\x87\xFE\x8B\xC0\xC9\xCA\xC1\xCE\xC2\x9F\x86\xE2\x9A\xC1\xD4\xC7\xD0\xCF\xA7\xA0\xE9\xC2\xD8\xC7\xCA\xC9\xCA\x94\xAE\xD6\xDB\xC8\xCB\xD6\xD3\xD6\xB4\xAF\xF2\xD1\xD9\xDB\xD9\xD2\xCE\xB6\xC0\xF8\xDF\xD5\xDB\xE1\xE1\xE2\xA4\xC7\xFA\xC2\x82\x02\x84\xC9\xDD\xB0\xD1\xD0\xF3\xED\xDC\xDC\xE3\xE5\xD7\xBE\xCA\xFA",
"\xE6\xE5\xED\xE5\x01\xCE\xDC\xC9\xFE\xE8\xD4\xF2\xD4\xF3\xAC\xE3\xEA\xE5\xFB\xF7\xF1\xF7\xF4\xEC\xF1\xEE\xF2\xF0\xFB\xFA\xFB\xFA\xF8\xB7\xEF\xFA\xF4\xFC\xFF\xFA\xFF\xF9\x42\x7B\x7E\x80\xFD\x44\x8F\x7E\x81\x01\x88\x75\x82\x82\x07\x8C\x89\x80\x76\xDB\x56\x71\x86\x74\xD5\x54\x89\x76\x84\xE8\x40\x8A\x84\x82\x1B\x8E\x8D\x84\x84\x19\x9C\x82\x8A\x87\x23\xA0\x83\x80\x89\xB5\x4C\x4F\x62\x78\x0B\xA6\x8D\x88\x8B\x0D\xAE\x81\x8C\x8C\x0F\xB4\x86\x6B\x46\x2B\x98\x87\x8A\x8C\x35\xBA\x8F\x89\x42\x06\x21\x7E\x8F\x8C\x43\xBD\x86\x87\x84\xD4\x57\x87\x91\x88\x28\xBC\x8F\x86\x42\x07\x02\x9B\x93\x8E\x36\xA5\x85\x95\x93\x0A\x48\x45\x57\x95\x10\x89\x02\x95\x92\x48\x95\x80\x98\x93\x4E\x96\x95\x93\x93\x67\xA6\x93\x97\x8F\x6B\x84\x9D\x9A\x91\x63\x94\x99\x98\x96\x73\xA5\x94\x9F\x9B\x68\xB8\x90\x72\x02\x5F\xA2\x9E\x9E\x92\x71\xAC\x91\xA2\x9B\x83\xB0\x9F\x9D\x98\x80\x87\xA4\x98\x97\x0D\x7D\x99\xA3\xA3\x88\x91\xAB\xA1\x9D\x8C\x94\xA6\xA6\x9E\x77\x83\x4C\x02\x42\xCD\x57\xA5\xA1\x9E\x9F\xAA\x91\xA9\xA6\x8A\xB2\x98\xA6\x9D\xA8\x95\xA7\xAA\xAA",
"\xA3\xA9\xA2\x86\x03\x8E\x92\xA6\xA9\xAB\xAC\xA5\xA2\xA2\xAD\x84\xB8\xA6\xA0\xA4\x93\xAB\xAE\xA6\xAE\xA0\x87\xAF\x01\xAC\xBD\xB4\xAF\xAC\xAF\xB3\x80\xB2\xAA\xB2\xA4\x88\xB7\xAE\xB3\xB9\x90\xBB\xAE\xAC\xCF\x94\xB1\xB6\xB5\xD3\x85\xBC\xB2\xAB\x06\x50\x04\xB1\xB2\xD2\x81\xB1\xBB\xB2\xE3\x8D\xB8\xB6\xB8\x91\x91\x0F\xB5\xB5\xDA\xA5\xBC\xB6\xB1\xBE\xB1\xB0\xBF\xBC\xDB\xB5\xAE\xBA\xBD\xE7\xA4\xB9\xBE\xB9\xED\xBB\xBF\xBA\x40\x10\x79\x82\xBD\xBD\xC7\xBE\xB8\xBD\xBF\x08\xE0\xB6\xC1\xC1\xC6\x53\x0B\xBB\xB5\x09\xEC\xBA\xC1\xC4\x10\xD3\xC6\xC6\xC4\x18\xD5\xC9\xC5\xB6\x17\xDA\xCE\xC4\xC7\x1B\xE8\xB4\xC4\xC8\x1F\xE2\xCD\xC4\xC9\x28\xE6\xC1\xCA\xBE\x23\xEA\xC5\xC8\xCB\x27\xEE\xC9\xCA\xBE\x14\x0F\xC3\xCC\xBF\x31\xF0\xC8\x69\x05\x36\xF2\xCE\xCE\xCE\x2F\xF8\xCB\xCA\xD0\x41\xE1\x46\x04\xA7\x07\xC9\x78\x05\xCF\x40\xF7\xCF\xBF\xBD\x0C\xF9\xC4\xD2\xD3\x49\xC3\xDF\xD3\xC2\x03\xD0\xD9\xD4\xD6\xF4\x9A\xDD\xD4\xD7\x87\x92\x42\xC3\xD7\x2D\xCD\xDF\xCF\xD4\x67\xD7\xD5\xD8\xDA\x66\xED\xDC\xD9\x6D\x00\x63\xD4\xC3\xD6\x6B\xEA\xD2\xD6\xDD\x56",
"\xD5\xD5\xD2\xDE\x54\xD1\xD9\xDE\xDF\xAA\x5B\x0C\xD3\xDB\x78\xFB\xD0\xE1\xDF\x74\xF7\xDC\xDD\xDA\x8B\xEE\xD5\xE0\xE2\x64\xCA\xE7\xE0\xE3\x12\x9C\x03\xE0\x84\x1D\x17\xED\xE0\xE1\x9B\xCF\xE4\xE5\xE2\x7F\xE0\xE6\xE2\xE8\x90\xF3\xD1\xE5\xB5\x1E\x1A\xE3\xE6\xE3\x9D\xED\xEB\xEA\xB9\x1F\x2A\xE4\xEB\xE7\xA7\xE3\xE5\xED\xE9\x5E\xC7\xA0\x0A\xEC\xB7\xF4\xE6\xEA\x40\x14\x72\xD9\xEF\xF0\x60\xC4\xF5\xDE\xEB\xB3\xFA\xB2\x08\xEF\xBF\xC6\xF2\xE6\x41\x23\x0C\xFE\xF1\xE8\xBD\xEC\xE5\xC0\x09\xD2\xC5\xFA\xF7\xF1\xAF\xDE\xE6\xF5\xF2\x9C\xDD\xF8\xF3\xD7\x25\x31\xA6\x09\xF6\xDC\xE0\xFE\xF5\xF8\xEA\xE3\xFD\xF3\xF6\xCF\xD5\xFC\xFA\xFC\xEB\xF5\xFE\xFB\xF4\xB6\xEF\xF9\xF8\xFD\xF7\xF0\xF4\xF6\xFE\xF1\x60\x83\xFF\x78\x72\x35\x13\x28\x7A\x61\x16\x22\x7A\xFF\x79\x74\x80\xDF\x4D\x87\x7B\xFC\x62\x7E\x04\xED\x73\x83\x81\x29\x07\x80\x03\x8B\x80\xEE\x1A\x8E\x80\x0E\x90\x82\x80\x0C\x9E\x83\xFC\x20\x8B\x83\xFD\x64\x85\x83\x26\x8F\x81\x6D\x2A\x08\x83\x6B\x6B\x05\x85\x25\x81\x82\x0A\xF6\x75\x83\x13\x9F\x83\x86\xFD\x7D\x5C\x46\x0A\x8D\x05\x58\x6E\x00",
"\x86\x28\x92\x86\x08\xB4\x84\x83\x22\x91\x86\x88\x36\x83\x84\x0E\xB5\x8B\x88\x24\x8D\x8F\x88\x50\x82\x23\x0B\x40\x87\x87\x21\xB9\x82\x88\x29\x96\x88\x13\xDA\x8B\x6A\x18\x14\x8A\x89\x5C\x91\x8B\x13\xC9\x84\x88\x31\xA1\x8C\x8C\xDA\x31\x05\xAC\x32\x01\x57\x19\x1F\x8D\x8C\x68\x9B\x89\x16\xF3\x88\x8B\x3A\x99\x84\x8E\x77\x96\x8D\x08\xF8\x8B\x8E\x3D\xB1\x80\x35\x34\x19\x79\x0D\x31\x56\x07\x58\x77\x07\x8D\x57\x99\x8E\x22\xFD\x8B\x91\x3F\xA1\x80\x07\xD9\x79\x05\xAC\x3A\x01\x57\x1D\x08\x92\x8E\x7E\x81\x89\x23\x9A\x9C\x91\x10\x9A\x08\x69\x09\x3A\x4B\xA8\x32\x22\x94\x81\x03\x59\x2B\x41\x59\x2A\x4C\x1D\x56\x21\x28\x73\x4C\x94\x13\x37\x28\x2B\x83\x25\x95\x72\x70\x91\x21\xA7\x89\x33\x2C\x87\x27\x4B\x5B\x86\x21\x97\x97\x29\x95\x62\x4C\x4E\x97\x81\x3C\x4F\x95\x29\x35\x94\x00\x47\x99\x31\xE7\x14\x2C\x38\xCA\x9E\x49\x56\x4E\x91\x21\x5D\x90\x9A\x21\xD2\x8D\x9B\xE0\x51\x92\x96\x85\x2A\x40\x53\xC5\x9C\x94\x32\xA6\x2A\x98\x66\xA3\x91\x99\x0A\x26\x9C\x6D\x42\x97\x32\x62\xA8\x99\x21\xC1\x60\x9F\x3B\x86\x2C\x9C\xDA\x16\x98\x00\xDF\x97",
"\x33\x3D\xF9\x96\x9E\x85\x20\x39\x2B\xF7\x9F\x9E\x3C\xE4\x91\x97\x69\x9B\x9A\x21\x38\x49\x31\x3D\xC4\x3E\x9C\x82\xB0\x9F\x2A\xD4\x94\x29\x38\x81\x29\xA1\x60\x97\x2A\x26\xFC\x8C\xA1\x4A\x01\xA7\x2B\x8C\x87\x3B\x95\xFE\x9D\xA3\x45\x9B\xA0\x4B\xAB\x0B\xA7\xA3\x29\x27\xA6\x4C\x20\xA9\x21\x7B\x98\xA3\xA4\x26\x3C\xA0\x40\xA0\x99\x30\x8F\xAB\xA4\xA4\x09\x22\xA2\x3E\xB4\xA7\x32\x9B\xB7\xA3\x24\xF7\x8E\x96\x42\xB0\xA3\x24\x9F\xBF\xA6\x23\x32\xB5\xA4\x51\x9F\x29\xA9\x9E\x8B\xA8\xA9\x25\xA8\x97\x53\x9D\x26\xA9\xA3\xBF\x1D\xA9\xB4\x35\xAB\x51\xD8\xA4\x38\xAD\xBF\xA1\xA8\x57\x2A\x98\xAC\x59\x22\xAD\xB0\x91\xA9\x31\xCA\x82\xAB\x65\x15\xA4\x36\x99\x2C\xAA\xA3\x0E\xA6\x22\x57\x9D\x2A\x99\xB9\xBF\x1D\xAE\x57\x29\x77\x33\x83\x21\xA3\x7B\xBE\xA9\xA4\x09\x3E\xA3\x5B\x80\x07\xA4\xB5\x82\x26\xB0\x01\x3C\x99\x42\x08\xB0\x01\x6C\x83\x24\xB1\x8E\xA2\x9E\x41\x6A\x91\x20\xC6\x94\xB0\x00\x96\xB9\x49\xA3\x0B\xBB\xB3\x56\x9D\xB4\x96\x0A\x3B\x53\x5E\x92\xB3\xB5\x28\x31\x51\x24\xCA\x81\x26\x14\x31\x57\x9F\x0B\x23\xB7\x50\x3A\xA2\x21\xEC\x2F",
"\xB0\x01\x29\x31\x51\xB6\x01\x33\xB7\x6B\xD4\x01\x56\x8F\x98\x7C\xB6\xC6\x3E\xA2\x01\xC0\xB9\x39\xC1\xAF\x84\xB6\x55\x11\x55\x44\xAC\x84\xB6\x2B\x31\x57\xA4\x3F\x94\xB7\x15\x4F\xBA\x21\x29\xB4\xB0\x0B\xD4\xA9\x22\x75\xAF\xB9\x0B\x58\x7C\x04\xB6\x00\x18\xB4\x78\x8D\x3C\xB4\xED\x37\x99\xA2\x21\x22\xBD\x44\xFD\x52\xBD\x7B\xB0\x89\x20\x1E\xA7\xA5\x48\x1E\xAB\xBC\x85\x67\xA7\xB2\x10\x43\xB2\x4B\xC9\x30\xB2\xF0\x99\x8C\xB1\xE2\xA1\x24\x63\x91\xAA\x98\xF7\xB1\x52\xB1\xAF\xB9\x8A\x32\x81\xC9\x9D\x58\x4E\x25\xA5\xCA\xB8\x98\x42\xE0\xBD\x01\x4B\x93\xB7\xAC\xA3\xB9\x8B\x83\x86\x25\xC2\xE2\x99\x83\xC3\x03\x3E\x5A\x87\xAA\x33\xAC\x83\x3B\xB8\x35\x20\xC2\x22\xBA\x23\xC2\x34\x11\xE6\xC2\x3B\x1D\xC6\x22\x68\xAF\xB1\x61\x17\xC5\x65\xC4\x9A\x40\xBD\xCD\x10\xC5\x60\x60\x82\x20\xC7\x7B\xB9\x8A\x8B\xB9\xC4\xB7\xA3\x7C\xC3\x6B\x2B\xDF\x96\x7F\xC2\x85\xC7\x81\x3B\xC7\xB5\x4B\x6A\x81\xBF\x4F\xC3\x21\x28\xC9\xC1\x39\x62\x76\xC7\x91\x3C\x69\x21\x18\xD9\xC2\x61\xE7\xAA\x20\x97\xDD\x5B\xC8\xD4\x02\x77\xC8\x03\x2A\xBE\x98\x8A\x29\xC9\x2F",
"\xE8\x31\x73\x68\xCB\x21\xAC\x46\xC6\x20\x87\x74\xB2\xB7\x7C\xB8\x5E\x6B\x89\x24\xCE\x37\xE1\x86\xCA\x03\x23\xCE\x9F\x9B\x89\xCB\x81\x27\xCF\xCA\xA8\x3B\x75\x9C\x90\x57\xD1\x81\x3A\xA8\xD1\x21\x8D\xD2\x40\x16\x7C\xC5\x0E\x94\xD6\x20\x70\xD0\xD2\x68\x4B\x7B\xD1\x48\x59\xD6\xD1\x65\xC1\x87\xA3\xCE\xC0\xBD\xDF\x9B\x4A\x42\x83\xB1\xA3\xA8\x82\x2A\xD0\x4D\xDD\x80\xCF\x02\x34\xCB\x5E\xE5\x72\xCB\xE4\x27\xA1\xA2\xB0\xC1\x21\xAB\x83\xDD\x83\x5D\xC2\x21\x6E\xAE\xD5\x89\x3C\x83\x24\xD7\xD7\xA7\x7D\xD6\xD5\x43\xDA\x40\x47\xDF\xB5\xE1\xA7\xD3\x6B\xD1\x69\x22\xA4\xCF\x96\x39\x04\x9A\xCF\xB1\xB1\x46\xD7\x40\x1C\xDF\xB4\xE6\x86\x22\xBC\xFD\x45\xDB\x40\x51\xD1\xD8\x30\x8C\xDE\xD0\xA1\xC2\x35\x0F\x9D\xDA\x99\x88\x8E\xDB\xDB\xE0\xBB\xB9\x9A\xF8\x56\xDA\x62\xE0\xBC\x8D\x9D\xC6\x39\x64\xE4\xB9\x21\x7A\xCB\xD8\xBC\x81\x99\xDD\x72\x17\xB1\xA2\x7F\xC1\x22\xBE\x0A\x25\x92\xC0\xA8\xC1\x56\x6F\xD6\x80\xBC\x90\x88\xDA\x0B\x8A\x27\x82\xDA\x92\x92\xE2\xD3\x5B\x86\x41\x62\xDB\xAE\x4A\xB9\xA2\x3B\x33\xC3\x23\x3D\x9A\xE3\x21\x73\xFB\xAD\x07",
"\x80\xA7\x48\x90\xD5\x97\x22\x85\x08\xE1\x21\x40\x09\xE4\x98\x43\xCC\x38\x85\x11\xBE\x20\xEB\xCF\xB7\x10\x16\xC3\x21\x9B\xF6\xDC\xB6\x44\x1C\xA7\xA1\x4D\xC5\xE7\x84\x3E\xE7\xDF\xB4\xA6\x0A\xD0\x90\x52\xD6\x96\xC6\xEE\xE5\xE0\xA8\x0B\xD2\x91\x5D\xCF\xA2\xC6\x22\xDE\x02\x39\xE7\x68\xCA\x0C\xE6\x29\x8A\x24\xE3\xCF\x8B\x0B\xD4\xC6\x30\xD0\xAB\xC3\x20\xEB\x01\x26\xE7\x33\xCD\x03\xED\xE4\x00\xDA\xE4\xD5\xB0\xE8\x6D\xCF\x0D\xEC\xD4\x17\xD0\xEE\x09\x3E\x89\xA5\xC0\x3F\xA3\xF1\xBE\xE8\x00\xF5\xAC\x25\xE0\xA6\x28\xBD\x90\x05\xF7\xB4\x86\xE3\xBF\xE1\x8B\xEE\x25\x13\xF1\xA3\xBC\x7F\xB3\xEA\x7B\xE1\xC2\xF3\xF4\xA3\x28\xDC\x32\x2C\xC2\xCC\xA3\xBA\xF3\x8F\xE0\xBD\xF3\x72\xA3\x2E\x5D\xFF\x1E\xA2\xAA\x25\xF3\xBE\xE3\xA7\xF6\x37\xA9\xF3\xBD\xC1\x89\x2E\xF5\x6E\xA7\xB5\xAA\xA1\x23\xF7\x09\xE0\xBB\xB0\x54\x2A\xA5\x4D\x3A\xF9\xA5\xF1\xAF\xE4\xB3\x72\x2C\xB3\x4A\x8C\xB4\x2A\xE2\xE1\x20",
};
vl::glr::DecompressSerializedData(compressed, true, dataSolidRows, dataRows, dataBlock, dataRemain, outputStream);
}
const wchar_t* TypeParserRuleName(vl::vint index)
{
static const wchar_t* results[] = {
L"EnumItem",
L"Enum",
L"ClassPropType",
L"classProp",
L"ClassBody",
L"Class",
L"Type",
L"File",
};
return results[index];
}
const wchar_t* TypeParserStateLabel(vl::vint index)
{
static const wchar_t* results[] = {
L"[0][EnumItem] BEGIN ",
L"[1][EnumItem] END [ENDING]",
L"[2][EnumItem]< ID \",\" @ >",
L"[3][EnumItem]< ID @ \",\" >",
L"[4][Enum] BEGIN ",
L"[5][Enum] END [ENDING]",
L"[6][Enum]< \"enum\" @ ID \"{\" { EnumItem } \"}\" >",
L"[7][Enum]< \"enum\" ID \"{\" @ { EnumItem } \"}\" >",
L"[8][Enum]< \"enum\" ID \"{\" { EnumItem @ } \"}\" >",
L"[9][Enum]< \"enum\" ID \"{\" { EnumItem } \"}\" @ >",
L"[10][Enum]< \"enum\" ID @ \"{\" { EnumItem } \"}\" >",
L"[11][ClassPropType] BEGIN ",
L"[12][ClassPropType] END [ENDING]",
L"[13][ClassPropType]\"token\" @",
L"[14][ClassPropType]ID \"[\" \"]\" @",
L"[15][ClassPropType]ID \"[\" @ \"]\"",
L"[16][ClassPropType]ID @",
L"[17][ClassPropType]ID @ \"[\" \"]\"",
L"[18][classProp] BEGIN ",
L"[19][classProp] END [ENDING]",
L"[20][classProp]< \"var\" @ ID \":\" ClassPropType \";\" >",
L"[21][classProp]< \"var\" ID \":\" @ ClassPropType \";\" >",
L"[22][classProp]< \"var\" ID \":\" ClassPropType \";\" @ >",
L"[23][classProp]< \"var\" ID \":\" ClassPropType @ \";\" >",
L"[24][classProp]< \"var\" ID @ \":\" ClassPropType \";\" >",
L"[25][ClassBody] BEGIN ",
L"[26][ClassBody] END [ENDING]",
L"[27][ClassBody]ID @ [ \":\" ID ] \"{\" { classProp } \"}\"",
L"[28][ClassBody]ID [ \":\" @ ID ] \"{\" { classProp } \"}\"",
L"[29][ClassBody]ID [ \":\" ID @ ] \"{\" { classProp } \"}\"",
L"[30][ClassBody]ID [ \":\" ID ] \"{\" @ { classProp } \"}\"",
L"[31][ClassBody]ID [ \":\" ID ] \"{\" { classProp @ } \"}\"",
L"[32][ClassBody]ID [ \":\" ID ] \"{\" { classProp } \"}\" @",
L"[33][Class] BEGIN ",
L"[34][Class] END [ENDING]",
L"[35][Class]< \"ambiguous\" \"class\" @ ClassBody >",
L"[36][Class]< \"ambiguous\" \"class\" ClassBody @ >",
L"[37][Class]< \"ambiguous\" @ \"class\" ClassBody >",
L"[38][Class]< \"class\" @ ClassBody >",
L"[39][Class]< \"class\" ClassBody @ >",
L"[40][Type] BEGIN ",
L"[41][Type] END [ENDING]",
L"[42][Type]<< ( !Enum @ | !Class ) >>",
L"[43][Type]<< ( !Enum | !Class @ ) >>",
L"[44][File] BEGIN ",
L"[45][File] END [ENDING]",
L"[46][File]< Type @ { Type } >",
L"[47][File]< Type { Type @ } >",
};
return results[index];
}
TypeParser::TypeParser()
: vl::glr::ParserBase<ParserGenTokens, TypeParserStates, ParserGenAstInsReceiver>(&ParserGenTokenDeleter, &ParserGenLexerData, &ParserGenTypeParserData)
{
};
vl::vint32_t TypeParser::FindCommonBaseClass(vl::vint32_t class1, vl::vint32_t class2) const
{
return -1;
};
vl::Ptr<vl::glr::parsergen::GlrAstFile> TypeParser::ParseFile(const vl::WString& input, vl::vint codeIndex) const
{
return ParseWithString<vl::glr::parsergen::GlrAstFile, TypeParserStates::File>(input, this, codeIndex);
};
vl::Ptr<vl::glr::parsergen::GlrAstFile> TypeParser::ParseFile(vl::collections::List<vl::regex::RegexToken>& tokens, vl::vint codeIndex) const
{
return ParseWithTokens<vl::glr::parsergen::GlrAstFile, TypeParserStates::File>(tokens, this, codeIndex);
};
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGEN_ASSEMBLER.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:ParserGen
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
/***********************************************************************
ParserGenAstInsReceiver : public vl::glr::AstInsReceiverBase
***********************************************************************/
vl::Ptr<vl::glr::ParsingAstBase> ParserGenAstInsReceiver::CreateAstNode(vl::vint32_t type)
{
auto cppTypeName = ParserGenCppTypeName((ParserGenClasses)type);
switch((ParserGenClasses)type)
{
case ParserGenClasses::AlternativeSyntax:
return new vl::glr::parsergen::GlrAlternativeSyntax();
case ParserGenClasses::Assignment:
return new vl::glr::parsergen::GlrAssignment();
case ParserGenClasses::AstFile:
return new vl::glr::parsergen::GlrAstFile();
case ParserGenClasses::Class:
return new vl::glr::parsergen::GlrClass();
case ParserGenClasses::ClassProp:
return new vl::glr::parsergen::GlrClassProp();
case ParserGenClasses::CreateClause:
return new vl::glr::parsergen::GlrCreateClause();
case ParserGenClasses::Enum:
return new vl::glr::parsergen::GlrEnum();
case ParserGenClasses::EnumItem:
return new vl::glr::parsergen::GlrEnumItem();
case ParserGenClasses::LiteralSyntax:
return new vl::glr::parsergen::GlrLiteralSyntax();
case ParserGenClasses::LoopSyntax:
return new vl::glr::parsergen::GlrLoopSyntax();
case ParserGenClasses::OptionalSyntax:
return new vl::glr::parsergen::GlrOptionalSyntax();
case ParserGenClasses::PartialClause:
return new vl::glr::parsergen::GlrPartialClause();
case ParserGenClasses::RefSyntax:
return new vl::glr::parsergen::GlrRefSyntax();
case ParserGenClasses::ReuseClause:
return new vl::glr::parsergen::GlrReuseClause();
case ParserGenClasses::Rule:
return new vl::glr::parsergen::GlrRule();
case ParserGenClasses::SequenceSyntax:
return new vl::glr::parsergen::GlrSequenceSyntax();
case ParserGenClasses::SyntaxFile:
return new vl::glr::parsergen::GlrSyntaxFile();
case ParserGenClasses::UseSyntax:
return new vl::glr::parsergen::GlrUseSyntax();
default:
return vl::glr::AssemblyThrowCannotCreateAbstractType(type, cppTypeName);
}
}
void ParserGenAstInsReceiver::SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::Ptr<vl::glr::ParsingAstBase> value)
{
auto cppFieldName = ParserGenCppFieldName((ParserGenFields)field);
switch((ParserGenFields)field)
{
case ParserGenFields::AlternativeSyntax_first:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrAlternativeSyntax::first, object, field, value, cppFieldName);
case ParserGenFields::AlternativeSyntax_second:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrAlternativeSyntax::second, object, field, value, cppFieldName);
case ParserGenFields::AstFile_types:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrAstFile::types, object, field, value, cppFieldName);
case ParserGenFields::Class_props:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrClass::props, object, field, value, cppFieldName);
case ParserGenFields::CreateClause_assignments:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrCreateClause::assignments, object, field, value, cppFieldName);
case ParserGenFields::CreateClause_syntax:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrCreateClause::syntax, object, field, value, cppFieldName);
case ParserGenFields::Enum_items:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrEnum::items, object, field, value, cppFieldName);
case ParserGenFields::LoopSyntax_delimiter:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrLoopSyntax::delimiter, object, field, value, cppFieldName);
case ParserGenFields::LoopSyntax_syntax:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrLoopSyntax::syntax, object, field, value, cppFieldName);
case ParserGenFields::OptionalSyntax_syntax:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrOptionalSyntax::syntax, object, field, value, cppFieldName);
case ParserGenFields::PartialClause_assignments:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrPartialClause::assignments, object, field, value, cppFieldName);
case ParserGenFields::PartialClause_syntax:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrPartialClause::syntax, object, field, value, cppFieldName);
case ParserGenFields::ReuseClause_assignments:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrReuseClause::assignments, object, field, value, cppFieldName);
case ParserGenFields::ReuseClause_syntax:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrReuseClause::syntax, object, field, value, cppFieldName);
case ParserGenFields::Rule_clauses:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrRule::clauses, object, field, value, cppFieldName);
case ParserGenFields::SequenceSyntax_first:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrSequenceSyntax::first, object, field, value, cppFieldName);
case ParserGenFields::SequenceSyntax_second:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrSequenceSyntax::second, object, field, value, cppFieldName);
case ParserGenFields::SyntaxFile_rules:
return vl::glr::AssemblerSetObjectField(&vl::glr::parsergen::GlrSyntaxFile::rules, object, field, value, cppFieldName);
default:
return vl::glr::AssemblyThrowFieldNotObject(field, cppFieldName);
}
}
void ParserGenAstInsReceiver::SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, const vl::regex::RegexToken& token, vl::vint32_t tokenIndex)
{
auto cppFieldName = ParserGenCppFieldName((ParserGenFields)field);
switch((ParserGenFields)field)
{
case ParserGenFields::Assignment_field:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrAssignment::field, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::Assignment_value:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrAssignment::value, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::Class_baseClass:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrClass::baseClass, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::ClassProp_name:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrClassProp::name, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::ClassProp_propTypeName:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrClassProp::propTypeName, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::CreateClause_type:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrCreateClause::type, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::EnumItem_name:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrEnumItem::name, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::LiteralSyntax_value:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrLiteralSyntax::value, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::PartialClause_type:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrPartialClause::type, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::RefSyntax_field:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrRefSyntax::field, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::RefSyntax_name:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrRefSyntax::name, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::Rule_name:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrRule::name, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::Type_name:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrType::name, object, field, token, tokenIndex, cppFieldName);
case ParserGenFields::UseSyntax_name:
return vl::glr::AssemblerSetTokenField(&vl::glr::parsergen::GlrUseSyntax::name, object, field, token, tokenIndex, cppFieldName);
default:
return vl::glr::AssemblyThrowFieldNotToken(field, cppFieldName);
}
}
void ParserGenAstInsReceiver::SetField(vl::glr::ParsingAstBase* object, vl::vint32_t field, vl::vint32_t enumItem)
{
auto cppFieldName = ParserGenCppFieldName((ParserGenFields)field);
switch((ParserGenFields)field)
{
case ParserGenFields::Class_ambiguity:
return vl::glr::AssemblerSetEnumField(&vl::glr::parsergen::GlrClass::ambiguity, object, field, enumItem, cppFieldName);
case ParserGenFields::ClassProp_propType:
return vl::glr::AssemblerSetEnumField(&vl::glr::parsergen::GlrClassProp::propType, object, field, enumItem, cppFieldName);
case ParserGenFields::OptionalSyntax_priority:
return vl::glr::AssemblerSetEnumField(&vl::glr::parsergen::GlrOptionalSyntax::priority, object, field, enumItem, cppFieldName);
default:
return vl::glr::AssemblyThrowFieldNotEnum(field, cppFieldName);
}
}
const wchar_t* ParserGenTypeName(ParserGenClasses type)
{
const wchar_t* results[] = {
L"AlternativeSyntax",
L"Assignment",
L"AstFile",
L"Class",
L"ClassProp",
L"Clause",
L"CreateClause",
L"Enum",
L"EnumItem",
L"LiteralSyntax",
L"LoopSyntax",
L"OptionalSyntax",
L"PartialClause",
L"RefSyntax",
L"ReuseClause",
L"Rule",
L"SequenceSyntax",
L"Syntax",
L"SyntaxFile",
L"Type",
L"UseSyntax",
};
vl::vint index = (vl::vint)type;
return 0 <= index && index < 21 ? results[index] : nullptr;
}
const wchar_t* ParserGenCppTypeName(ParserGenClasses type)
{
const wchar_t* results[] = {
L"vl::glr::parsergen::GlrAlternativeSyntax",
L"vl::glr::parsergen::GlrAssignment",
L"vl::glr::parsergen::GlrAstFile",
L"vl::glr::parsergen::GlrClass",
L"vl::glr::parsergen::GlrClassProp",
L"vl::glr::parsergen::GlrClause",
L"vl::glr::parsergen::GlrCreateClause",
L"vl::glr::parsergen::GlrEnum",
L"vl::glr::parsergen::GlrEnumItem",
L"vl::glr::parsergen::GlrLiteralSyntax",
L"vl::glr::parsergen::GlrLoopSyntax",
L"vl::glr::parsergen::GlrOptionalSyntax",
L"vl::glr::parsergen::GlrPartialClause",
L"vl::glr::parsergen::GlrRefSyntax",
L"vl::glr::parsergen::GlrReuseClause",
L"vl::glr::parsergen::GlrRule",
L"vl::glr::parsergen::GlrSequenceSyntax",
L"vl::glr::parsergen::GlrSyntax",
L"vl::glr::parsergen::GlrSyntaxFile",
L"vl::glr::parsergen::GlrType",
L"vl::glr::parsergen::GlrUseSyntax",
};
vl::vint index = (vl::vint)type;
return 0 <= index && index < 21 ? results[index] : nullptr;
}
const wchar_t* ParserGenFieldName(ParserGenFields field)
{
const wchar_t* results[] = {
L"AlternativeSyntax::first",
L"AlternativeSyntax::second",
L"Assignment::field",
L"Assignment::value",
L"AstFile::types",
L"Class::ambiguity",
L"Class::baseClass",
L"Class::props",
L"ClassProp::name",
L"ClassProp::propType",
L"ClassProp::propTypeName",
L"CreateClause::assignments",
L"CreateClause::syntax",
L"CreateClause::type",
L"Enum::items",
L"EnumItem::name",
L"LiteralSyntax::value",
L"LoopSyntax::delimiter",
L"LoopSyntax::syntax",
L"OptionalSyntax::priority",
L"OptionalSyntax::syntax",
L"PartialClause::assignments",
L"PartialClause::syntax",
L"PartialClause::type",
L"RefSyntax::field",
L"RefSyntax::name",
L"ReuseClause::assignments",
L"ReuseClause::syntax",
L"Rule::clauses",
L"Rule::name",
L"SequenceSyntax::first",
L"SequenceSyntax::second",
L"SyntaxFile::rules",
L"Type::name",
L"UseSyntax::name",
};
vl::vint index = (vl::vint)field;
return 0 <= index && index < 35 ? results[index] : nullptr;
}
const wchar_t* ParserGenCppFieldName(ParserGenFields field)
{
const wchar_t* results[] = {
L"vl::glr::parsergen::GlrAlternativeSyntax::first",
L"vl::glr::parsergen::GlrAlternativeSyntax::second",
L"vl::glr::parsergen::GlrAssignment::field",
L"vl::glr::parsergen::GlrAssignment::value",
L"vl::glr::parsergen::GlrAstFile::types",
L"vl::glr::parsergen::GlrClass::ambiguity",
L"vl::glr::parsergen::GlrClass::baseClass",
L"vl::glr::parsergen::GlrClass::props",
L"vl::glr::parsergen::GlrClassProp::name",
L"vl::glr::parsergen::GlrClassProp::propType",
L"vl::glr::parsergen::GlrClassProp::propTypeName",
L"vl::glr::parsergen::GlrCreateClause::assignments",
L"vl::glr::parsergen::GlrCreateClause::syntax",
L"vl::glr::parsergen::GlrCreateClause::type",
L"vl::glr::parsergen::GlrEnum::items",
L"vl::glr::parsergen::GlrEnumItem::name",
L"vl::glr::parsergen::GlrLiteralSyntax::value",
L"vl::glr::parsergen::GlrLoopSyntax::delimiter",
L"vl::glr::parsergen::GlrLoopSyntax::syntax",
L"vl::glr::parsergen::GlrOptionalSyntax::priority",
L"vl::glr::parsergen::GlrOptionalSyntax::syntax",
L"vl::glr::parsergen::GlrPartialClause::assignments",
L"vl::glr::parsergen::GlrPartialClause::syntax",
L"vl::glr::parsergen::GlrPartialClause::type",
L"vl::glr::parsergen::GlrRefSyntax::field",
L"vl::glr::parsergen::GlrRefSyntax::name",
L"vl::glr::parsergen::GlrReuseClause::assignments",
L"vl::glr::parsergen::GlrReuseClause::syntax",
L"vl::glr::parsergen::GlrRule::clauses",
L"vl::glr::parsergen::GlrRule::name",
L"vl::glr::parsergen::GlrSequenceSyntax::first",
L"vl::glr::parsergen::GlrSequenceSyntax::second",
L"vl::glr::parsergen::GlrSyntaxFile::rules",
L"vl::glr::parsergen::GlrType::name",
L"vl::glr::parsergen::GlrUseSyntax::name",
};
vl::vint index = (vl::vint)field;
return 0 <= index && index < 35 ? results[index] : nullptr;
}
vl::Ptr<vl::glr::ParsingAstBase> ParserGenAstInsReceiver::ResolveAmbiguity(vl::vint32_t type, vl::collections::Array<vl::Ptr<vl::glr::ParsingAstBase>>& candidates)
{
auto cppTypeName = ParserGenCppTypeName((ParserGenClasses)type);
return vl::glr::AssemblyThrowTypeNotAllowAmbiguity(type, cppTypeName);
}
}
}
}
/***********************************************************************
.\PARSERGEN_GENERATED\PARSERGEN_LEXER.CPP
***********************************************************************/
/***********************************************************************
This file is generated by: Vczh Parser Generator
From parser definition:ParserGen
Licensed under https://github.com/vczh-libraries/License
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
bool ParserGenTokenDeleter(vl::vint token)
{
switch((ParserGenTokens)token)
{
case ParserGenTokens::COMMENT:
case ParserGenTokens::SPACE:
return true;
default:
return false;
}
}
const wchar_t* ParserGenTokenId(ParserGenTokens token)
{
static const wchar_t* results[] = {
L"AMBIGUOUS",
L"CLASS",
L"ENUM",
L"VAR",
L"TOKEN",
L"AS",
L"PARTIAL",
L"OPEN_ROUND",
L"CLOSE_ROUND",
L"OPEN_SQUARE",
L"CLOSE_SQUARE",
L"OPEN_CURLY",
L"CLOSE_CURLY",
L"COMMA",
L"COLON",
L"SEMICOLON",
L"INFER",
L"ALTERNATIVE",
L"USE",
L"ASSIGN",
L"POSITIVE",
L"NEGATIVE",
L"ID",
L"STRING",
L"SPACE",
L"COMMENT",
};
vl::vint index = (vl::vint)token;
return 0 <= index && index < ParserGenTokenCount ? results[index] : nullptr;
}
const wchar_t* ParserGenTokenDisplayText(ParserGenTokens token)
{
static const wchar_t* results[] = {
L"ambiguous",
L"class",
L"enum",
L"var",
L"token",
L"as",
L"partial",
L"(",
L")",
L"[",
L"]",
L"{",
L"}",
L",",
L":",
L";",
L"::=",
L"|",
L"!",
L"=",
L"+",
L"-",
nullptr,
nullptr,
nullptr,
nullptr,
};
vl::vint index = (vl::vint)token;
return 0 <= index && index < ParserGenTokenCount ? results[index] : nullptr;
}
const wchar_t* ParserGenTokenRegex(ParserGenTokens token)
{
static const wchar_t* results[] = {
L"ambiguous",
L"class",
L"enum",
L"var",
L"token",
L"as",
L"partial",
L"/(",
L"/)",
L"/[",
L"/]",
L"/{",
L"/}",
L",",
L":",
L";",
L"::=",
L"/|",
L"!",
L"=",
L"/+",
L"-",
L"[a-zA-Z_][a-zA-Z0-9_]*",
L"(\"[^\"]*\")+",
L"/s+",
L"////[^/r/n]*",
};
vl::vint index = (vl::vint)token;
return 0 <= index && index < ParserGenTokenCount ? results[index] : nullptr;
}
void ParserGenLexerData(vl::stream::IStream& outputStream)
{
static const vl::vint dataLength = 1368; // 15852 bytes before compressing
static const vl::vint dataBlock = 256;
static const vl::vint dataRemain = 88;
static const vl::vint dataSolidRows = 5;
static const vl::vint dataRows = 6;
static const char* compressed[] = {
"\xEC\x3D\x00\x00\x50\x05\x00\x00\x40\x00\x01\xBB\x01\x84\x81\x82\x1C\x82\x01\x04\x88\x04\x89\x04\x84\x82\x05\x0F\x84\x8B\x04\x8C\x04\x81\x06\x8B\x04\x8E\x04\x9F\x04\x80\x11\x8E\x82\x21\x20\x84\x82\x13\x94\x83\x10\x82\x27\x04\xA8\x0A\x94\x81\x15\x96\x82\x2A\x30\x84\x8B\x13\x9C\x80\x16\x9B\x04\xAD\x39\x84\x8E\x14\x9C\x83\x17\x3F\x84\xB0\x04\x89\x1C\x83\x82\x83\x04\x83\x82\x84\x8C\x1C\xA4\x83\x1E\x4F\x84\xBE\x04\x80\x81\x81\x20\x82\x5A\x04\x9B\x3A\xA4\x84\x2D\xAE\x82\x5D\x60\x84\x9E\x23\xB4\x83\x2E\xB3\x04\xE0\x29\xA4\x81\x34\xB4\x82\x31\x6F\x84\xA3\x32\xB4\x84\x31\xBA\x82\x65\x78\x84\x86\x3B\xBC\x83\x32\xBF\x04\xE8\x01\xC4\x89\x34\xC0\x82\x35\x87\x84\xAB\x2A\xC4\x84\x35\xC6\x82\x6D\x10\xC4\x8E\x33\xCC\x83\x36\xCB\x04\xF0\x19\xC4\x81\x3C\xCC\x82\x39\x9F\x84\xB3\x22\xD4\x84\x39\xD2\x82\x75\x28\xC4\x96\x3B\xD4\x83\x3A\x82\x7A\x04\xBB\x32\xD4\x84\x3D\xDA\x82\x7D\x38\xC4\x9E\x34\x87\x7F\x7E\x08\x00\x3E\xFE\xD7\x04\x84\xE1\x80\xE1\xFF\x46\xC1\xE2\xEA\xE1\x08\x82\x0B\xBD\xC2\xC7\x0A\x81\xEE\xDF\x08\x8C\x01\x94\x15\xFF",
"\x78\x0B\xEE\x8D\x80\x0F\x5B\xD2\x1B\xE5\x0E\x87\xE2\xE1\x10\xE7\xFE\xC5\xFA\xF7\x7D\x85\x80\xEC\x80\x02\x04\x81\xFB\x00\xFB\xFB\xF0\xF8\xC0\x11\xFC\xFA\xFD\xFF\x80\x06\x3E\x7A\x7D\x01\xFA\x44\x0A\x7F\x44\x01\x40\x71\x41\x45\xED\x48\x7E\x83\x83\x10\x91\x82\x87\x84\x14\x95\x88\x73\x06\xDB\x56\x82\x70\x86\x0D\x94\x8C\x87\x72\xBE\x5F\x82\x88\x41\x23\x81\x45\x88\x00\x27\xA9\x84\x41\x06\x24\xAD\x86\x8A\x8B\x28\x84\x4A\x04\x8C\x2A\x9D\x8A\x87\x8D\x38\xB9\x8A\x8F\x83\x1F\xBB\x8F\x3D\x8F\x37\x80\x91\x88\x8D\x44\xAF\x86\x91\x8C\x47\xA7\x8C\x05\x91\x48\x8D\x95\x8E\x93\x4C\xBE\x82\x97\x94\x54\xBC\x89\x85\x90\x57\x93\x82\x93\x8F\x4C\x8F\x9E\x95\x97\x04\x5D\x00\x99\x92\x63\x8D\x95\x97\x99\x68\xB9\x8B\x94\x8E\x6B\x9E\x8B\x76\x07\x65\x9F\x94\x9B\x9C\x50\xB4\x92\x9D\x9D\x66\xA9\x9A\x9F\x9E\x10\xAD\x9A\x86\x9F\x12\x9B\x97\x9F\xA0\x71\xB0\x8C\x46\x9D\x85\x87\x9C\x9F\xA2\x8B\x80\xA5\x86\xA3\x7D\x9B\x7E\x44\xA2\x94\xB8\x94\xA1\xA5\x97\xB9\x9C\xA3\xA6\x9C\x9D\xAE\xA7\xA7\xA0\xA1\xA2\xAB\xA8\xA4\xA5\xA6\xAB\xA9\xA8\xA9\xAA\xAB\xAA",
"\xAC\xAD\xAE\xAB\xAB\xB0\xB1\xA2\xAF\xAC\xB4\xB5\xA6\xAF\xAD\xB8\xB9\xAA\xAF\xAE\xBC\x8B\xA1\x4A\x8D\xBD\x81\xB2\xB3\xB0\xC4\x85\xB6\xB3\xB1\xC8\x89\xBA\xB3\xB2\xCC\x8D\xBE\xB3\xB3\xD0\x91\xB2\xB7\xB4\xD4\xBE\x80\xA6\x96\x59\x81\xAB\x75\xA6\xDC\x89\xA6\xA6\xB7\xD7\x92\x84\x49\x40\xE3\x80\x05\xBB\xB9\x25\x64\xB9\xB8\x00\x27\x6A\xBE\xBA\xB9\xEB\xA8\xBF\xBA\xBC\xF0\xB3\xB1\xBF\xBD\xF6\xB9\xB5\xBF\xBE\xF4\xBD\xB8\xBC\xBF\xFF\xBE\xBA\xBE\xC0\x00\xC3\xC1\xC1\xB6\x24\x04\x49\xC1\x7B\x0B\xE0\x8F\x3D\xC3\xD5\x91\xC2\xC6\x84\x25\x19\xB3\xC7\xC5\xA7\xA1\xB1\x86\xC6\x1B\x9B\xB4\x42\x09\xE0\xA1\xC8\xA6\xC8\x78\x97\xCC\xC6\x95\xC0\x9B\xCE\xC7\xC8\x2C\xDF\xBD\xC9\xB7\x8A\x93\xC7\xCA\x83\x33\xC2\xA4\xC8\xCC\x2E\xF9\xC9\xA6\xC9\x16\xEE\x99\xC9\xA4\xED\x69\x4F\xCB\xCD\x44\xC3\xDF\xCF\xB3\x33\xD7\x8D\xCC\xCA\x0E\xF8\xCE\xD1\xD1\x4D\xAB\x44\x9C\xCF\x47\xDA\xB5\xD6\xD2\xED\x4F\xD6\xD2\xCE\x30\xAE\x4B\xD4\xD5\x0E\xEC\x9B\xD0\xCD\x2B\xDC\xDB\xD5\x4C\x5B\xDA\xD1\xD8\xB5\x49\xDD\xC7\xD6\xDB\x4D\xD0\xDA\xDB\x93\x34\x5F\xD8\xC6\x86\x37",
"\x6F\xD7\xDE\xA7\x04\xFD\xDB\xB9\xBB\x05\xC1\xEE\xDE\xC1\x84\xC2\xE7\xC1\xE1\x83\xC6\xE8\xE3\xE1\x8A\xCD\xE9\xE0\xBD\x9E\xBA\x4A\xDF\xDE\x77\xCD\xC0\xC6\x70\x97\xFE\x69\xE4\xE5\x9C\xD5\x8D\x4D\x40\x9F\xCE\xC1\xE8\x72\xA1\xE5\xEE\x4C\xE8\xA7\xC0\x06\xE8\xEA\xAC\xEA\xE9\xEB\xEA\xAE\xED\xE0\xEF\xEC\xAF\xF5\xE2\xEE\xED\xB1\xF9\xE4\xEF\xED\xBC\xFA\xE8\xEF\xEE\xBE\xFD\xE0\xF3\xE8\xC8\xAD\xD3\x93\xE4\x36\xE9\xD0\x8C\x50\xCA\xCD\xF5\xCA\xCC\x63\xEA\xC8\xF1\xD9\x73\xF2\xDC\x93\x50\x2D\xE0\xD6\xB5\xF4\x70\xD8\xD6\xDB\xF7\x4F\xB1\x06\xF5\xA5\xDA\xFB\x85\xCC\xF5\xE3\xE0\xF9\xFB\x89\xE5\xFA\x87\xF9\xD6\x65\xB2\x0B\xFB\xFC\x53\xD0\xF3\xE6\xF7\x62\xF0\xFE\xF1\xF5\x2D\xF3\x05\x99\xE7\x00\x95\x54\x0D\x04\x23\x81\x80\x05\x80\x00\x07\x89\x80\x01\x8B\x81\x21\x1A\x0C\x80\x81\x0F\x8A\x82\x01\x91\x84\x83\x09\x96\x80\x82\x17\x92\x80\x06\x9B\x8A\x83\x0E\x95\x84\x83\x1F\x9E\x81\x06\xA1\x84\x85\x11\xA6\x80\x84\x27\x87\x80\xE9\x29\x7B\x85\xF6\x03\x7F\x77\x30\x82\x79\x0C\xC1\x74\x87\x17\xB2\x87\x86\x35\x93\x86\x0D\xB9\x88\x87\x1D\x80\x79",
"\x59\xC6\x7C\x4B\xF4\x7A\x7A\x7D\x80\x36\x04\x7E\x45\x99\x65\xFB\x6A\x4C\x7B\xE3\x71\x6B\x7F\x48\x87\x47\x0D\x5E\x5B\x89\xFC\x6B\x68\x5B\x44\x9C\x7D\x12\xDA\x81\x89\x62\x41\x8F\x7D\x4F\x9B\x88\xD4\x38\x01\x8B\x26\x8A\x5F\x8B\x66\x89\x7A\x18\xC7\x45\x28\x28\xAE\x8F\x8A\x16\x42\x84\x0A\xF3\x87\x80\x07\xA9\x85\x84\x74\x98\x8E\x1C\xFB\x8A\x8F\x3E\xB7\x8F\x8F\x79\x80\x90\x1F\x82\x9F\x83\xC8\x66\x89\x80\x88\x91\x54\x1A\xC3\x81\x8C\x2E\xA5\x8F\x48\x47\x2F\x7A\xC4\x0B\x90\x8E\xE9\x4D\x97\x91\x6B\x99\x91\x15\xD8\x4C\x90\xEF\x4E\x97\x8D\x38\x7B\x93\x9F\x69\x8B\x3A\xA5\x19\x97\x93\xA7\x87\x91\xF1\x2A\x9E\x88\x2B\x9E\x90\x93\x4F\x4D\x28\x28\xAC\x96\x58\x4A\xAE\x90\x6E\xA8\x9F\x40\x54\x33\x94\x7C\xFB\x55\x96\x67\xBF\x8C\x6B\x2B\xBC\x99\x95\x4A\x53\x2D\x7E\x93\x94\x94\x18\xC3\x95\x99\x66\xAA\x6A\x94\x16\x4B\x98\x2E\xB0\x90\x6B\x1F\x14\x8E\x97\xDB\x7D\x93\x34\xC4\x99\x97\xFF\x7B\x46\x1F\xFF\x1F\x16\x3F\x79\x1F\x1B\x77\x3F\x1D\x2A\x05\x20\x00\x74\x01\x2B\x9C\x75\x8F\x3F\x9D\xEC\x84\x23\x74\x01\x2B\x21\x80\x0D\x21\x20\xE9\x20",
"\x00\x82\x00\x0C\x40\x00\x17\x21\x20\xDF\x20\x01\x78\x01\x2E\x39\x80\x23\x39\x20\xD7\x39\x3A\x7E\x6D\x93\x47\x80\x1D\x39\x20\x0D\xAE\x9D\x40\x04\x41\x9F\x8A\x92\xA7\xA2\xED\x8C\xA2\x8C\x45\x34\x21\x87\x80\x04\x45\x16\xB9\xA0\x41\x76\x31\xA4\x82\x0A\x40\x00\x11\xA0\xA4\x46\x84\x23\x3F\x92\x90\xA4\xA3\x16\xAF\x3C\x00\x06\x4E\xA5\x95\x80\x40\x9E\xE9\x80",
};
vl::glr::DecompressSerializedData(compressed, true, dataSolidRows, dataRows, dataBlock, dataRemain, outputStream);
}
}
}
}
/***********************************************************************
.\SYNTAX\SYNTAXCPPGEN.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace stream;
using namespace regex;
/***********************************************************************
GenerateSyntaxFileNames
***********************************************************************/
Ptr<CppSyntaxGenOutput> GenerateSyntaxFileNames(SyntaxSymbolManager& manager, Ptr<CppParserGenOutput> output)
{
auto syntaxOutput = MakePtr<CppSyntaxGenOutput>();
syntaxOutput->syntaxH = manager.Global().name + manager.name + L".h";
syntaxOutput->syntaxCpp = manager.Global().name + manager.name + L".cpp";
output->syntaxOutputs.Add(&manager, syntaxOutput);
return syntaxOutput;
}
/***********************************************************************
WriteSyntaxHeaderFile
***********************************************************************/
void WriteSyntaxHeaderFile(SyntaxSymbolManager& manager, automaton::Executable& executable, automaton::Metadata& metadata, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer)
{
WriteFileComment(manager.Global().name, writer);
if (manager.Global().headerGuard != L"")
{
writer.WriteString(L"#ifndef ");
writer.WriteLine(manager.Global().headerGuard + L"_" + wupper(manager.name) + L"_SYNTAX");
writer.WriteString(L"#define ");
writer.WriteLine(manager.Global().headerGuard + L"_" + wupper(manager.name) + L"_SYNTAX");
}
else
{
writer.WriteLine(L"#pragma once");
}
writer.WriteLine(L"");
writer.WriteLine(L"#include \"" + output->assemblyH + L"\"");
writer.WriteLine(L"#include \"" + output->lexerH +L"\"");
writer.WriteLine(L"");
WString prefix = WriteNssBegin(manager.Global().cppNss, writer);
{
writer.WriteLine(prefix + L"enum class " + manager.name + L"States");
writer.WriteLine(prefix + L"{");
for (auto&& [ruleName, index] : indexed(metadata.ruleNames))
{
writer.WriteLine(prefix + L"\t" + ruleName + L" = " + itow(executable.ruleStartStates[index]) + L",");
}
writer.WriteLine(prefix + L"};");
}
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"const wchar_t* " + manager.name + L"RuleName(vl::vint index);");
writer.WriteLine(prefix + L"const wchar_t* " + manager.name + L"StateLabel(vl::vint index);");
WriteLoadDataFunctionHeader(prefix, manager.Global().name + manager.name + L"Data", writer);
}
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"class " + manager.name);
writer.WriteString(prefix+L"\t: public vl::glr::ParserBase<");
writer.WriteString(manager.Global().name + L"Tokens, ");
writer.WriteString(manager.name + L"States, ");
writer.WriteString(manager.Global().name + L"AstInsReceiver>");
writer.WriteLine(prefix + L"\t, protected vl::glr::automaton::TraceManager::ITypeCallback");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"protected:");
writer.WriteLine(prefix + L"\tvl::vint32_t FindCommonBaseClass(vl::vint32_t class1, vl::vint32_t class2) const override;");
writer.WriteLine(prefix + L"public:");
writer.WriteLine(prefix + L"\t" + manager.name + L"();");
writer.WriteLine(L"");
for (auto ruleName : manager.RuleOrder())
{
auto ruleSymbol = manager.Rules()[ruleName];
if (manager.parsableRules.Contains(ruleSymbol))
{
auto astType = manager.ruleTypes[ruleSymbol];
writer.WriteLine(prefix + L"\tvl::Ptr<" + astType + L"> Parse" + ruleName + L"(const vl::WString& input, vl::vint codeIndex = -1) const;");
writer.WriteLine(prefix + L"\tvl::Ptr<" + astType + L"> Parse" + ruleName + L"(vl::collections::List<vl::regex::RegexToken>& tokens, vl::vint codeIndex = -1) const;");
}
}
writer.WriteLine(prefix + L"};");
}
WriteNssEnd(manager.Global().cppNss, writer);
if (manager.Global().headerGuard != L"")
{
writer.WriteString(L"#endif");
}
}
/***********************************************************************
WriteSyntaxCppFile
***********************************************************************/
void WriteSyntaxCppFile(SyntaxSymbolManager& manager, automaton::Executable& executable, automaton::Metadata& metadata, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer)
{
WriteFileComment(manager.Global().name, writer);
writer.WriteLine(L"#include \"" + output->syntaxOutputs[&manager]->syntaxH + L"\"");
writer.WriteLine(L"");
WString prefix = WriteNssBegin(manager.Global().cppNss, writer);
{
MemoryStream syntaxData;
executable.Serialize(syntaxData);
syntaxData.SeekFromBegin(0);
WriteLoadDataFunctionCpp(prefix, manager.Global().name + manager.name + L"Data", syntaxData, true, writer);
}
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"const wchar_t* " + manager.name + L"RuleName(vl::vint index)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tstatic const wchar_t* results[] = {");
for (auto&& ruleName : metadata.ruleNames)
{
writer.WriteString(prefix + L"\t\tL\"");
WriteCppStringBody(ruleName, writer);
writer.WriteLine(L"\",");
}
writer.WriteLine(prefix + L"\t};");
writer.WriteLine(prefix + L"\treturn results[index];");
writer.WriteLine(prefix + L"}");
}
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"const wchar_t* " + manager.name + L"StateLabel(vl::vint index)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\tstatic const wchar_t* results[] = {");
for (auto&& stateLabel : metadata.stateLabels)
{
writer.WriteString(prefix + L"\t\tL\"");
WriteCppStringBody(stateLabel, writer);
writer.WriteLine(L"\",");
}
writer.WriteLine(prefix + L"\t};");
writer.WriteLine(prefix + L"\treturn results[index];");
writer.WriteLine(prefix + L"}");
}
{
writer.WriteLine(L"");
writer.WriteLine(prefix + manager.name + L"::"+ manager.name + L"()");
writer.WriteString(prefix + L"\t: vl::glr::ParserBase<");
writer.WriteString(manager.Global().name + L"Tokens, ");
writer.WriteString(manager.name + L"States, ");
writer.WriteString(manager.Global().name + L"AstInsReceiver>(");
writer.WriteString(L"&" + manager.Global().name + L"TokenDeleter, ");
writer.WriteString(L"&" + manager.Global().name + L"LexerData, ");
writer.WriteLine(L"&" + manager.Global().name + manager.name + L"Data)");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"};");
}
{
writer.WriteLine(L"");
writer.WriteLine(prefix + L"vl::vint32_t " + manager.name + L"::FindCommonBaseClass(vl::vint32_t class1, vl::vint32_t class2) const");
writer.WriteLine(prefix + L"{");
if (
output->classIds.Count() == 0 ||
From(output->classIds.Keys())
.Where([](auto c) { return c->ambiguousDerivedClass != nullptr; })
.IsEmpty()
)
{
writer.WriteLine(prefix + L"\treturn -1;");
}
else
{
Array<AstClassSymbol*> idToClasses(output->classIds.Count());
for (auto [k, v] : output->classIds)
{
idToClasses[v] = k;
}
writer.WriteLine(prefix + L"\tstatic vl::vint32_t results[" + itow(idToClasses.Count()) + L"][" + itow(idToClasses.Count()) + L"] = {");
for (auto [c1, i1] : indexed(idToClasses))
{
writer.WriteString(prefix + L"\t\t{");
for (auto [c2, i2] : indexed(idToClasses))
{
if (auto baseClass = FindCommonBaseClass(c1, c2))
{
writer.WriteString(itow(output->classIds[baseClass]) + L", ");
}
else
{
writer.WriteString(L"-1, ");
}
}
writer.WriteLine(L"},");
}
writer.WriteLine(prefix + L"\t};");
writer.WriteLine(prefix + L"\treturn vl::glr::AssemblerFindCommonBaseClass(class1, class2, results);");
}
writer.WriteLine(prefix + L"};");
}
for (auto ruleName : manager.RuleOrder())
{
auto ruleSymbol = manager.Rules()[ruleName];
if (manager.parsableRules.Contains(ruleSymbol))
{
auto astType = manager.ruleTypes[ruleSymbol];
writer.WriteLine(L"");
writer.WriteLine(prefix + L"vl::Ptr<" + astType + L"> " + manager.name + L"::Parse" + ruleName + L"(const vl::WString& input, vl::vint codeIndex) const");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\t return ParseWithString<" + astType + L", " + manager.name + L"States::" + ruleName + L">(input, this, codeIndex);");
writer.WriteLine(prefix + L"};");
writer.WriteLine(L"");
writer.WriteLine(prefix + L"vl::Ptr<" + astType + L"> " + manager.name + L"::Parse" + ruleName + L"(vl::collections::List<vl::regex::RegexToken>& tokens, vl::vint codeIndex) const");
writer.WriteLine(prefix + L"{");
writer.WriteLine(prefix + L"\t return ParseWithTokens<" + astType + L", " + manager.name + L"States::" + ruleName + L">(tokens, this, codeIndex);");
writer.WriteLine(prefix + L"};");
}
}
WriteNssEnd(manager.Global().cppNss, writer);
}
/***********************************************************************
WriteLexerFiles
***********************************************************************/
void WriteSyntaxFiles(SyntaxSymbolManager& manager, automaton::Executable& executable, automaton::Metadata& metadata, Ptr<CppParserGenOutput> output, collections::Dictionary<WString, WString>& files)
{
WString fileH = GenerateToStream([&](StreamWriter& writer)
{
WriteSyntaxHeaderFile(manager, executable, metadata, output, writer);
});
WString fileCpp = GenerateToStream([&](StreamWriter& writer)
{
WriteSyntaxCppFile(manager, executable, metadata, output, writer);
});
files.Add(output->syntaxOutputs[&manager]->syntaxH, fileH);
files.Add(output->syntaxOutputs[&manager]->syntaxCpp, fileCpp);
}
}
}
}
/***********************************************************************
.\SYNTAX\SYNTAXSYMBOL.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
/***********************************************************************
StateSymbol
***********************************************************************/
StateSymbol::StateSymbol(RuleSymbol* _rule, vint32_t _clauseId)
: ownerManager(_rule->Owner())
, rule(_rule)
, clauseId(_clauseId)
{
}
void StateSymbol::GetOutEdgesInStableOrder(collections::List<StateSymbol*>& orderedStates, EdgeList& orderedEdges)
{
CopyFrom(orderedEdges, From(outEdges)
.OrderBy([&](EdgeSymbol* e1, EdgeSymbol* e2)
{
vint result = 0;
if (e1->input.type != e2->input.type)
{
result = (vint)e1->input.type - (vint)e2->input.type;
}
else
{
switch (e1->input.type)
{
case EdgeInputType::Token:
result = e1->input.token - e2->input.token;
break;
case EdgeInputType::Rule:
result = ownerManager->RuleOrder().IndexOf(e1->input.rule->Name()) - ownerManager->RuleOrder().IndexOf(e2->input.rule->Name());
break;
default:;
}
}
if (result != 0) return result;
return orderedStates.IndexOf(e1->To()) - orderedStates.IndexOf(e2->To());
}));
}
/***********************************************************************
EdgeSymbol
***********************************************************************/
EdgeSymbol::EdgeSymbol(StateSymbol* _from, StateSymbol* _to)
: ownerManager(_from->Owner())
, fromState(_from)
, toState(_to)
{
fromState->outEdges.Add(this);
toState->inEdges.Add(this);
}
/***********************************************************************
RuleSymbol
***********************************************************************/
RuleSymbol::RuleSymbol(SyntaxSymbolManager* _ownerManager, const WString& _name)
: ownerManager(_ownerManager)
, name(_name)
{
}
/***********************************************************************
SyntaxSymbolManager
***********************************************************************/
SyntaxSymbolManager::SyntaxSymbolManager(ParserSymbolManager& _global)
: global(_global)
{
}
RuleSymbol* SyntaxSymbolManager::CreateRule(const WString& name, ParsingTextRange codeRange)
{
CHECK_ERROR(states.Count() + edges.Count() == 0, L"vl::gre::parsergen::SyntaxSymbolManager::CreateRule(const WString&)#Cannot create new rules after building the automaton.");
auto rule = new RuleSymbol(this, name);
if (!rules.Add(name, rule))
{
AddError(
ParserErrorType::DuplicatedRule,
codeRange,
name
);
}
return rule;
}
StateSymbol* SyntaxSymbolManager::CreateState(RuleSymbol* rule, vint32_t clauseId)
{
CHECK_ERROR(phase == SyntaxPhase::EpsilonNFA, L"vl::gre::parsergen::SyntaxSymbolManager::CreateState(RuleSymbol*)#Cannot change the automaton after calling BuildCompactSyntax().");
auto symbol = new StateSymbol(rule, clauseId);
states.Add(symbol);
return symbol;
}
EdgeSymbol* SyntaxSymbolManager::CreateEdge(StateSymbol* from, StateSymbol* to)
{
CHECK_ERROR(phase == SyntaxPhase::EpsilonNFA, L"vl::gre::parsergen::SyntaxSymbolManager::CreateEdge(StateSymbol*, StateSymbol*)#Cannot change the automaton after calling BuildCompactSyntax().");
auto symbol = new EdgeSymbol(from, to);
edges.Add(symbol);
return symbol;
}
void SyntaxSymbolManager::BuildCompactNFA()
{
CHECK_ERROR(global.Errors().Count() == 0, L"vl::gre::parsergen::SyntaxSymbolManager::BuildCompactSyntax()#BuildCompactNFA() cannot be called before errors are resolved.");
CHECK_ERROR(phase == SyntaxPhase::EpsilonNFA, L"vl::gre::parsergen::SyntaxSymbolManager::BuildCompactSyntax()#BuildCompactNFA() can only be called on epsilon NFA.");
BuildCompactNFAInternal();
phase = SyntaxPhase::CompactNFA;
}
void SyntaxSymbolManager::BuildCrossReferencedNFA()
{
CHECK_ERROR(global.Errors().Count() == 0, L"vl::gre::parsergen::SyntaxSymbolManager::BuildCompactSyntax()#BuildCrossReferencedNFA() cannot be called before errors are resolved.");
CHECK_ERROR(phase == SyntaxPhase::CompactNFA, L"vl::gre::parsergen::SyntaxSymbolManager::BuildCompactSyntax()#BuildCrossReferencedNFA() can only be called on compact NFA.");
BuildCrossReferencedNFAInternal();
phase = SyntaxPhase::CrossReferencedNFA;
}
void SyntaxSymbolManager::GetStatesInStableOrder(collections::List<StateSymbol*>& order)
{
Group<RuleSymbol*, StateSymbol*> groupedStates;
{
List<StateSymbol*> visited;
for (auto ruleName : rules.order)
{
auto ruleSymbol = rules.map[ruleName];
for (auto startState : ruleSymbol->startStates)
{
if (!visited.Contains(startState))
{
vint startIndex = visited.Add(startState);
for (vint i = startIndex; i < visited.Count(); i++)
{
auto state = visited[i];
groupedStates.Add(state->Rule(), state);
for (auto edge : state->OutEdges())
{
auto target = edge->To();
if (!visited.Contains(target))
{
visited.Add(target);
}
}
}
}
}
}
}
{
vint counter = 0;
for (auto ruleName : rules.order)
{
auto ruleSymbol = rules.map[ruleName];
auto orderedStates = From(groupedStates[ruleSymbol])
.OrderBy([](StateSymbol* s1, StateSymbol* s2)
{
return WString::Compare(s1->label, s2->label);
});
for (auto state : orderedStates)
{
order.Add(state);
}
}
}
}
WString SyntaxSymbolManager::GetStateGlobalLabel(StateSymbol* state, vint index)
{
return L"[" + itow(index) + L"][" + state->Rule()->Name() + L"]" + state->label + (state->endingState ? L"[ENDING]" : L"");
}
}
}
}
/***********************************************************************
.\SYNTAX\SYNTAXSYMBOL_AUTOMATON.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
/***********************************************************************
SyntaxSymbolManager::BuildAutomaton
***********************************************************************/
void SyntaxSymbolManager::BuildAutomaton(vint tokenCount, automaton::Executable& executable, automaton::Metadata& metadata)
{
CHECK_ERROR(global.Errors().Count() == 0, L"vl::gre::parsergen::SyntaxSymbolManager::BuildAutomaton(Executable&, Metadata&)#BuildAutomaton() cannot be called before errors are resolved.");
CHECK_ERROR(phase == SyntaxPhase::CrossReferencedNFA, L"vl::gre::parsergen::SyntaxSymbolManager::BuildAutomaton(Executable&, Metadata&)#BuildAutomaton() can only be called on cross referenced NFA.");
// metadata.ruleNames
List<RuleSymbol*> rulesInOrder;
CopyFrom(rulesInOrder, From(rules.order).Select([this](auto&& name) { return rules.map[name]; }));
metadata.ruleNames.Resize(rulesInOrder.Count());
for (auto [rule, index] : indexed(rulesInOrder))
{
metadata.ruleNames[index] = rule->Name();
}
// metadata.stateLabels
List<StateSymbol*> statesInOrder;
GetStatesInStableOrder(statesInOrder);
metadata.stateLabels.Resize(statesInOrder.Count());
for (auto [state, index] : indexed(statesInOrder))
{
metadata.stateLabels[index] = GetStateGlobalLabel(state, index);
}
executable.tokenCount = (vint32_t)tokenCount;
executable.ruleCount = (vint32_t)rulesInOrder.Count();
// executable.ruleStartStates
executable.ruleStartStates.Resize(rulesInOrder.Count());
for (auto [rule, index] : indexed(rulesInOrder))
{
executable.ruleStartStates[index] = (vint32_t)statesInOrder.IndexOf(rule->startStates[0]);
}
// executable.states
executable.states.Resize(statesInOrder.Count());
for (auto [state, index] : indexed(statesInOrder))
{
auto&& stateDesc = executable.states[index];
stateDesc.rule = (vint32_t)rulesInOrder.IndexOf(state->Rule());
stateDesc.clause = state->ClauseId();
stateDesc.endingState = state->endingState;
}
List<EdgeSymbol*> edgesInOrder;
List<EdgeSymbol*> returnEdgesInOrder;
List<vint32_t> returnIndicesInOrder;
List<AstIns> instructionsInOrder;
// executable.transitions
vint inputCount = automaton::Executable::TokenBegin + tokenCount;
executable.transitions.Resize(statesInOrder.Count() * inputCount);
for (auto [state, stateIndex] : indexed(statesInOrder))
{
for (vint input = 0; input < inputCount; input++)
{
auto&& transition = executable.transitions[stateIndex * inputCount + input];
auto orderedEdges = From(state->OutEdges())
.Where([&](EdgeSymbol* edge)
{
switch (input)
{
case automaton::Executable::EndingInput:
return edge->input.type == EdgeInputType::Ending;
case automaton::Executable::LeftrecInput:
return edge->input.type == EdgeInputType::LeftRec;
default:
return edge->input.type == EdgeInputType::Token && edge->input.token == input - automaton::Executable::TokenBegin;
}
})
.OrderBy([&](EdgeSymbol* e1, EdgeSymbol* e2)
{
return statesInOrder.IndexOf(e1->To()) - statesInOrder.IndexOf(e2->To());
});
transition.start = (vint32_t)edgesInOrder.Count();
CopyFrom(edgesInOrder, orderedEdges, true);
transition.count = (vint32_t)edgesInOrder.Count() - transition.start;
if (transition.count == 0)
{
transition.start = -1;
continue;
}
}
}
// executable.edges
executable.edges.Resize(edgesInOrder.Count());
for (auto [edge, edgeIndex] : indexed(edgesInOrder))
{
auto&& edgeDesc = executable.edges[edgeIndex];
edgeDesc.fromState = (vint32_t)statesInOrder.IndexOf(edge->From());
edgeDesc.toState = (vint32_t)statesInOrder.IndexOf(edge->To());
switch (edge->importancy)
{
case EdgeImportancy::HighPriority:
edgeDesc.priority = automaton::EdgePriority::HighPriority;
break;
case EdgeImportancy::LowPriority:
edgeDesc.priority = automaton::EdgePriority::LowPriority;
break;
default:;
}
edgeDesc.insBeforeInput.start = (vint32_t)instructionsInOrder.Count();
CopyFrom(instructionsInOrder, edge->insBeforeInput, true);
edgeDesc.insBeforeInput.count = (vint32_t)instructionsInOrder.Count() - edgeDesc.insBeforeInput.start;
edgeDesc.insAfterInput.start = (vint32_t)instructionsInOrder.Count();
CopyFrom(instructionsInOrder, edge->insAfterInput, true);
edgeDesc.insAfterInput.count = (vint32_t)instructionsInOrder.Count() - edgeDesc.insAfterInput.start;
edgeDesc.returnIndices.start = (vint32_t)returnIndicesInOrder.Count();
for (auto returnEdge : edge->returnEdges)
{
vint index = returnEdgesInOrder.IndexOf(returnEdge);
if (index == -1)
{
index = returnEdgesInOrder.Add(returnEdge);
}
returnIndicesInOrder.Add((vint32_t)index);
}
edgeDesc.returnIndices.count = (vint32_t)returnIndicesInOrder.Count() - edgeDesc.returnIndices.start;
if (edgeDesc.insBeforeInput.count == 0) edgeDesc.insBeforeInput.start = -1;
if (edgeDesc.insAfterInput.count == 0) edgeDesc.insAfterInput.start = -1;
if (edgeDesc.returnIndices.count == 0) edgeDesc.returnIndices.start = -1;
}
// executable.returns
executable.returns.Resize(returnEdgesInOrder.Count());
for (auto [edge, edgeIndex] : indexed(returnEdgesInOrder))
{
auto&& returnDesc = executable.returns[edgeIndex];
returnDesc.consumedRule = (vint32_t)rulesInOrder.IndexOf(edge->input.rule);
returnDesc.returnState = (vint32_t)statesInOrder.IndexOf(edge->To());
switch (edge->importancy)
{
case EdgeImportancy::HighPriority:
returnDesc.priority = automaton::EdgePriority::HighPriority;
break;
case EdgeImportancy::LowPriority:
returnDesc.priority = automaton::EdgePriority::LowPriority;
break;
default:;
}
returnDesc.insAfterInput.start = (vint32_t)instructionsInOrder.Count();
CopyFrom(instructionsInOrder, edge->insAfterInput, true);
returnDesc.insAfterInput.count = (vint32_t)instructionsInOrder.Count() - returnDesc.insAfterInput.start;
if (returnDesc.insAfterInput.count == 0) returnDesc.insAfterInput.start = -1;
}
// executable.returnIndices
CopyFrom(executable.returnIndices, returnIndicesInOrder);
// executable.instructions
CopyFrom(executable.instructions, instructionsInOrder);
}
}
}
}
/***********************************************************************
.\SYNTAX\SYNTAXSYMBOL_CREATEPARSERGENRULESYNTAX.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace syntax_writer;
extern syntax_writer::Token tok(ParserGenTokens id);
extern syntax_writer::Token tok(ParserGenTokens id, ParserGenFields field);
/***********************************************************************
CreateParserGenRuleSyntax
***********************************************************************/
void CreateParserGenRuleSyntax(SyntaxSymbolManager& manager)
{
manager.name = L"RuleParser";
auto _optionalBody = manager.CreateRule(L"OptionalBody");
auto _syntax0 = manager.CreateRule(L"Syntax0");
auto _syntax1 = manager.CreateRule(L"Syntax1");
auto _syntax2 = manager.CreateRule(L"Syntax2");
auto _syntax = manager.CreateRule(L"Syntax");
auto _assignment = manager.CreateRule(L"Assignment");
auto _clause = manager.CreateRule(L"Clause");
auto _rule = manager.CreateRule(L"Rule");
auto _file = manager.CreateRule(L"File");
manager.parsableRules.Add(_file);
manager.ruleTypes.Add(_file, L"vl::glr::parsergen::GlrSyntaxFile");
using T = ParserGenTokens;
using C = ParserGenClasses;
using F = ParserGenFields;
// "[" Syntax:syntax "]" as partial OptionalSyntax
Clause{ _optionalBody } = partial(tok(T::OPEN_SQUARE) + rule(_syntax, F::OptionalSyntax_syntax) + tok(T::CLOSE_SQUARE));
// ID:name [":" ID:field] as RefSyntax
Clause{ _syntax0 } = create(tok(T::ID, F::RefSyntax_name) + opt(tok(T::COLON) + tok(T::ID, F::RefSyntax_field)), C::RefSyntax);
// STRING:value as LiteralSyntax
Clause{ _syntax0 } = create(tok(T::STRING, F::LiteralSyntax_value), C::LiteralSyntax);
// "!" ID:name as UseSyntax
Clause{ _syntax0 } = create(tok(T::USE) + tok(T::ID, F::UseSyntax_name), C::UseSyntax);
// "{" Syntax:syntax [";" syntax:delimiter] "}" as LoopSyntax
Clause{ _syntax0 } = create(tok(T::OPEN_CURLY) + rule(_syntax, F::LoopSyntax_syntax) + opt(tok(T::SEMICOLON) + rule(_syntax, F::LoopSyntax_delimiter)) + tok(T::CLOSE_CURLY), C::LoopSyntax);
// "+" OptionalBody as OptionalSyntax {priority = PreferTake}
Clause{ _syntax0 } = create(tok(T::POSITIVE) + prule(_optionalBody), C::OptionalSyntax).with(F::OptionalSyntax_priority, GlrOptionalPriority::PreferTake);
// "-" OptionalBody as OptionalSyntax {priority = PreferSkip}
Clause{ _syntax0 } = create(tok(T::NEGATIVE) + prule(_optionalBody), C::OptionalSyntax).with(F::OptionalSyntax_priority, GlrOptionalPriority::PreferSkip);
// OptionalBody as OptionalSyntax {priority = Equal}
Clause{ _syntax0 } = create(prule(_optionalBody), C::OptionalSyntax).with(F::OptionalSyntax_priority, GlrOptionalPriority::Equal);
// "(" !Syntax ")"
Clause{ _syntax0 } = tok(T::OPEN_ROUND) + use(_syntax) + tok(T::CLOSE_ROUND);
// !Syntax0
Clause{ _syntax1 } = use(_syntax0);
// Syntax1:first Syntax0:second as SequenceSyntax
Clause{ _syntax1 } = create(rule(_syntax1, F::SequenceSyntax_first) + rule(_syntax0, F::SequenceSyntax_second), C::SequenceSyntax);
// !Syntax1
Clause{ _syntax2 } = use(_syntax1);
// Syntax2:first "|" Syntax1:second as AlternativeSyntax
Clause{ _syntax2 } = create(rule(_syntax2, F::AlternativeSyntax_first) + tok(T::ALTERNATIVE) + rule(_syntax1, F::AlternativeSyntax_second), C::AlternativeSyntax);
// !Syntax2
Clause{ _syntax } = use(_syntax2);
// ID:field "=" STRING:value as partial Assignment
Clause{ _assignment } = create(tok(T::ID, F::Assignment_field) + tok(T::ASSIGN) + tok(T::ID, F::Assignment_value), C::Assignment);
// Syntax:syntax "as" ID:type ["{" {Assignment:assignments ; ","} "}"] as CreateClause
Clause{ _clause } = create(rule(_syntax, F::CreateClause_syntax) + tok(T::AS) + tok(T::ID, F::CreateClause_type) + opt(tok(T::OPEN_CURLY) + loop(rule(_assignment, F::CreateClause_assignments), tok(T::COMMA)) + tok(T::CLOSE_CURLY)), C::CreateClause);
// Syntax:syntax "as" "partial" ID:type ["{" {Assignment:assignments ; ","} "}"] as PartialClause
Clause{ _clause } = create(rule(_syntax, F::PartialClause_syntax) + tok(T::AS) + tok(T::PARTIAL) + tok(T::ID, F::PartialClause_type) + opt(tok(T::OPEN_CURLY) + loop(rule(_assignment, F::PartialClause_assignments), tok(T::COMMA)) + tok(T::CLOSE_CURLY)), C::PartialClause);
// Syntax:syntax ["{" {Assignment:assignments ; ","} "}"] as ReuseClause
Clause{ _clause } = create(rule(_syntax, F::ReuseClause_syntax) + opt(tok(T::OPEN_CURLY) + loop(rule(_assignment, F::ReuseClause_assignments), tok(T::COMMA)) + tok(T::CLOSE_CURLY)), C::ReuseClause);
// ID:name {"::=" Clause:clauses} ";" as Rule
Clause{ _rule } = create(tok(T::ID, F::Rule_name) + loop(tok(T::INFER) + rule(_clause, F::Rule_clauses)) + tok(T::SEMICOLON), C::Rule);
// Rule:rules {Rule:rules} as SyntaxFile
Clause{ _file } = create(rule(_rule, F::SyntaxFile_rules) + loop(rule(_rule, F::SyntaxFile_rules)), C::SyntaxFile);
}
}
}
}
/***********************************************************************
.\SYNTAX\SYNTAXSYMBOL_CREATEPARSERGENTYPESYNTAX.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
using namespace syntax_writer;
extern syntax_writer::Token tok(ParserGenTokens id);
extern syntax_writer::Token tok(ParserGenTokens id, ParserGenFields field);
/***********************************************************************
CreateParserGenTypeSyntax
***********************************************************************/
void CreateParserGenTypeSyntax(SyntaxSymbolManager& manager)
{
manager.name = L"TypeParser";
auto _enumItem = manager.CreateRule(L"EnumItem");
auto _enum = manager.CreateRule(L"Enum");
auto _classPropType = manager.CreateRule(L"ClassPropType");
auto _classProp = manager.CreateRule(L"classProp");
auto _classBody = manager.CreateRule(L"ClassBody");
auto _class = manager.CreateRule(L"Class");
auto _type = manager.CreateRule(L"Type");
auto _file = manager.CreateRule(L"File");
manager.parsableRules.Add(_file);
manager.ruleTypes.Add(_file, L"vl::glr::parsergen::GlrAstFile");
using T = ParserGenTokens;
using C = ParserGenClasses;
using F = ParserGenFields;
// ID:name "," as EnumItem
Clause{ _enumItem } = create(tok(T::ID, F::EnumItem_name) + tok(T::COMMA), C::EnumItem);
// "enum" ID:name "{" {EnumItem} "}" as Enum
Clause{ _enum } = create(tok(T::ENUM) + tok(T::ID, F::Type_name) + tok(T::OPEN_CURLY) + loop(rule(_enumItem, F::Enum_items)) + tok(T::CLOSE_CURLY), C::Enum);
// "token" as partial ClassProp {propType = "Token"}
Clause{ _classPropType } = partial(tok(T::TOKEN)).with(F::ClassProp_propType, GlrPropType::Token);
// ID:propTypeName as partial ClassProp {propType = "Type"}
Clause{ _classPropType } = partial(tok(T::ID, F::ClassProp_propTypeName)).with(F::ClassProp_propType, GlrPropType::Type);
// ID:propTypeName "[" "]" as partial ClassProp {propType = "Array"}
Clause{ _classPropType } = partial(tok(T::ID, F::ClassProp_propTypeName) + tok(T::OPEN_SQUARE) + tok(T::CLOSE_SQUARE)).with(F::ClassProp_propType, GlrPropType::Array);
// "var" ID:name ":" ClassPropType ";" as ClassProp
Clause{ _classProp } = create(tok(T::VAR) + tok(T::ID, F::ClassProp_name) + tok(T::COLON) + prule(_classPropType) + tok(T::SEMICOLON), C::ClassProp);
// ID:name [":" ID:baseClass] "{" {ClassProp} "}" as partial Class
Clause{ _classBody } = partial(tok(T::ID, F::Type_name) + opt(tok(T::COLON) + tok(T::ID, F::Class_baseClass)) + tok(T::OPEN_CURLY) + loop(rule(_classProp, F::Class_props)) + tok(T::CLOSE_CURLY));
// "class" ClassBody {ambiguity = No}
Clause{ _class } = create(tok(T::CLASS) + prule(_classBody), C::Class).with(F::Class_ambiguity, GlrClassAmbiguity::No);
// "ambiguous" "class" ClassBody {ambiguity = Yes}
Clause{ _class } = create(tok(T::AMBIGUOUS) + tok(T::CLASS) + prule(_classBody), C::Class).with(F::Class_ambiguity, GlrClassAmbiguity::Yes);
// !Class | !Enum
Clause{ _type } = use(_enum) | use(_class);
// type:types {type:types} as AstFile
Clause{ _file } = create(rule(_type, F::AstFile_types) + loop(rule(_type, F::AstFile_types)), C::AstFile);
}
}
}
}
/***********************************************************************
.\SYNTAX\SYNTAXSYMBOL_CREATEPARSERGENUTILITY.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
syntax_writer::Token tok(ParserGenTokens id)
{
auto d = ParserGenTokenDisplayText(id);
auto n = ParserGenTokenId(id);
return syntax_writer::tok(
id,
(d ? L"\"" + WString::Unmanaged(d) + L"\"" : WString::Unmanaged(n))
);
}
syntax_writer::Token tok(ParserGenTokens id, ParserGenFields field)
{
auto d = ParserGenTokenDisplayText(id);
auto n = ParserGenTokenId(id);
return syntax_writer::tok(
id,
(d ? L"\"" + WString::Unmanaged(d) + L"\"" : WString::Unmanaged(n)),
field
);
}
}
}
}
/***********************************************************************
.\SYNTAX\SYNTAXSYMBOL_NFACOMPACT.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
/***********************************************************************
StateSymbolSet
***********************************************************************/
struct StateSymbolSet
{
private:
static const SortedList<StateSymbol*> EmptyStates;
Ptr<SortedList<StateSymbol*>> states;
public:
StateSymbolSet() = default;
StateSymbolSet(const StateSymbolSet&) = delete;
StateSymbolSet& operator=(const StateSymbolSet&) = delete;
StateSymbolSet(StateSymbolSet&& set)
{
states = set.states;
set.states = nullptr;
}
StateSymbolSet& operator=(StateSymbolSet&& set)
{
states = set.states;
set.states = nullptr;
return *this;
}
StateSymbolSet Copy() const
{
StateSymbolSet set;
set.states = states;
return set;
}
bool Add(StateSymbol* state)
{
if (states)
{
if (states->Contains(state)) return false;
states->Add(state);
return true;
}
else
{
states = new SortedList<StateSymbol*>();
states->Add(state);
return true;
}
}
const SortedList<StateSymbol*>& States() const
{
return states ? *states.Obj() : EmptyStates;
}
vint Compare(const StateSymbolSet& set) const
{
if (!states && !set.states) return 0;
if (!states) return -1;
if (!set.states) return 1;
return CompareEnumerable(*states.Obj(), *set.states.Obj());
}
bool operator==(const StateSymbolSet& set) const { return Compare(set) == 0; }
bool operator!=(const StateSymbolSet& set) const { return Compare(set) != 0; }
bool operator< (const StateSymbolSet& set) const { return Compare(set) < 0; }
bool operator<=(const StateSymbolSet& set) const { return Compare(set) <= 0; }
bool operator> (const StateSymbolSet& set) const { return Compare(set) > 0; }
bool operator>=(const StateSymbolSet& set) const { return Compare(set) >= 0; }
};
const SortedList<StateSymbol*> StateSymbolSet::EmptyStates;
/***********************************************************************
CompactSyntaxBuilder
***********************************************************************/
class CompactSyntaxBuilder
{
using StateList = collections::List<Ptr<StateSymbol>>;
using EdgeList = collections::List<Ptr<EdgeSymbol>>;
protected:
RuleSymbol* rule;
StateList& newStates;
EdgeList& newEdges;
Dictionary<StateSymbol*, StateSymbol*> oldToNew;
Dictionary<StateSymbol*, StateSymbol*> newToOld;
void BuildEpsilonEliminatedEdgesInternal(
StateSymbol* walkingOldState,
StateSymbol* newState,
StateSymbol* endState,
List<StateSymbol*>& visited,
List<EdgeSymbol*>& accumulatedEdges)
{
/*
* walkingOldState : a state in the epsilon-NFA
* newState : a state in the compact-NFA
* it represents the mirrored walkingOldState in the first call when accumulatedEdges is empty
* in future recursive calls, walkingOldState keeps changing, but newState stays the same
* endState : the ending state of the rule
* visited : stores any new discovered epsilon-NFA states
* duplicated states will not be added to this list
* accumulatedEdges : epsilon edges from the first walkingOldState to the current walkingOldState
*/
for (auto edge : walkingOldState->OutEdges())
{
accumulatedEdges.Add(edge);
switch (edge->input.type)
{
case EdgeInputType::Token:
case EdgeInputType::Rule:
{
auto targetNewState = CreateCompactState(edge->To());
if (!visited.Contains(targetNewState))
{
visited.Add(targetNewState);
}
auto newEdge = new EdgeSymbol(newState, targetNewState);
newEdges.Add(newEdge);
newEdge->input = edge->input;
newEdge->important |= edge->important;
for (auto accumulatedEdge : accumulatedEdges)
{
CopyFrom(newEdge->insBeforeInput, accumulatedEdge->insBeforeInput, true);
CopyFrom(newEdge->insAfterInput, accumulatedEdge->insAfterInput, true);
newEdge->important |= accumulatedEdge->important;
}
}
break;
case EdgeInputType::Epsilon:
BuildEpsilonEliminatedEdgesInternal(edge->To(), newState, endState, visited, accumulatedEdges);
break;
default:;
}
accumulatedEdges.RemoveAt(accumulatedEdges.Count() - 1);
}
if (walkingOldState->endingState)
{
auto newEdge = new EdgeSymbol(newState, endState);
newEdge->input.type = EdgeInputType::Ending;
for (auto accumulatedEdge : accumulatedEdges)
{
CopyFrom(newEdge->insBeforeInput, accumulatedEdge->insBeforeInput, true);
CopyFrom(newEdge->insAfterInput, accumulatedEdge->insAfterInput, true);
newEdge->important |= accumulatedEdge->important;
}
for (auto endingEdge : newState->OutEdges())
{
if (endingEdge != newEdge && endingEdge->input.type == EdgeInputType::Ending)
{
if (
CompareEnumerable(endingEdge->insBeforeInput, newEdge->insBeforeInput) == 0 &&
CompareEnumerable(endingEdge->insAfterInput, newEdge->insAfterInput) == 0)
{
CHECK_ERROR(newEdge->important == endingEdge->important, L"It is not possible to have two equal ending edges with different priority.");
newState->outEdges.Remove(newEdge);
endState->inEdges.Remove(newEdge);
delete newEdge;
goto DISCARD_ENDING_EDGE;
}
}
}
newEdges.Add(newEdge);
DISCARD_ENDING_EDGE:;
}
}
public:
CompactSyntaxBuilder(RuleSymbol* _rule, StateList& _newStates, EdgeList& _newEdges)
: rule(_rule)
, newStates(_newStates)
, newEdges(_newEdges)
{
}
StateSymbol* CreateCompactState(StateSymbol* state)
{
vint index = oldToNew.Keys().IndexOf(state);
if (index != -1)
{
return oldToNew.Values()[index];
}
else
{
auto newState = new StateSymbol(rule, state->ClauseId());
newState->label = state->label;
newStates.Add(newState);
oldToNew.Add(state, newState);
newToOld.Add(newState, state);
return newState;
}
}
void BuildEpsilonEliminatedEdges(
StateSymbol* newState,
StateSymbol* endState,
List<StateSymbol*>& visited)
{
List<EdgeSymbol*> accumulatedEdges;
BuildEpsilonEliminatedEdgesInternal(newToOld[newState], newState, endState, visited, accumulatedEdges);
}
};
/***********************************************************************
SyntaxSymbolManager::CreateLeftRecEdge
***********************************************************************/
void SyntaxSymbolManager::BuildLeftRecEdge(EdgeSymbol* newEdge, EdgeSymbol* endingEdge, EdgeSymbol* lrecPrefixEdge)
{
newEdge->important |= endingEdge->important;
newEdge->important |= lrecPrefixEdge->important;
newEdge->input.type = EdgeInputType::LeftRec;
CopyFrom(newEdge->insBeforeInput, endingEdge->insBeforeInput, true);
CopyFrom(newEdge->insAfterInput, endingEdge->insAfterInput, true);
CopyFrom(newEdge->insBeforeInput, lrecPrefixEdge->insBeforeInput, true);
CopyFrom(newEdge->insAfterInput, lrecPrefixEdge->insAfterInput, true);
for (vint i = 0; i < newEdge->insBeforeInput.Count(); i++)
{
auto& ins = newEdge->insBeforeInput[i];
if (ins.type == AstInsType::BeginObject)
{
ins.type = AstInsType::BeginObjectLeftRecursive;
}
}
for (vint i = 0; i < newEdge->insAfterInput.Count(); i++)
{
auto& ins = newEdge->insAfterInput[i];
if (ins.type == AstInsType::BeginObject)
{
ins.type = AstInsType::BeginObjectLeftRecursive;
}
}
}
/***********************************************************************
SyntaxSymbolManager::EliminateLeftRecursion
***********************************************************************/
void SyntaxSymbolManager::EliminateLeftRecursion(RuleSymbol* rule, StateSymbol* startState, StateSymbol* endState, StateList& newStates, EdgeList& newEdges)
{
/*
* Move the single rule prefix from the rule begin state
* if it is left recursive
*
* [BEFORE] (r is the current rule)
* +-> ... -> A --------(ending)-+
* | |
* S -+-(r)----> ... -> B -(ending)-+-> E
* | --- |
* +-(r)----> ... -> C -(ending)-+
*
* [AFTER] (the epsilon edge doesn't exist, it is for demo only)
* +----(epsilon)----------+
* | |
* | +-(leftrec)-> ... -> B -(ending)---+
* v | v
* S-> ... -> A -+-----------------------(ending)-> E
* ^ | ^
* | +-(leftrec)-> ... -> C -(ending)---+
* | |
* +----(epsilon)----------+
*/
List<EdgeSymbol*> lrecEdges;
for (auto edge : startState->OutEdges())
{
if (edge->input.type != EdgeInputType::Rule) continue;
if (edge->input.rule != rule) continue;
lrecEdges.Add(edge);
}
for (auto lrecEdge : lrecEdges)
{
for (auto endingEdge : endState->InEdges())
{
auto state = endingEdge->From();
auto newEdge = new EdgeSymbol(state, lrecEdge->To());
newEdges.Add(newEdge);
BuildLeftRecEdge(newEdge, endingEdge, lrecEdge);
}
}
for (auto lrecEdge : lrecEdges)
{
lrecEdge->From()->outEdges.Remove(lrecEdge);
lrecEdge->To()->inEdges.Remove(lrecEdge);
newEdges.Remove(lrecEdge);
}
}
/***********************************************************************
SyntaxSymbolManager::EliminateEpsilonEdges
***********************************************************************/
void SyntaxSymbolManager::EliminateSingleRulePrefix(RuleSymbol* rule, StateSymbol* startState, StateSymbol* endState, StateList& newStates, EdgeList& newEdges)
{
/*
* Move the single rule prefix from the rule begin state
* if there is any single rule clause consist of the same rule
*
* [BEFORE]
* +-(x)-> A --------(ending)-+
* | |
* S -+-(x)-> ... -> B -(ending)-+-> E
* | |
* +-(x)-> ... -> C -(ending)-+
*
* [AFTER]
* +-(leftrec)-> ... -> B -(ending)---+
* | v
* S-(x)-> A -+-----------------------(ending)-> E
* | ^
* +-(leftrec)-> ... -> C -(ending)---+
*/
Group<RuleSymbol*, EdgeSymbol*> prefixEdges;
List<EdgeSymbol*> continuationEdges;
for (auto edge : startState->OutEdges())
{
if (edge->input.type != EdgeInputType::Rule) continue;
if (edge->input.rule == rule) continue;
auto state = edge->To();
if (state->InEdges().Count() > 1) continue;
if (state->OutEdges().Count() == 1 && state->OutEdges()[0]->input.type == EdgeInputType::Ending)
{
prefixEdges.Add(edge->input.rule, edge);
}
else
{
continuationEdges.Add(edge);
}
}
for (auto continuationEdge : continuationEdges)
{
vint prefixIndex = prefixEdges.Keys().IndexOf(continuationEdge->input.rule);
if (prefixIndex == -1) continue;
for (auto prefixEdge : prefixEdges.GetByIndex(prefixIndex))
{
auto state = prefixEdge->To();
auto endingEdge = state->OutEdges()[0];
auto newEdge = new EdgeSymbol(state, continuationEdge->To());
newEdges.Add(newEdge);
BuildLeftRecEdge(newEdge, endingEdge, continuationEdge);
}
}
for (auto continuationEdge : continuationEdges)
{
vint prefixIndex = prefixEdges.Keys().IndexOf(continuationEdge->input.rule);
if (prefixIndex == -1) continue;
continuationEdge->From()->outEdges.Remove(continuationEdge);
continuationEdge->To()->inEdges.Remove(continuationEdge);
newEdges.Remove(continuationEdge);
}
}
/***********************************************************************
SyntaxSymbolManager::EliminateEpsilonEdges
***********************************************************************/
StateSymbol* SyntaxSymbolManager::EliminateEpsilonEdges(RuleSymbol* rule, StateList& newStates, EdgeList& newEdges)
{
/*
* For any transition that goes through some epsilon edge and ends with a non-epsilon edge
* we copy all instructions from epsilon edges and the non-epsilon edge in order
* and create a new edge directly pointing to the toState of the non-epsilon edge
*
* [BEFORE]
* +-(x)-> B
* |
* A -(e1)-+-(e2)-> C -+-(y)-> E
* | |
* +-(e3)-> D -+
*
* [AFTER]
* +-(e1,x)-> B
* |
* A -+-(e1,e2,y)-> E
* | ^
* +-(e1,e3,y)---+
*/
// epsilon-NFAs are per clause
// now we need to create a start state and an ending state
// to connect all epsilon-NFAs of its clauses together
auto psuedoState = CreateState(rule, -1);
for (auto startState : rule->startStates)
{
CreateEdge(psuedoState, startState);
}
CompactSyntaxBuilder builder(rule, newStates, newEdges);
auto compactStartState = builder.CreateCompactState(psuedoState);
compactStartState->label = L" BEGIN ";
auto compactEndState = new StateSymbol(rule, -1);
compactEndState->label = L" END ";
compactEndState->endingState = true;
newStates.Add(compactEndState);
List<StateSymbol*> visited;
visited.Add(compactStartState);
// all epsilon-NFAs of its clauses become one connected epsilon-NFA of this rule
// we can build the compact-NFA out of this epsilon-NFA starting from the start state
for (vint i = 0; i < visited.Count(); i++)
{
auto current = visited[i];
builder.BuildEpsilonEliminatedEdges(current, compactEndState, visited);
}
// optimize
EliminateLeftRecursion(rule, compactStartState, compactEndState, newStates, newEdges);
EliminateSingleRulePrefix(rule, compactStartState, compactEndState, newStates, newEdges);
return compactStartState;
}
/***********************************************************************
SyntaxSymbolManager::BuildCompactNFAInternal
***********************************************************************/
void SyntaxSymbolManager::BuildCompactNFAInternal()
{
StateList newStates;
EdgeList newEdges;
for (auto ruleSymbol : rules.map.Values())
{
auto startState = EliminateEpsilonEdges(ruleSymbol, newStates, newEdges);
ruleSymbol->startStates.Clear();
ruleSymbol->startStates.Add(startState);
}
CopyFrom(states, newStates);
CopyFrom(edges, newEdges);
// only when a state has any important out edge
// its out edges are marked accordingly
for (auto state : states)
{
bool competition = false;
for (auto edge : state->OutEdges())
{
if (edge->important)
{
competition = true;
break;
}
}
if (competition)
{
for (auto edge : state->OutEdges())
{
edge->importancy = edge->important ? EdgeImportancy::HighPriority : EdgeImportancy::LowPriority;
}
}
}
}
}
}
}
/***********************************************************************
.\SYNTAX\SYNTAXSYMBOL_NFACROSSREFERENCED.CPP
***********************************************************************/
namespace vl
{
namespace glr
{
namespace parsergen
{
using namespace collections;
/***********************************************************************
SyntaxSymbolManager::FixCrossReferencedRuleEdge
***********************************************************************/
void SyntaxSymbolManager::FixCrossReferencedRuleEdge(StateSymbol* startState, collections::Group<StateSymbol*, EdgeSymbol*>& orderedEdges, collections::List<EdgeSymbol*>& accumulatedEdges)
{
auto lastEdge = accumulatedEdges[accumulatedEdges.Count() - 1];
auto lastRule = lastEdge->input.rule;
auto ruleBegin = lastRule->startStates[0];
vint index = orderedEdges.Keys().IndexOf(ruleBegin);
if (index == -1) return;
for (auto edge : orderedEdges.GetByIndex(index))
{
switch (edge->input.type)
{
case EdgeInputType::Token:
if (edge->returnEdges.Count() == 0)
{
auto newEdge = new EdgeSymbol(startState, edge->To());
edges.Add(newEdge);
newEdge->input = edge->input;
newEdge->importancy = edge->importancy;
for (auto acc : accumulatedEdges)
{
CopyFrom(newEdge->insBeforeInput, acc->insBeforeInput, true);
newEdge->returnEdges.Add(acc);
}
CopyFrom(newEdge->insBeforeInput, edge->insBeforeInput, true);
CopyFrom(newEdge->insAfterInput, edge->insAfterInput, true);
}
break;
case EdgeInputType::Rule:
if (accumulatedEdges.Contains(edge))
{
AddError(
ParserErrorType::RuleIsIndirectlyLeftRecursive,
{},
edge->input.rule->Name()
);
}
else
{
accumulatedEdges.Add(edge);
FixCrossReferencedRuleEdge(startState, orderedEdges, accumulatedEdges);
accumulatedEdges.RemoveAt(accumulatedEdges.Count() - 1);
}
break;
default:;
}
}
}
/***********************************************************************
SyntaxSymbolManager::BuildCrossReferencedNFAInternal
***********************************************************************/
void SyntaxSymbolManager::BuildCrossReferencedNFAInternal()
{
List<StateSymbol*> states;
GetStatesInStableOrder(states);
Group<StateSymbol*, EdgeSymbol*> orderedEdges;
for (auto state : states)
{
List<EdgeSymbol*> edges;
state->GetOutEdgesInStableOrder(states, edges);
for (auto edge : edges)
{
orderedEdges.Add(state, edge);
}
}
for (auto state : states)
{
vint index = orderedEdges.Keys().IndexOf(state);
if (index != -1)
{
for (auto edge : orderedEdges.GetByIndex(index))
{
if (edge->input.type == EdgeInputType::Rule)
{
List<EdgeSymbol*> accumulatedEdges;
accumulatedEdges.Add(edge);
FixCrossReferencedRuleEdge(edge->From(), orderedEdges, accumulatedEdges);
}
}
}
}
}
}
}
}