mirror of
https://github.com/vczh-libraries/Release.git
synced 2026-05-26 01:35:31 +08:00
Update release
This commit is contained in:
@@ -4254,6 +4254,7 @@ Event Receiver
|
||||
,lostFocus(_sender)
|
||||
,caretNotify(_sender)
|
||||
,clipboardNotify(_sender)
|
||||
,renderTargetChanged(_sender)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+229
-4
@@ -2632,7 +2632,13 @@ Input
|
||||
|
||||
// if competitions happen between new surviving traces
|
||||
// remove traces that known to have lost the competition
|
||||
CheckBackupTracesBeforeSwapping(currentTokenIndex);
|
||||
if (CheckBackupTracesBeforeSwapping(currentTokenIndex))
|
||||
{
|
||||
// after competition are closed
|
||||
// different surviving traces might be mergable
|
||||
// merge them and remove unnecessary traces
|
||||
TryMergeSurvivingTraces();
|
||||
}
|
||||
|
||||
EndSwap();
|
||||
|
||||
@@ -2806,6 +2812,7 @@ namespace vl
|
||||
{
|
||||
namespace automaton
|
||||
{
|
||||
using namespace collections;
|
||||
|
||||
/***********************************************************************
|
||||
EnsureTraceWithValidStates
|
||||
@@ -2831,7 +2838,7 @@ AreTwoEndingInputTraceEqual
|
||||
{
|
||||
// two traces equal to each other if
|
||||
// 1) they are in the same state
|
||||
// 2) they have the same executedReturnStack (and therefore the same returnStack)
|
||||
// 2) they have the same executedReturnStack and returnStack
|
||||
// 3) they are attending same competitions
|
||||
// 4) they have the same switchValues
|
||||
// 5) the candidate has an ending input
|
||||
@@ -2850,7 +2857,7 @@ AreTwoEndingInputTraceEqual
|
||||
MergeTwoEndingInputTrace
|
||||
***********************************************************************/
|
||||
|
||||
void TraceManager::MergeTwoEndingInputTrace(Trace* newTrace, Trace* candidate)
|
||||
Trace* TraceManager::MergeTwoEndingInputTrace(Trace* newTrace, Trace* candidate)
|
||||
{
|
||||
// goal of this function is to create a structure
|
||||
// NEWTRACE ---+->AMBIGUITY
|
||||
@@ -2861,9 +2868,14 @@ MergeTwoEndingInputTrace
|
||||
// a former trace will copy CANDIDATE and insert before CANDIDATE
|
||||
// and CANDIDATE will be initialized to an empty trace
|
||||
|
||||
// if a former trace is created to replace the candidate
|
||||
// in which case the candidate becomes a merge trace
|
||||
// the former trace is returned
|
||||
|
||||
if (candidate->state == -1)
|
||||
{
|
||||
AddTraceToCollection(candidate, newTrace, &Trace::predecessors);
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2879,8 +2891,211 @@ MergeTwoEndingInputTrace
|
||||
|
||||
AddTraceToCollection(candidate, formerTrace, &Trace::predecessors);
|
||||
AddTraceToCollection(candidate, newTrace, &Trace::predecessors);
|
||||
return formerTrace;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
TryMergeSurvivingTraces
|
||||
***********************************************************************/
|
||||
|
||||
void TraceManager::TryMergeSurvivingTraces()
|
||||
{
|
||||
#define ERROR_MESSAGE_PREFIX L"vl::glr::automaton::TraceManager::TryMergeSurvivingTraces()#"
|
||||
if (concurrentCount == 0) return;
|
||||
|
||||
struct EndingOrMergeTraceData
|
||||
{
|
||||
bool surviving = true; // becomes false when this trace does not survive anymore
|
||||
};
|
||||
|
||||
vint32_t removedTracesCount = 0;
|
||||
Dictionary<Trace*, EndingOrMergeTraceData> endingOrMergeTraces;
|
||||
Group<vint32_t, Trace*> endingOrMergeTracesByState;
|
||||
|
||||
// index surviving traces
|
||||
for (vint32_t i = 0; i < concurrentCount; i++)
|
||||
{
|
||||
auto trace = backupTraces->Get(i);
|
||||
endingOrMergeTraces.Add(trace, {});
|
||||
|
||||
if (trace->state == -1)
|
||||
{
|
||||
endingOrMergeTracesByState.Add(EnsureTraceWithValidStates(trace)->state, trace);
|
||||
}
|
||||
else if (trace->byInput == Executable::EndingInput)
|
||||
{
|
||||
endingOrMergeTracesByState.Add(trace->state, trace);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined VCZH_MSVC && defined _DEBUG
|
||||
// check assumptions
|
||||
for (vint32_t i = 0; i < concurrentCount; i++)
|
||||
{
|
||||
auto trace = backupTraces->Get(i);
|
||||
if (trace->state == -1)
|
||||
{
|
||||
auto predecessorId = trace->predecessors.first;
|
||||
while (predecessorId != nullref)
|
||||
{
|
||||
auto predecessor = GetTrace(predecessorId);
|
||||
predecessorId = predecessor->predecessors.siblingNext;
|
||||
|
||||
CHECK_ERROR(endingOrMergeTraces.Keys().IndexOf(predecessor) == -1, ERROR_MESSAGE_PREFIX L"Internal error: Predecessors of a merge trace should not survive.");
|
||||
}
|
||||
}
|
||||
else if (trace->byInput == Executable::EndingInput)
|
||||
{
|
||||
CHECK_ERROR(trace->predecessors.first == trace->predecessors.last, ERROR_MESSAGE_PREFIX L"Internal error: Executable::EndingInput trace could not have multiple predecessors.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// unsurvive a trace
|
||||
auto unsurviveTrace = [&](Trace* trace, EndingOrMergeTraceData& data)
|
||||
{
|
||||
if (data.surviving)
|
||||
{
|
||||
data.surviving = false;
|
||||
removedTracesCount++;
|
||||
}
|
||||
};
|
||||
|
||||
// check if a trace survived
|
||||
// if an Executable::EndingInput trace survived but its only predecessor does not
|
||||
// it becomes not survived
|
||||
auto ensureEndingTraceSurvived = [&](Trace* trace)
|
||||
{
|
||||
if (trace == initialTrace) return true;
|
||||
|
||||
auto& data = const_cast<EndingOrMergeTraceData&>(endingOrMergeTraces[trace]);
|
||||
if (!data.surviving) return false;
|
||||
|
||||
if (trace->state != -1)
|
||||
{
|
||||
auto predecessorId = trace->predecessors.first;
|
||||
if (predecessorId != nullref)
|
||||
{
|
||||
auto predecessor = GetTrace(predecessorId);
|
||||
if (!endingOrMergeTraces[predecessor].surviving)
|
||||
{
|
||||
unsurviveTrace(trace, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return data.surviving;
|
||||
};
|
||||
|
||||
// find surviving traces that merge
|
||||
for (vint32_t i = 0; i < concurrentCount; i++)
|
||||
{
|
||||
// get the next surviving Executable::EndingInput trace
|
||||
auto trace = backupTraces->Get(i);
|
||||
if (trace->state != -1 && trace->byInput != Executable::EndingInput) continue;
|
||||
if (!ensureEndingTraceSurvived(trace)) continue;
|
||||
auto realTrace = EnsureTraceWithValidStates(trace);
|
||||
|
||||
// find all traces Executable::EndingInput traces with the same state that after it
|
||||
auto&& candidates = endingOrMergeTracesByState[realTrace->state];
|
||||
vint index = candidates.IndexOf(trace);
|
||||
for (vint j = index + 1; j < candidates.Count(); j++)
|
||||
{
|
||||
// ensure the candidate also survived
|
||||
auto candidate = candidates[j];
|
||||
if (!ensureEndingTraceSurvived(candidate)) continue;
|
||||
auto realCandidate = EnsureTraceWithValidStates(candidate);
|
||||
|
||||
if (AreTwoEndingInputTraceEqual(realTrace, realCandidate))
|
||||
{
|
||||
// merge two traces
|
||||
if (trace == realTrace)
|
||||
{
|
||||
// if trace is an ordinary trace
|
||||
if (candidate == realCandidate)
|
||||
{
|
||||
// if candidate is an ordinary trace
|
||||
// turn trace into a merge trace
|
||||
auto formerTrace = MergeTwoEndingInputTrace(candidate, trace);
|
||||
CHECK_ERROR(formerTrace != nullptr, ERROR_MESSAGE_PREFIX L"Internal error: formerTrace should not be null.");
|
||||
realTrace = formerTrace;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if candidate is a merge trace
|
||||
// turn trace into a merge trace
|
||||
// give the rest of predecessors of candidate to trace
|
||||
auto candidateHead = GetTrace(candidate->predecessors.first);
|
||||
auto candidateNextId = candidateHead->predecessors.siblingNext;
|
||||
|
||||
candidateHead->predecessors.siblingNext = nullref;
|
||||
auto formerTrace = MergeTwoEndingInputTrace(candidateHead, trace);
|
||||
CHECK_ERROR(formerTrace != nullptr, ERROR_MESSAGE_PREFIX L"Internal error: formerTrace should not be null.");
|
||||
realTrace = formerTrace;
|
||||
|
||||
candidateHead->predecessors.siblingNext = candidateNextId;
|
||||
trace->predecessors.last = candidate->predecessors.last;
|
||||
candidate->predecessors.first = nullref;
|
||||
candidate->predecessors.last = nullref;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if trace is a merge trace
|
||||
if (candidate == realCandidate)
|
||||
{
|
||||
// if candidate is an ordinary trace
|
||||
// merge candidate into trace
|
||||
auto formerTrace = MergeTwoEndingInputTrace(candidate, trace);
|
||||
CHECK_ERROR(formerTrace == nullptr, ERROR_MESSAGE_PREFIX L"Internal error: formerTrace should be null.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// if candidate is an ordinary trace
|
||||
// give all predecessors of candidate to trace
|
||||
auto traceTail = GetTrace(trace->predecessors.last);
|
||||
auto candidateHead = GetTrace(candidate->predecessors.first);
|
||||
|
||||
traceTail->predecessors.siblingNext = candidateHead;
|
||||
candidateHead->predecessors.siblingPrev = traceTail;
|
||||
|
||||
trace->predecessors.last = candidate->predecessors.last;
|
||||
candidate->predecessors.first = nullref;
|
||||
candidate->predecessors.last = nullref;
|
||||
}
|
||||
}
|
||||
|
||||
auto& data = const_cast<EndingOrMergeTraceData&>(endingOrMergeTraces[candidate]);
|
||||
unsurviveTrace(candidate, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (removedTracesCount > 0)
|
||||
{
|
||||
// mark all unsurviving traces
|
||||
for (vint32_t i = 0; i < concurrentCount; i++)
|
||||
{
|
||||
auto trace = backupTraces->Get(i);
|
||||
vint index = endingOrMergeTraces.Keys().IndexOf(trace);
|
||||
if (index == -1) continue;
|
||||
if (endingOrMergeTraces.Values()[index].surviving) continue;
|
||||
backupTraces->Set(i, nullptr);
|
||||
}
|
||||
|
||||
// clean up surviving trace list
|
||||
vint writing = 0;
|
||||
for (vint32_t i = 0; i < concurrentCount; i++)
|
||||
{
|
||||
auto trace = backupTraces->Get(i);
|
||||
if (!trace) continue;
|
||||
backupTraces->Set(writing++, trace);
|
||||
}
|
||||
concurrentCount -= removedTracesCount;
|
||||
}
|
||||
|
||||
#undef ERROR_MESSAGE_PREFIX
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3080,8 +3295,9 @@ CheckAttendingCompetitionsOnEndingEdge
|
||||
CheckBackupTracesBeforeSwapping
|
||||
***********************************************************************/
|
||||
|
||||
void TraceManager::CheckBackupTracesBeforeSwapping(vint32_t currentTokenIndex)
|
||||
bool TraceManager::CheckBackupTracesBeforeSwapping(vint32_t currentTokenIndex)
|
||||
{
|
||||
bool closedCompetitions = false;
|
||||
// try to find if any competition could be settled at this moment
|
||||
|
||||
{
|
||||
@@ -3193,6 +3409,7 @@ CheckBackupTracesBeforeSwapping
|
||||
for (vint i = 0; i < concurrentCount; i++)
|
||||
{
|
||||
auto trace = EnsureTraceWithValidStates(backupTraces->Get(i));
|
||||
auto attendingCompetitions = trace->competitionRouting.attendingCompetitions;
|
||||
auto* pnext = &trace->competitionRouting.attendingCompetitions;
|
||||
while (*pnext != nullref)
|
||||
{
|
||||
@@ -3206,7 +3423,15 @@ CheckBackupTracesBeforeSwapping
|
||||
pnext = &ac->nextActiveAC;
|
||||
}
|
||||
}
|
||||
|
||||
if (trace->competitionRouting.attendingCompetitions != attendingCompetitions)
|
||||
{
|
||||
// only check the head node since this could trigger merging
|
||||
closedCompetitions = true;
|
||||
}
|
||||
}
|
||||
|
||||
return closedCompetitions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,6 +567,10 @@ IAstInsReceiver (Code Generation Templates)
|
||||
Ptr<ParsingAstBase> AssemblerResolveAmbiguity(vint32_t type, collections::Array<Ptr<ParsingAstBase>>& candidates, const wchar_t* cppTypeName)
|
||||
{
|
||||
auto ast = Ptr(new TAmbiguity());
|
||||
if (candidates.Count() > 0)
|
||||
{
|
||||
ast->codeRange = candidates[0]->codeRange;
|
||||
}
|
||||
for (auto candidate : candidates)
|
||||
{
|
||||
if (auto typedAst = candidate.Cast<TElement>())
|
||||
@@ -2287,13 +2291,14 @@ TraceManager
|
||||
// Ambiguity
|
||||
Trace* EnsureTraceWithValidStates(Trace* trace);
|
||||
bool AreTwoEndingInputTraceEqual(Trace* newTrace, Trace* candidate);
|
||||
void MergeTwoEndingInputTrace(Trace* newTrace, Trace* candidate);
|
||||
Trace* MergeTwoEndingInputTrace(Trace* newTrace, Trace* candidate);
|
||||
void TryMergeSurvivingTraces();
|
||||
|
||||
// Competition
|
||||
void AttendCompetition(Trace* trace, Ref<AttendingCompetitions>& newAttendingCompetitions, Ref<AttendingCompetitions>& newCarriedCompetitions, Ref<ReturnStack> returnStack, vint32_t ruleId, vint32_t clauseId, bool forHighPriority);
|
||||
void AttendCompetitionIfNecessary(Trace* trace, vint32_t currentTokenIndex, EdgeDesc& edgeDesc, Ref<AttendingCompetitions>& newAttendingCompetitions, Ref<AttendingCompetitions>& newCarriedCompetitions, Ref<ReturnStack>& newReturnStack);
|
||||
void CheckAttendingCompetitionsOnEndingEdge(Trace* trace, EdgeDesc& edgeDesc, Ref<AttendingCompetitions> acId, Ref<ReturnStack> returnStack);
|
||||
void CheckBackupTracesBeforeSwapping(vint32_t currentTokenIndex);
|
||||
bool CheckBackupTracesBeforeSwapping(vint32_t currentTokenIndex);
|
||||
|
||||
// ReturnStack
|
||||
ReturnStackSuccessors* GetCurrentSuccessorInReturnStack(Ref<ReturnStack> base, vint32_t currentTokenIndex);
|
||||
|
||||
+1458
-517
File diff suppressed because it is too large
Load Diff
+169
-66
@@ -9,7 +9,7 @@ DEVELOPER: Zihan Chen(vczh)
|
||||
#include "VlppRegex.h"
|
||||
|
||||
/***********************************************************************
|
||||
.\PARSERGEN\PARSERSYMBOL.H
|
||||
.\PARSERGEN_GLOBAL\PARSERSYMBOL.H
|
||||
***********************************************************************/
|
||||
/***********************************************************************
|
||||
Author: Zihan Chen (vczh)
|
||||
@@ -78,18 +78,21 @@ ParserSymbolManager
|
||||
|
||||
#define GLR_PARSER_ERROR_LIST(ERROR_ITEM)\
|
||||
/* AstSymbolManager */\
|
||||
ERROR_ITEM(DuplicatedFileGroup, fileGroupName)\
|
||||
ERROR_ITEM(DuplicatedFile, fileName)\
|
||||
ERROR_ITEM(FileDependencyNotExists, fileName, dependency)\
|
||||
ERROR_ITEM(FileCyclicDependency, fileName, dependency)\
|
||||
ERROR_ITEM(DuplicatedSymbol, fileName, symbolName)\
|
||||
ERROR_ITEM(DuplicatedSymbolGlobally, fileName, symbolName, anotherFileName)\
|
||||
ERROR_ITEM(FileGroupDependencyNotExists, fileGroupName, dependency)\
|
||||
ERROR_ITEM(FileGroupCyclicDependency, fileGroupName, dependency)\
|
||||
ERROR_ITEM(DuplicatedSymbolInFile, fileName, symbolName)\
|
||||
ERROR_ITEM(DuplicatedSymbolInFileGroup, fileName, symbolName, anotherFileName)\
|
||||
ERROR_ITEM(DuplicatedClassProp, fileName, className, propName)\
|
||||
ERROR_ITEM(DuplicatedEnumItem, fileName, enumName, propName)\
|
||||
ERROR_ITEM(BaseClassNotExists, fileName, className, typeName)\
|
||||
ERROR_ITEM(BaseClassNotClass, fileName, className, typeName)\
|
||||
ERROR_ITEM(BaseClassNotPublic, fileName, className, typeName)\
|
||||
ERROR_ITEM(BaseClassCyclicDependency, fileName, className)\
|
||||
ERROR_ITEM(FieldTypeNotExists, fileName, className, propName)\
|
||||
ERROR_ITEM(FieldTypeNotClass, fileName, className, propName)\
|
||||
ERROR_ITEM(FieldTypeNotPublic, fileName, className, propName)\
|
||||
/* LexerSymbolManager */\
|
||||
ERROR_ITEM(InvalidTokenDefinition, code)\
|
||||
ERROR_ITEM(DuplicatedToken, tokenName)\
|
||||
@@ -105,9 +108,11 @@ ParserSymbolManager
|
||||
ERROR_ITEM(LeftRecursionInjectHasNoContinuation, ruleName, placeholder, targetRuleName)\
|
||||
/* SyntaxAst(ResolveName) */\
|
||||
ERROR_ITEM(RuleNameConflictedWithToken, ruleName)\
|
||||
ERROR_ITEM(TypeNotUniqueInRule, ruleName, name)\
|
||||
ERROR_ITEM(TypeNotExistsInRule, ruleName, name)\
|
||||
ERROR_ITEM(TypeNotClassInRule, ruleName, name)\
|
||||
ERROR_ITEM(TokenOrRuleNotExistsInRule, ruleName, name)\
|
||||
ERROR_ITEM(ReferencedRuleNotPublicInRuleOfDifferentFile, ruleName, name)\
|
||||
ERROR_ITEM(LiteralNotValidToken, ruleName, name)\
|
||||
ERROR_ITEM(LiteralIsDiscardedToken, ruleName, name)\
|
||||
ERROR_ITEM(ConditionalLiteralNotValidToken, ruleName, name)\
|
||||
@@ -171,7 +176,6 @@ ParserSymbolManager
|
||||
ERROR_ITEM(PartialRuleIndirectlyBeginsWithPrefixMerge, ruleName, prefixMergeRule)\
|
||||
ERROR_ITEM(ClausePartiallyIndirectlyBeginsWithPrefixMergeAndLiteral, ruleName, prefixMergeRule, literal)\
|
||||
ERROR_ITEM(ClausePartiallyIndirectlyBeginsWithPrefixMergeAndRule, ruleName, prefixMergeRule, literal)\
|
||||
ERROR_ITEM(RuleDeductToPrefixMergeInNonSimpleUseClause, ruleName, prefixMergeRule, byRule)\
|
||||
/* SyntaxAst(RewriteSyntax_PrefixMerge, prefix_merge) */\
|
||||
ERROR_ITEM(PrefixExtractionAffectedRuleReferencedAnother, ruleName, conflictedRule, prefixRule) /* During left_recursion_inject clause generation, if prefix extracted affected the process, all !prefixRule clauses where prefixRule is the prefix of conflictedRule in any !conflictedRule clauses, prefixRule should not be affected */\
|
||||
|
||||
@@ -184,6 +188,7 @@ ParserSymbolManager
|
||||
|
||||
enum class ParserDefFileType
|
||||
{
|
||||
AstGroup,
|
||||
Ast,
|
||||
Lexer,
|
||||
Syntax,
|
||||
@@ -275,6 +280,7 @@ namespace vl
|
||||
class AstEnumSymbol;
|
||||
class AstClassSymbol;
|
||||
class AstDefFile;
|
||||
class AstDefFileGroup;
|
||||
class AstSymbolManager;
|
||||
|
||||
/***********************************************************************
|
||||
@@ -290,8 +296,8 @@ AstSymbol
|
||||
AstSymbol(AstDefFile* _file, const WString& _name);
|
||||
public:
|
||||
bool isPublic = false;
|
||||
AstDefFile* Owner() { return ownerFile; }
|
||||
const WString& Name() { return name; }
|
||||
AstDefFile* Owner() const { return ownerFile; }
|
||||
const WString& Name() const { return name; }
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
@@ -308,7 +314,7 @@ AstEnumSymbol
|
||||
public:
|
||||
vint value = 0;
|
||||
|
||||
AstEnumSymbol* Parent() { return parent; }
|
||||
AstEnumSymbol* Parent() const { return parent; }
|
||||
};
|
||||
|
||||
class AstEnumSymbol : public AstSymbol
|
||||
@@ -320,8 +326,9 @@ AstEnumSymbol
|
||||
AstEnumSymbol(AstDefFile* _file, const WString& _name);
|
||||
public:
|
||||
AstEnumItemSymbol* CreateItem(const WString& itemName, ParsingTextRange codeRange = {});
|
||||
const auto& Items() { return items.map; }
|
||||
const auto& ItemOrder() { return items.order; }
|
||||
|
||||
const auto& Items() const { return items.map; }
|
||||
const auto& ItemOrder() const { return items.order; }
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
@@ -346,10 +353,17 @@ AstClassSymbol
|
||||
AstPropType propType = AstPropType::Token;
|
||||
AstSymbol* propSymbol = nullptr;
|
||||
|
||||
AstClassSymbol* Parent() { return parent; }
|
||||
AstClassSymbol* Parent() const { return parent; }
|
||||
bool SetPropType(AstPropType _type, const WString& typeName = WString::Empty, ParsingTextRange codeRange = {});
|
||||
};
|
||||
|
||||
enum class AstClassType
|
||||
{
|
||||
Defined,
|
||||
Generated_ToResolve,
|
||||
Generated_Common,
|
||||
};
|
||||
|
||||
class AstClassSymbol : public AstSymbol
|
||||
{
|
||||
friend class AstDefFile;
|
||||
@@ -358,15 +372,20 @@ AstClassSymbol
|
||||
|
||||
AstClassSymbol(AstDefFile* _file, const WString& _name);
|
||||
public:
|
||||
AstClassType classType = AstClassType::Defined;
|
||||
AstClassSymbol* baseClass = nullptr;
|
||||
AstClassSymbol* ambiguousDerivedClass = nullptr;
|
||||
collections::List<AstClassSymbol*> derivedClasses;
|
||||
|
||||
AstClassSymbol* derivedClass_ToResolve = nullptr;
|
||||
AstClassSymbol* derivedClass_Common = nullptr;
|
||||
|
||||
bool SetBaseClass(const WString& typeName, ParsingTextRange codeRange = {});
|
||||
AstClassSymbol* CreateAmbiguousDerivedClass(ParsingTextRange codeRange);
|
||||
AstClassSymbol* CreateDerivedClass_ToResolve(ParsingTextRange codeRange);
|
||||
AstClassSymbol* CreateDerivedClass_Common(ParsingTextRange codeRange);
|
||||
AstClassPropSymbol* CreateProp(const WString& propName, ParsingTextRange codeRange = {});
|
||||
const auto& Props() { return props.map; }
|
||||
const auto& PropOrder() { return props.order; }
|
||||
|
||||
const auto& Props() const { return props.map; }
|
||||
const auto& PropOrder() const { return props.order; }
|
||||
};
|
||||
|
||||
extern AstClassSymbol* FindCommonBaseClass(AstClassSymbol* c1, AstClassSymbol* c2);
|
||||
@@ -378,39 +397,73 @@ AstDefFile
|
||||
|
||||
class AstDefFile : public Object
|
||||
{
|
||||
friend class AstSymbolManager;
|
||||
|
||||
friend class AstDefFileGroup;
|
||||
using DependenciesList = collections::List<WString>;
|
||||
using StringItems = collections::List<WString>;
|
||||
protected:
|
||||
ParserSymbolManager* global = nullptr;
|
||||
AstSymbolManager* ownerManager = nullptr;
|
||||
AstDefFileGroup* ownerGroup = nullptr;
|
||||
WString name;
|
||||
MappedOwning<AstSymbol> symbols;
|
||||
|
||||
template<typename T>
|
||||
T* CreateSymbol(const WString& symbolName, ParsingTextRange codeRange);
|
||||
|
||||
AstDefFile(ParserSymbolManager* _global, AstSymbolManager* _ownerManager, const WString& _name);
|
||||
AstDefFile(AstDefFileGroup* _ownerGroup, const WString& _name);
|
||||
public:
|
||||
DependenciesList dependencies;
|
||||
StringItems cppNss;
|
||||
StringItems refNss;
|
||||
WString classPrefix;
|
||||
AstDefFileGroup* Owner() const { return ownerGroup; }
|
||||
const WString& Name() const { return name; }
|
||||
AstEnumSymbol* CreateEnum(const WString& symbolName, bool isPublic = false, ParsingTextRange codeRange = {});
|
||||
AstClassSymbol* CreateClass(const WString& symbolName, bool isPublic = false, ParsingTextRange codeRange = {});
|
||||
|
||||
AstSymbolManager* Owner() { return ownerManager; }
|
||||
const WString& Name() { return name; }
|
||||
bool AddDependency(const WString& dependency, ParsingTextRange codeRange = {});
|
||||
AstEnumSymbol* CreateEnum(const WString& symbolName, ParsingTextRange codeRange = {});
|
||||
AstClassSymbol* CreateClass(const WString& symbolName, ParsingTextRange codeRange = {});
|
||||
const auto& Symbols() { return symbols.map; }
|
||||
const auto& SymbolOrder() { return symbols.order; }
|
||||
const auto& Symbols() const { return symbols.map; }
|
||||
const auto& SymbolOrder() const { return symbols.order; }
|
||||
|
||||
template<typename ...TArgs>
|
||||
void AddError(ParserErrorType type, ParsingTextRange codeRange, TArgs&&... args)
|
||||
void AddError(ParserErrorType type, ParsingTextRange codeRange, TArgs&&... args);
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
AstDefFileGroup
|
||||
***********************************************************************/
|
||||
|
||||
class AstDefFileGroup : public Object
|
||||
{
|
||||
friend class AstDefFile;
|
||||
friend class AstSymbolManager;
|
||||
using DependenciesList = collections::List<WString>;
|
||||
using StringItems = collections::List<WString>;
|
||||
using SymbolMap = collections::Dictionary<WString, AstSymbol*>;
|
||||
protected:
|
||||
AstSymbolManager* ownerManager = nullptr;
|
||||
WString name;
|
||||
MappedOwning<AstDefFile> files;
|
||||
SymbolMap symbolMap;
|
||||
|
||||
AstDefFileGroup(AstSymbolManager* _ownerManager, const WString& _name);
|
||||
public:
|
||||
DependenciesList dependencies;
|
||||
StringItems cppNss;
|
||||
StringItems refNss;
|
||||
WString classPrefix;
|
||||
|
||||
AstSymbolManager* Owner() const { return ownerManager; }
|
||||
const WString& Name() const { return name; }
|
||||
bool AddDependency(const WString& dependency, ParsingTextRange codeRange = {});
|
||||
AstDefFile* CreateFile(const WString& name);
|
||||
|
||||
const auto& Files() const { return files.map; }
|
||||
const auto& FileOrder() const { return files.order; }
|
||||
const auto& Symbols() const { return symbolMap; }
|
||||
collections::LazyList<WString> SymbolOrder()
|
||||
{
|
||||
global->AddError(type, { ParserDefFileType::Ast,name,codeRange }, std::forward<TArgs&&>(args)...);
|
||||
return From(files.order)
|
||||
.Select([this](const WString& fileName) { return files.map[fileName]; })
|
||||
.SelectMany([](AstDefFile* file) { return From(file->SymbolOrder()); })
|
||||
;
|
||||
}
|
||||
|
||||
template<typename ...TArgs>
|
||||
void AddError(ParserErrorType type, ParsingTextRange codeRange, TArgs&&... args);
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
@@ -419,27 +472,47 @@ AstSymbolManager
|
||||
|
||||
class AstSymbolManager : public Object
|
||||
{
|
||||
using SymbolMap = collections::Dictionary<WString, AstSymbol*>;
|
||||
|
||||
friend class AstDefFile;
|
||||
using SymbolGroup = collections::Group<WString, AstSymbol*>;
|
||||
using FileMap = collections::Dictionary<WString, AstDefFile*>;
|
||||
protected:
|
||||
MappedOwning<AstDefFile> files;
|
||||
SymbolMap symbolMap;
|
||||
ParserSymbolManager& global;
|
||||
ParserSymbolManager& global;
|
||||
MappedOwning<AstDefFileGroup> fileGroups;
|
||||
SymbolGroup symbolGroup;
|
||||
FileMap fileMap;
|
||||
|
||||
public:
|
||||
AstSymbolManager(ParserSymbolManager& _global);
|
||||
|
||||
AstDefFile* CreateFile(const WString& name);
|
||||
AstDefFileGroup* CreateFileGroup(const WString& name);
|
||||
|
||||
const ParserSymbolManager& Global() const { return global; }
|
||||
const auto& Files() const { return files.map; }
|
||||
const auto& FileOrder() const { return files.order; }
|
||||
const auto& Symbols() const { return symbolMap; }
|
||||
const ParserSymbolManager& Global() const { return global; }
|
||||
const auto& FileGroups() const { return fileGroups.map; }
|
||||
const auto& FileGroupOrder() const { return fileGroups.order; }
|
||||
const auto& Symbols() const { return symbolGroup; }
|
||||
const auto& Files() const { return fileMap; }
|
||||
};
|
||||
|
||||
extern AstDefFile* CreateParserGenTypeAst(AstSymbolManager& manager);
|
||||
extern AstDefFile* CreateParserGenRuleAst(AstSymbolManager& manager);
|
||||
extern AstDefFile* CreateParserGenTypeAst(AstSymbolManager& manager);
|
||||
extern AstDefFile* CreateParserGenRuleAst(AstSymbolManager& manager);
|
||||
|
||||
/***********************************************************************
|
||||
AddError
|
||||
***********************************************************************/
|
||||
|
||||
template<typename ...TArgs>
|
||||
void AstDefFile::AddError(ParserErrorType type, ParsingTextRange codeRange, TArgs&&... args)
|
||||
{
|
||||
auto&& global = const_cast<ParserSymbolManager&>(ownerGroup->Owner()->Global());
|
||||
global.AddError(type, { ParserDefFileType::Ast,name,codeRange }, std::forward<TArgs&&>(args)...);
|
||||
}
|
||||
|
||||
template<typename ...TArgs>
|
||||
void AstDefFileGroup::AddError(ParserErrorType type, ParsingTextRange codeRange, TArgs&&... args)
|
||||
{
|
||||
auto&& global = const_cast<ParserSymbolManager&>(ownerManager->Global());
|
||||
global.AddError(type, { ParserDefFileType::AstGroup,name,codeRange }, std::forward<TArgs&&>(args)...);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -521,7 +594,7 @@ LexerSymbolManager
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
.\PARSERGEN\PARSERCPPGEN.H
|
||||
.\PARSERGEN_GLOBAL\PARSERCPPGEN.H
|
||||
***********************************************************************/
|
||||
/***********************************************************************
|
||||
Author: Zihan Chen (vczh)
|
||||
@@ -538,7 +611,7 @@ namespace vl
|
||||
{
|
||||
namespace parsergen
|
||||
{
|
||||
class AstDefFile;
|
||||
class AstDefFileGroup;
|
||||
class AstClassPropSymbol;
|
||||
class AstClassSymbol;
|
||||
class TokenSymbol;
|
||||
@@ -576,7 +649,7 @@ Output
|
||||
WString assemblyCpp;
|
||||
WString lexerH;
|
||||
WString lexerCpp;
|
||||
collections::Dictionary<AstDefFile*, Ptr<CppAstGenOutput>> astOutputs;
|
||||
collections::Dictionary<AstDefFileGroup*, Ptr<CppAstGenOutput>> astOutputs;
|
||||
collections::Dictionary<SyntaxSymbolManager*, Ptr<CppSyntaxGenOutput>> syntaxOutputs;
|
||||
|
||||
collections::Dictionary<AstClassSymbol*, vint32_t> classIds;
|
||||
@@ -623,29 +696,29 @@ namespace vl
|
||||
{
|
||||
extern void GenerateAstFileNames(AstSymbolManager& manager, Ptr<CppParserGenOutput> parserOutput);
|
||||
|
||||
extern void WriteAstHeaderFile (AstDefFile* file, stream::StreamWriter& writer);
|
||||
extern void WriteAstCppFile (AstDefFile* file, const WString& astHeaderName, stream::StreamWriter& writer);
|
||||
extern void WriteAstHeaderFile (AstDefFileGroup* group, stream::StreamWriter& writer);
|
||||
extern void WriteAstCppFile (AstDefFileGroup* group, const WString& astHeaderName, stream::StreamWriter& writer);
|
||||
|
||||
extern void WriteAstUtilityHeaderFile (AstDefFile* file, Ptr<CppAstGenOutput> output, const WString& extraNss, stream::StreamWriter& writer, Func<void(const WString&)> callback);
|
||||
extern void WriteAstUtilityCppFile (AstDefFile* file, const WString& utilityHeaderFile, const WString& extraNss, stream::StreamWriter& writer, Func<void(const WString&)> callback);
|
||||
extern void WriteAstUtilityHeaderFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, const WString& extraNss, stream::StreamWriter& writer, Func<void(const WString&)> callback);
|
||||
extern void WriteAstUtilityCppFile (AstDefFileGroup* group, const WString& utilityHeaderFile, const WString& extraNss, stream::StreamWriter& writer, Func<void(const WString&)> callback);
|
||||
extern void WriteParserUtilityHeaderFile (AstSymbolManager& manager, Ptr<CppParserGenOutput> output, const WString& guardPostfix, stream::StreamWriter& writer, Func<void(const WString&)> callback);
|
||||
extern void WriteParserUtilityCppFile (AstSymbolManager& manager, const WString& utilityHeaderFile, stream::StreamWriter& writer, Func<void(const WString&)> callback);
|
||||
|
||||
extern void WriteAstBuilderHeaderFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteAstBuilderCppFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteEmptyVisitorHeaderFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteEmptyVisitorCppFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteCopyVisitorHeaderFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteCopyVisitorCppFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteTraverseVisitorHeaderFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteTraverseVisitorCppFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteJsonVisitorHeaderFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteJsonVisitorCppFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteAstBuilderHeaderFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteAstBuilderCppFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteEmptyVisitorHeaderFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteEmptyVisitorCppFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteCopyVisitorHeaderFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteCopyVisitorCppFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteTraverseVisitorHeaderFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteTraverseVisitorCppFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteJsonVisitorHeaderFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteJsonVisitorCppFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||
|
||||
extern void WriteAstAssemblerHeaderFile (AstSymbolManager& manager, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer);
|
||||
extern void WriteAstAssemblerCppFile (AstSymbolManager& manager, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer);
|
||||
|
||||
extern void WriteAstFiles (AstDefFile* file, Ptr<CppAstGenOutput> output, collections::Dictionary<WString, WString>& files);
|
||||
extern void WriteAstFiles (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, collections::Dictionary<WString, WString>& files);
|
||||
extern void WriteAstFiles (AstSymbolManager& manager, Ptr<CppParserGenOutput> output, collections::Dictionary<WString, WString>& files);
|
||||
}
|
||||
}
|
||||
@@ -2444,6 +2517,33 @@ namespace vl::glr::parsergen
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
.\PARSERGEN_PRINTER\ASTTOCODE.H
|
||||
***********************************************************************/
|
||||
#ifndef VCZH_PARSER2_PARSERGEN_ASTTOCODE
|
||||
#define VCZH_PARSER2_PARSERGEN_ASTTOCODE
|
||||
|
||||
|
||||
namespace vl::glr::parsergen
|
||||
{
|
||||
extern Ptr<GlrAstFile> TypeSymbolToAst(
|
||||
const AstSymbolManager& manager,
|
||||
bool createGeneratedTypes
|
||||
);
|
||||
|
||||
extern void TypeAstToCode(
|
||||
Ptr<GlrAstFile> file,
|
||||
stream::TextWriter& writer
|
||||
);
|
||||
|
||||
extern void SyntaxAstToCode(
|
||||
Ptr<GlrSyntaxFile> file,
|
||||
stream::TextWriter& writer
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
.\SYNTAX\SYNTAXSYMBOL.H
|
||||
***********************************************************************/
|
||||
@@ -2592,9 +2692,10 @@ RuleSymbol
|
||||
WString name;
|
||||
vint32_t currentClauseId = -1;
|
||||
|
||||
RuleSymbol(SyntaxSymbolManager* _ownerManager, const WString& _name);
|
||||
RuleSymbol(SyntaxSymbolManager* _ownerManager, const WString& _name, vint _fileIndex);
|
||||
public:
|
||||
StateList startStates;
|
||||
vint fileIndex = -1;
|
||||
bool isPublic = false;
|
||||
bool isParser = false;
|
||||
bool isPartial = false;
|
||||
@@ -2656,7 +2757,7 @@ SyntaxSymbolManager
|
||||
WString name;
|
||||
LrpFlagList lrpFlags;
|
||||
|
||||
RuleSymbol* CreateRule(const WString& name, ParsingTextRange codeRange = {});
|
||||
RuleSymbol* CreateRule(const WString& name, vint fileIndex, bool isPublic, bool isParser, ParsingTextRange codeRange = {});
|
||||
void RemoveRule(const WString& name);
|
||||
|
||||
StateSymbol* CreateState(RuleSymbol* rule, vint32_t clauseId);
|
||||
@@ -2830,9 +2931,11 @@ Compiler
|
||||
***********************************************************************/
|
||||
|
||||
extern WString UnescapeLiteral(const WString& literal, wchar_t quot);
|
||||
extern void CompileAst(AstSymbolManager& astManager, collections::List<collections::Pair<AstDefFile*, Ptr<GlrAstFile>>>& files);
|
||||
extern void CompileAst(AstSymbolManager& astManager, AstDefFile* astDefFile, Ptr<GlrAstFile> file);
|
||||
extern void CompileLexer(LexerSymbolManager& lexerManager, const WString& input);
|
||||
extern Ptr<GlrSyntaxFile> CompileSyntax(AstSymbolManager& astManager, LexerSymbolManager& lexerManager, SyntaxSymbolManager& syntaxManager, Ptr<CppParserGenOutput> output, collections::List<Ptr<GlrSyntaxFile>>& files);
|
||||
extern Ptr<GlrSyntaxFile> CompileSyntax(AstSymbolManager& astManager, LexerSymbolManager& lexerManager, SyntaxSymbolManager& syntaxManager, Ptr<CppParserGenOutput> output, Ptr<GlrSyntaxFile> file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user