mirror of
https://github.com/vczh-libraries/Release.git
synced 2026-09-27 18:59:19 +08:00
Update release
This commit is contained in:
@@ -4254,6 +4254,7 @@ Event Receiver
|
|||||||
,lostFocus(_sender)
|
,lostFocus(_sender)
|
||||||
,caretNotify(_sender)
|
,caretNotify(_sender)
|
||||||
,clipboardNotify(_sender)
|
,clipboardNotify(_sender)
|
||||||
|
,renderTargetChanged(_sender)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+229
-4
@@ -2632,7 +2632,13 @@ Input
|
|||||||
|
|
||||||
// if competitions happen between new surviving traces
|
// if competitions happen between new surviving traces
|
||||||
// remove traces that known to have lost the competition
|
// 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();
|
EndSwap();
|
||||||
|
|
||||||
@@ -2806,6 +2812,7 @@ namespace vl
|
|||||||
{
|
{
|
||||||
namespace automaton
|
namespace automaton
|
||||||
{
|
{
|
||||||
|
using namespace collections;
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
EnsureTraceWithValidStates
|
EnsureTraceWithValidStates
|
||||||
@@ -2831,7 +2838,7 @@ AreTwoEndingInputTraceEqual
|
|||||||
{
|
{
|
||||||
// two traces equal to each other if
|
// two traces equal to each other if
|
||||||
// 1) they are in the same state
|
// 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
|
// 3) they are attending same competitions
|
||||||
// 4) they have the same switchValues
|
// 4) they have the same switchValues
|
||||||
// 5) the candidate has an ending input
|
// 5) the candidate has an ending input
|
||||||
@@ -2850,7 +2857,7 @@ AreTwoEndingInputTraceEqual
|
|||||||
MergeTwoEndingInputTrace
|
MergeTwoEndingInputTrace
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
void TraceManager::MergeTwoEndingInputTrace(Trace* newTrace, Trace* candidate)
|
Trace* TraceManager::MergeTwoEndingInputTrace(Trace* newTrace, Trace* candidate)
|
||||||
{
|
{
|
||||||
// goal of this function is to create a structure
|
// goal of this function is to create a structure
|
||||||
// NEWTRACE ---+->AMBIGUITY
|
// NEWTRACE ---+->AMBIGUITY
|
||||||
@@ -2861,9 +2868,14 @@ MergeTwoEndingInputTrace
|
|||||||
// a former trace will copy CANDIDATE and insert before CANDIDATE
|
// a former trace will copy CANDIDATE and insert before CANDIDATE
|
||||||
// and CANDIDATE will be initialized to an empty trace
|
// 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)
|
if (candidate->state == -1)
|
||||||
{
|
{
|
||||||
AddTraceToCollection(candidate, newTrace, &Trace::predecessors);
|
AddTraceToCollection(candidate, newTrace, &Trace::predecessors);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2879,8 +2891,211 @@ MergeTwoEndingInputTrace
|
|||||||
|
|
||||||
AddTraceToCollection(candidate, formerTrace, &Trace::predecessors);
|
AddTraceToCollection(candidate, formerTrace, &Trace::predecessors);
|
||||||
AddTraceToCollection(candidate, newTrace, &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
|
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
|
// try to find if any competition could be settled at this moment
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -3193,6 +3409,7 @@ CheckBackupTracesBeforeSwapping
|
|||||||
for (vint i = 0; i < concurrentCount; i++)
|
for (vint i = 0; i < concurrentCount; i++)
|
||||||
{
|
{
|
||||||
auto trace = EnsureTraceWithValidStates(backupTraces->Get(i));
|
auto trace = EnsureTraceWithValidStates(backupTraces->Get(i));
|
||||||
|
auto attendingCompetitions = trace->competitionRouting.attendingCompetitions;
|
||||||
auto* pnext = &trace->competitionRouting.attendingCompetitions;
|
auto* pnext = &trace->competitionRouting.attendingCompetitions;
|
||||||
while (*pnext != nullref)
|
while (*pnext != nullref)
|
||||||
{
|
{
|
||||||
@@ -3206,7 +3423,15 @@ CheckBackupTracesBeforeSwapping
|
|||||||
pnext = &ac->nextActiveAC;
|
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)
|
Ptr<ParsingAstBase> AssemblerResolveAmbiguity(vint32_t type, collections::Array<Ptr<ParsingAstBase>>& candidates, const wchar_t* cppTypeName)
|
||||||
{
|
{
|
||||||
auto ast = Ptr(new TAmbiguity());
|
auto ast = Ptr(new TAmbiguity());
|
||||||
|
if (candidates.Count() > 0)
|
||||||
|
{
|
||||||
|
ast->codeRange = candidates[0]->codeRange;
|
||||||
|
}
|
||||||
for (auto candidate : candidates)
|
for (auto candidate : candidates)
|
||||||
{
|
{
|
||||||
if (auto typedAst = candidate.Cast<TElement>())
|
if (auto typedAst = candidate.Cast<TElement>())
|
||||||
@@ -2287,13 +2291,14 @@ TraceManager
|
|||||||
// Ambiguity
|
// Ambiguity
|
||||||
Trace* EnsureTraceWithValidStates(Trace* trace);
|
Trace* EnsureTraceWithValidStates(Trace* trace);
|
||||||
bool AreTwoEndingInputTraceEqual(Trace* newTrace, Trace* candidate);
|
bool AreTwoEndingInputTraceEqual(Trace* newTrace, Trace* candidate);
|
||||||
void MergeTwoEndingInputTrace(Trace* newTrace, Trace* candidate);
|
Trace* MergeTwoEndingInputTrace(Trace* newTrace, Trace* candidate);
|
||||||
|
void TryMergeSurvivingTraces();
|
||||||
|
|
||||||
// Competition
|
// Competition
|
||||||
void AttendCompetition(Trace* trace, Ref<AttendingCompetitions>& newAttendingCompetitions, Ref<AttendingCompetitions>& newCarriedCompetitions, Ref<ReturnStack> returnStack, vint32_t ruleId, vint32_t clauseId, bool forHighPriority);
|
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 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 CheckAttendingCompetitionsOnEndingEdge(Trace* trace, EdgeDesc& edgeDesc, Ref<AttendingCompetitions> acId, Ref<ReturnStack> returnStack);
|
||||||
void CheckBackupTracesBeforeSwapping(vint32_t currentTokenIndex);
|
bool CheckBackupTracesBeforeSwapping(vint32_t currentTokenIndex);
|
||||||
|
|
||||||
// ReturnStack
|
// ReturnStack
|
||||||
ReturnStackSuccessors* GetCurrentSuccessorInReturnStack(Ref<ReturnStack> base, vint32_t currentTokenIndex);
|
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"
|
#include "VlppRegex.h"
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
.\PARSERGEN\PARSERSYMBOL.H
|
.\PARSERGEN_GLOBAL\PARSERSYMBOL.H
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Author: Zihan Chen (vczh)
|
Author: Zihan Chen (vczh)
|
||||||
@@ -78,18 +78,21 @@ ParserSymbolManager
|
|||||||
|
|
||||||
#define GLR_PARSER_ERROR_LIST(ERROR_ITEM)\
|
#define GLR_PARSER_ERROR_LIST(ERROR_ITEM)\
|
||||||
/* AstSymbolManager */\
|
/* AstSymbolManager */\
|
||||||
|
ERROR_ITEM(DuplicatedFileGroup, fileGroupName)\
|
||||||
ERROR_ITEM(DuplicatedFile, fileName)\
|
ERROR_ITEM(DuplicatedFile, fileName)\
|
||||||
ERROR_ITEM(FileDependencyNotExists, fileName, dependency)\
|
ERROR_ITEM(FileGroupDependencyNotExists, fileGroupName, dependency)\
|
||||||
ERROR_ITEM(FileCyclicDependency, fileName, dependency)\
|
ERROR_ITEM(FileGroupCyclicDependency, fileGroupName, dependency)\
|
||||||
ERROR_ITEM(DuplicatedSymbol, fileName, symbolName)\
|
ERROR_ITEM(DuplicatedSymbolInFile, fileName, symbolName)\
|
||||||
ERROR_ITEM(DuplicatedSymbolGlobally, fileName, symbolName, anotherFileName)\
|
ERROR_ITEM(DuplicatedSymbolInFileGroup, fileName, symbolName, anotherFileName)\
|
||||||
ERROR_ITEM(DuplicatedClassProp, fileName, className, propName)\
|
ERROR_ITEM(DuplicatedClassProp, fileName, className, propName)\
|
||||||
ERROR_ITEM(DuplicatedEnumItem, fileName, enumName, propName)\
|
ERROR_ITEM(DuplicatedEnumItem, fileName, enumName, propName)\
|
||||||
ERROR_ITEM(BaseClassNotExists, fileName, className, typeName)\
|
ERROR_ITEM(BaseClassNotExists, fileName, className, typeName)\
|
||||||
ERROR_ITEM(BaseClassNotClass, fileName, className, typeName)\
|
ERROR_ITEM(BaseClassNotClass, fileName, className, typeName)\
|
||||||
|
ERROR_ITEM(BaseClassNotPublic, fileName, className, typeName)\
|
||||||
ERROR_ITEM(BaseClassCyclicDependency, fileName, className)\
|
ERROR_ITEM(BaseClassCyclicDependency, fileName, className)\
|
||||||
ERROR_ITEM(FieldTypeNotExists, fileName, className, propName)\
|
ERROR_ITEM(FieldTypeNotExists, fileName, className, propName)\
|
||||||
ERROR_ITEM(FieldTypeNotClass, fileName, className, propName)\
|
ERROR_ITEM(FieldTypeNotClass, fileName, className, propName)\
|
||||||
|
ERROR_ITEM(FieldTypeNotPublic, fileName, className, propName)\
|
||||||
/* LexerSymbolManager */\
|
/* LexerSymbolManager */\
|
||||||
ERROR_ITEM(InvalidTokenDefinition, code)\
|
ERROR_ITEM(InvalidTokenDefinition, code)\
|
||||||
ERROR_ITEM(DuplicatedToken, tokenName)\
|
ERROR_ITEM(DuplicatedToken, tokenName)\
|
||||||
@@ -105,9 +108,11 @@ ParserSymbolManager
|
|||||||
ERROR_ITEM(LeftRecursionInjectHasNoContinuation, ruleName, placeholder, targetRuleName)\
|
ERROR_ITEM(LeftRecursionInjectHasNoContinuation, ruleName, placeholder, targetRuleName)\
|
||||||
/* SyntaxAst(ResolveName) */\
|
/* SyntaxAst(ResolveName) */\
|
||||||
ERROR_ITEM(RuleNameConflictedWithToken, ruleName)\
|
ERROR_ITEM(RuleNameConflictedWithToken, ruleName)\
|
||||||
|
ERROR_ITEM(TypeNotUniqueInRule, ruleName, name)\
|
||||||
ERROR_ITEM(TypeNotExistsInRule, ruleName, name)\
|
ERROR_ITEM(TypeNotExistsInRule, ruleName, name)\
|
||||||
ERROR_ITEM(TypeNotClassInRule, ruleName, name)\
|
ERROR_ITEM(TypeNotClassInRule, ruleName, name)\
|
||||||
ERROR_ITEM(TokenOrRuleNotExistsInRule, ruleName, name)\
|
ERROR_ITEM(TokenOrRuleNotExistsInRule, ruleName, name)\
|
||||||
|
ERROR_ITEM(ReferencedRuleNotPublicInRuleOfDifferentFile, ruleName, name)\
|
||||||
ERROR_ITEM(LiteralNotValidToken, ruleName, name)\
|
ERROR_ITEM(LiteralNotValidToken, ruleName, name)\
|
||||||
ERROR_ITEM(LiteralIsDiscardedToken, ruleName, name)\
|
ERROR_ITEM(LiteralIsDiscardedToken, ruleName, name)\
|
||||||
ERROR_ITEM(ConditionalLiteralNotValidToken, ruleName, name)\
|
ERROR_ITEM(ConditionalLiteralNotValidToken, ruleName, name)\
|
||||||
@@ -171,7 +176,6 @@ ParserSymbolManager
|
|||||||
ERROR_ITEM(PartialRuleIndirectlyBeginsWithPrefixMerge, ruleName, prefixMergeRule)\
|
ERROR_ITEM(PartialRuleIndirectlyBeginsWithPrefixMerge, ruleName, prefixMergeRule)\
|
||||||
ERROR_ITEM(ClausePartiallyIndirectlyBeginsWithPrefixMergeAndLiteral, ruleName, prefixMergeRule, literal)\
|
ERROR_ITEM(ClausePartiallyIndirectlyBeginsWithPrefixMergeAndLiteral, ruleName, prefixMergeRule, literal)\
|
||||||
ERROR_ITEM(ClausePartiallyIndirectlyBeginsWithPrefixMergeAndRule, ruleName, prefixMergeRule, literal)\
|
ERROR_ITEM(ClausePartiallyIndirectlyBeginsWithPrefixMergeAndRule, ruleName, prefixMergeRule, literal)\
|
||||||
ERROR_ITEM(RuleDeductToPrefixMergeInNonSimpleUseClause, ruleName, prefixMergeRule, byRule)\
|
|
||||||
/* SyntaxAst(RewriteSyntax_PrefixMerge, prefix_merge) */\
|
/* 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 */\
|
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
|
enum class ParserDefFileType
|
||||||
{
|
{
|
||||||
|
AstGroup,
|
||||||
Ast,
|
Ast,
|
||||||
Lexer,
|
Lexer,
|
||||||
Syntax,
|
Syntax,
|
||||||
@@ -275,6 +280,7 @@ namespace vl
|
|||||||
class AstEnumSymbol;
|
class AstEnumSymbol;
|
||||||
class AstClassSymbol;
|
class AstClassSymbol;
|
||||||
class AstDefFile;
|
class AstDefFile;
|
||||||
|
class AstDefFileGroup;
|
||||||
class AstSymbolManager;
|
class AstSymbolManager;
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@@ -290,8 +296,8 @@ AstSymbol
|
|||||||
AstSymbol(AstDefFile* _file, const WString& _name);
|
AstSymbol(AstDefFile* _file, const WString& _name);
|
||||||
public:
|
public:
|
||||||
bool isPublic = false;
|
bool isPublic = false;
|
||||||
AstDefFile* Owner() { return ownerFile; }
|
AstDefFile* Owner() const { return ownerFile; }
|
||||||
const WString& Name() { return name; }
|
const WString& Name() const { return name; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@@ -308,7 +314,7 @@ AstEnumSymbol
|
|||||||
public:
|
public:
|
||||||
vint value = 0;
|
vint value = 0;
|
||||||
|
|
||||||
AstEnumSymbol* Parent() { return parent; }
|
AstEnumSymbol* Parent() const { return parent; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class AstEnumSymbol : public AstSymbol
|
class AstEnumSymbol : public AstSymbol
|
||||||
@@ -320,8 +326,9 @@ AstEnumSymbol
|
|||||||
AstEnumSymbol(AstDefFile* _file, const WString& _name);
|
AstEnumSymbol(AstDefFile* _file, const WString& _name);
|
||||||
public:
|
public:
|
||||||
AstEnumItemSymbol* CreateItem(const WString& itemName, ParsingTextRange codeRange = {});
|
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;
|
AstPropType propType = AstPropType::Token;
|
||||||
AstSymbol* propSymbol = nullptr;
|
AstSymbol* propSymbol = nullptr;
|
||||||
|
|
||||||
AstClassSymbol* Parent() { return parent; }
|
AstClassSymbol* Parent() const { return parent; }
|
||||||
bool SetPropType(AstPropType _type, const WString& typeName = WString::Empty, ParsingTextRange codeRange = {});
|
bool SetPropType(AstPropType _type, const WString& typeName = WString::Empty, ParsingTextRange codeRange = {});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class AstClassType
|
||||||
|
{
|
||||||
|
Defined,
|
||||||
|
Generated_ToResolve,
|
||||||
|
Generated_Common,
|
||||||
|
};
|
||||||
|
|
||||||
class AstClassSymbol : public AstSymbol
|
class AstClassSymbol : public AstSymbol
|
||||||
{
|
{
|
||||||
friend class AstDefFile;
|
friend class AstDefFile;
|
||||||
@@ -358,15 +372,20 @@ AstClassSymbol
|
|||||||
|
|
||||||
AstClassSymbol(AstDefFile* _file, const WString& _name);
|
AstClassSymbol(AstDefFile* _file, const WString& _name);
|
||||||
public:
|
public:
|
||||||
|
AstClassType classType = AstClassType::Defined;
|
||||||
AstClassSymbol* baseClass = nullptr;
|
AstClassSymbol* baseClass = nullptr;
|
||||||
AstClassSymbol* ambiguousDerivedClass = nullptr;
|
|
||||||
collections::List<AstClassSymbol*> derivedClasses;
|
collections::List<AstClassSymbol*> derivedClasses;
|
||||||
|
|
||||||
|
AstClassSymbol* derivedClass_ToResolve = nullptr;
|
||||||
|
AstClassSymbol* derivedClass_Common = nullptr;
|
||||||
|
|
||||||
bool SetBaseClass(const WString& typeName, ParsingTextRange codeRange = {});
|
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 = {});
|
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);
|
extern AstClassSymbol* FindCommonBaseClass(AstClassSymbol* c1, AstClassSymbol* c2);
|
||||||
@@ -378,39 +397,73 @@ AstDefFile
|
|||||||
|
|
||||||
class AstDefFile : public Object
|
class AstDefFile : public Object
|
||||||
{
|
{
|
||||||
friend class AstSymbolManager;
|
friend class AstDefFileGroup;
|
||||||
|
|
||||||
using DependenciesList = collections::List<WString>;
|
using DependenciesList = collections::List<WString>;
|
||||||
using StringItems = collections::List<WString>;
|
using StringItems = collections::List<WString>;
|
||||||
protected:
|
protected:
|
||||||
ParserSymbolManager* global = nullptr;
|
AstDefFileGroup* ownerGroup = nullptr;
|
||||||
AstSymbolManager* ownerManager = nullptr;
|
|
||||||
WString name;
|
WString name;
|
||||||
MappedOwning<AstSymbol> symbols;
|
MappedOwning<AstSymbol> symbols;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* CreateSymbol(const WString& symbolName, ParsingTextRange codeRange);
|
T* CreateSymbol(const WString& symbolName, ParsingTextRange codeRange);
|
||||||
|
|
||||||
AstDefFile(ParserSymbolManager* _global, AstSymbolManager* _ownerManager, const WString& _name);
|
AstDefFile(AstDefFileGroup* _ownerGroup, const WString& _name);
|
||||||
public:
|
public:
|
||||||
DependenciesList dependencies;
|
AstDefFileGroup* Owner() const { return ownerGroup; }
|
||||||
StringItems cppNss;
|
const WString& Name() const { return name; }
|
||||||
StringItems refNss;
|
AstEnumSymbol* CreateEnum(const WString& symbolName, bool isPublic = false, ParsingTextRange codeRange = {});
|
||||||
WString classPrefix;
|
AstClassSymbol* CreateClass(const WString& symbolName, bool isPublic = false, ParsingTextRange codeRange = {});
|
||||||
|
|
||||||
AstSymbolManager* Owner() { return ownerManager; }
|
const auto& Symbols() const { return symbols.map; }
|
||||||
const WString& Name() { return name; }
|
const auto& SymbolOrder() const { return symbols.order; }
|
||||||
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; }
|
|
||||||
|
|
||||||
template<typename ...TArgs>
|
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
|
class AstSymbolManager : public Object
|
||||||
{
|
{
|
||||||
using SymbolMap = collections::Dictionary<WString, AstSymbol*>;
|
|
||||||
|
|
||||||
friend class AstDefFile;
|
friend class AstDefFile;
|
||||||
|
using SymbolGroup = collections::Group<WString, AstSymbol*>;
|
||||||
|
using FileMap = collections::Dictionary<WString, AstDefFile*>;
|
||||||
protected:
|
protected:
|
||||||
MappedOwning<AstDefFile> files;
|
ParserSymbolManager& global;
|
||||||
SymbolMap symbolMap;
|
MappedOwning<AstDefFileGroup> fileGroups;
|
||||||
ParserSymbolManager& global;
|
SymbolGroup symbolGroup;
|
||||||
|
FileMap fileMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AstSymbolManager(ParserSymbolManager& _global);
|
AstSymbolManager(ParserSymbolManager& _global);
|
||||||
|
|
||||||
AstDefFile* CreateFile(const WString& name);
|
AstDefFileGroup* CreateFileGroup(const WString& name);
|
||||||
|
|
||||||
const ParserSymbolManager& Global() const { return global; }
|
const ParserSymbolManager& Global() const { return global; }
|
||||||
const auto& Files() const { return files.map; }
|
const auto& FileGroups() const { return fileGroups.map; }
|
||||||
const auto& FileOrder() const { return files.order; }
|
const auto& FileGroupOrder() const { return fileGroups.order; }
|
||||||
const auto& Symbols() const { return symbolMap; }
|
const auto& Symbols() const { return symbolGroup; }
|
||||||
|
const auto& Files() const { return fileMap; }
|
||||||
};
|
};
|
||||||
|
|
||||||
extern AstDefFile* CreateParserGenTypeAst(AstSymbolManager& manager);
|
extern AstDefFile* CreateParserGenTypeAst(AstSymbolManager& manager);
|
||||||
extern AstDefFile* CreateParserGenRuleAst(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
|
#endif
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
.\PARSERGEN\PARSERCPPGEN.H
|
.\PARSERGEN_GLOBAL\PARSERCPPGEN.H
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Author: Zihan Chen (vczh)
|
Author: Zihan Chen (vczh)
|
||||||
@@ -538,7 +611,7 @@ namespace vl
|
|||||||
{
|
{
|
||||||
namespace parsergen
|
namespace parsergen
|
||||||
{
|
{
|
||||||
class AstDefFile;
|
class AstDefFileGroup;
|
||||||
class AstClassPropSymbol;
|
class AstClassPropSymbol;
|
||||||
class AstClassSymbol;
|
class AstClassSymbol;
|
||||||
class TokenSymbol;
|
class TokenSymbol;
|
||||||
@@ -576,7 +649,7 @@ Output
|
|||||||
WString assemblyCpp;
|
WString assemblyCpp;
|
||||||
WString lexerH;
|
WString lexerH;
|
||||||
WString lexerCpp;
|
WString lexerCpp;
|
||||||
collections::Dictionary<AstDefFile*, Ptr<CppAstGenOutput>> astOutputs;
|
collections::Dictionary<AstDefFileGroup*, Ptr<CppAstGenOutput>> astOutputs;
|
||||||
collections::Dictionary<SyntaxSymbolManager*, Ptr<CppSyntaxGenOutput>> syntaxOutputs;
|
collections::Dictionary<SyntaxSymbolManager*, Ptr<CppSyntaxGenOutput>> syntaxOutputs;
|
||||||
|
|
||||||
collections::Dictionary<AstClassSymbol*, vint32_t> classIds;
|
collections::Dictionary<AstClassSymbol*, vint32_t> classIds;
|
||||||
@@ -623,29 +696,29 @@ namespace vl
|
|||||||
{
|
{
|
||||||
extern void GenerateAstFileNames(AstSymbolManager& manager, Ptr<CppParserGenOutput> parserOutput);
|
extern void GenerateAstFileNames(AstSymbolManager& manager, Ptr<CppParserGenOutput> parserOutput);
|
||||||
|
|
||||||
extern void WriteAstHeaderFile (AstDefFile* file, stream::StreamWriter& writer);
|
extern void WriteAstHeaderFile (AstDefFileGroup* group, stream::StreamWriter& writer);
|
||||||
extern void WriteAstCppFile (AstDefFile* file, const WString& astHeaderName, 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 WriteAstUtilityHeaderFile (AstDefFileGroup* group, 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 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 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 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 WriteAstBuilderHeaderFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||||
extern void WriteAstBuilderCppFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
extern void WriteAstBuilderCppFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||||
extern void WriteEmptyVisitorHeaderFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
extern void WriteEmptyVisitorHeaderFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||||
extern void WriteEmptyVisitorCppFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
extern void WriteEmptyVisitorCppFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||||
extern void WriteCopyVisitorHeaderFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
extern void WriteCopyVisitorHeaderFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||||
extern void WriteCopyVisitorCppFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
extern void WriteCopyVisitorCppFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||||
extern void WriteTraverseVisitorHeaderFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
extern void WriteTraverseVisitorHeaderFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||||
extern void WriteTraverseVisitorCppFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
extern void WriteTraverseVisitorCppFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||||
extern void WriteJsonVisitorHeaderFile (AstDefFile* file, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
extern void WriteJsonVisitorHeaderFile (AstDefFileGroup* group, Ptr<CppAstGenOutput> output, stream::StreamWriter& writer);
|
||||||
extern void WriteJsonVisitorCppFile (AstDefFile* file, 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 WriteAstAssemblerHeaderFile (AstSymbolManager& manager, Ptr<CppParserGenOutput> output, stream::StreamWriter& writer);
|
||||||
extern void WriteAstAssemblerCppFile (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);
|
extern void WriteAstFiles (AstSymbolManager& manager, Ptr<CppParserGenOutput> output, collections::Dictionary<WString, WString>& files);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2444,6 +2517,33 @@ namespace vl::glr::parsergen
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
.\SYNTAX\SYNTAXSYMBOL.H
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
@@ -2592,9 +2692,10 @@ RuleSymbol
|
|||||||
WString name;
|
WString name;
|
||||||
vint32_t currentClauseId = -1;
|
vint32_t currentClauseId = -1;
|
||||||
|
|
||||||
RuleSymbol(SyntaxSymbolManager* _ownerManager, const WString& _name);
|
RuleSymbol(SyntaxSymbolManager* _ownerManager, const WString& _name, vint _fileIndex);
|
||||||
public:
|
public:
|
||||||
StateList startStates;
|
StateList startStates;
|
||||||
|
vint fileIndex = -1;
|
||||||
bool isPublic = false;
|
bool isPublic = false;
|
||||||
bool isParser = false;
|
bool isParser = false;
|
||||||
bool isPartial = false;
|
bool isPartial = false;
|
||||||
@@ -2656,7 +2757,7 @@ SyntaxSymbolManager
|
|||||||
WString name;
|
WString name;
|
||||||
LrpFlagList lrpFlags;
|
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);
|
void RemoveRule(const WString& name);
|
||||||
|
|
||||||
StateSymbol* CreateState(RuleSymbol* rule, vint32_t clauseId);
|
StateSymbol* CreateState(RuleSymbol* rule, vint32_t clauseId);
|
||||||
@@ -2830,9 +2931,11 @@ Compiler
|
|||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
extern WString UnescapeLiteral(const WString& literal, wchar_t quot);
|
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 CompileAst(AstSymbolManager& astManager, AstDefFile* astDefFile, Ptr<GlrAstFile> file);
|
||||||
extern void CompileLexer(LexerSymbolManager& lexerManager, const WString& input);
|
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, collections::List<Ptr<GlrSyntaxFile>>& files);
|
||||||
|
extern Ptr<GlrSyntaxFile> CompileSyntax(AstSymbolManager& astManager, LexerSymbolManager& lexerManager, SyntaxSymbolManager& syntaxManager, Ptr<CppParserGenOutput> output, Ptr<GlrSyntaxFile> file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,6 +113,9 @@ void PrintCompileErrors(ParserSymbolManager& global)
|
|||||||
{
|
{
|
||||||
switch (error.location.type)
|
switch (error.location.type)
|
||||||
{
|
{
|
||||||
|
case ParserDefFileType::AstGroup:
|
||||||
|
Console::Write(L"[AstGroup:" + error.location.name + L"]");
|
||||||
|
break;
|
||||||
case ParserDefFileType::Ast:
|
case ParserDefFileType::Ast:
|
||||||
Console::Write(L"[Ast:" + error.location.name + L"]");
|
Console::Write(L"[Ast:" + error.location.name + L"]");
|
||||||
break;
|
break;
|
||||||
@@ -251,22 +254,33 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
for (auto elementAst : asts)
|
for (auto elementAst : asts)
|
||||||
{
|
{
|
||||||
WString name, file;
|
WString name;
|
||||||
READ_ATTRIBUTE(name, elementAst, L"name", L"/Parser/Asts/Ast@name");
|
READ_ATTRIBUTE(name, elementAst, L"name", L"/Parser/Asts/Ast@name");
|
||||||
READ_ATTRIBUTE(file, elementAst, L"file", L"/Parser/Asts/Ast@file[@name=\"" + name + L"\"]");
|
|
||||||
Console::WriteLine(L"Processing " + file + L" ...");
|
|
||||||
|
|
||||||
File astFile = workingDir / file;
|
auto astDefFileGroup = astManager.CreateFileGroup(name);
|
||||||
if (!astFile.Exists()) EXIT_ERROR(L"Missing ast definition file: " + astFile.GetFilePath().GetFullPath());
|
READ_ELEMENT_ITEMS(astDefFileGroup->cppNss, regexNamespace, elementAst, L"CppNamespace", L"/Parser/Asts/Ast@file[@name=\"" + name + L"\"]/CppNamespace");
|
||||||
auto astInput = astFile.ReadAllTextByBom();
|
READ_ELEMENT_ITEMS(astDefFileGroup->refNss, regexNamespace, elementAst, L"ReflectionNamespace", L"/Parser/Asts/Ast@file[@name=\"" + name + L"\"]/ReflectionNamespace");
|
||||||
auto ast = typeParser.ParseFile(astInput);
|
READ_ELEMENT(astDefFileGroup->classPrefix, elementAst, L"ClassPrefix", L"/Parser/Asts/Ast@file[@name=\"" + name + L"\"]/ClassPrefix");
|
||||||
EXIT_IF_PARSER_FAIL(errors, L"Syntax errors found in file: " + astFile.GetFilePath().GetFullPath());
|
|
||||||
|
|
||||||
auto astDefFile = astManager.CreateFile(name);
|
List<Pair<AstDefFile*, Ptr<GlrAstFile>>> astFiles;
|
||||||
READ_ELEMENT_ITEMS(astDefFile->cppNss, regexNamespace, elementAst, L"CppNamespace", L"/Parser/Asts/Ast@file[@name=\"" + name + L"\"]/CppNamespace");
|
for (auto elementFile : XmlGetElements(elementAst, L"File"))
|
||||||
READ_ELEMENT_ITEMS(astDefFile->refNss, regexNamespace, elementAst, L"ReflectionNamespace", L"/Parser/Asts/Ast@file[@name=\"" + name + L"\"]/ReflectionNamespace");
|
{
|
||||||
READ_ELEMENT(astDefFile->classPrefix, elementAst, L"ClassPrefix", L"/Parser/Asts/Ast@file[@name=\"" + name + L"\"]/ClassPrefix");
|
WString file;
|
||||||
CompileAst(astManager, astDefFile, ast);
|
READ_ATTRIBUTE(file, elementFile, L"file", L"/Parser/Asts/Ast/File@file");
|
||||||
|
Console::WriteLine(L"Processing " + file + L" ...");
|
||||||
|
|
||||||
|
File astFile = workingDir / file;
|
||||||
|
if (!astFile.Exists()) EXIT_ERROR(L"Missing ast definition file: " + astFile.GetFilePath().GetFullPath());
|
||||||
|
auto astInput = astFile.ReadAllTextByBom();
|
||||||
|
auto ast = typeParser.ParseFile(astInput);
|
||||||
|
EXIT_IF_PARSER_FAIL(errors, L"Syntax errors found in file: " + astFile.GetFilePath().GetFullPath());
|
||||||
|
|
||||||
|
auto astDefFile = astDefFileGroup->CreateFile(file);
|
||||||
|
astFiles.Add({ astDefFile,ast });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (astFiles.Count() == 0) EXIT_ERROR(L"Missing /Parser/Asts/Ast/File");
|
||||||
|
CompileAst(astManager, astFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXIT_IF_COMPILE_FAIL(global);
|
EXIT_IF_COMPILE_FAIL(global);
|
||||||
@@ -293,24 +307,30 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EXIT_ERROR(L"Missing /Parser/Asts");
|
EXIT_ERROR(L"Missing /Parser/Lexer");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto elementSyntax = XmlGetElement(config->rootElement, L"Syntax"))
|
if (auto elementSyntax = XmlGetElement(config->rootElement, L"Syntax"))
|
||||||
{
|
{
|
||||||
WString name, file;
|
WString name;
|
||||||
READ_ATTRIBUTE(name, elementSyntax, L"name", L"/Parser/Syntax@name");
|
READ_ATTRIBUTE(name, elementSyntax, L"name", L"/Parser/Syntax@name");
|
||||||
READ_ATTRIBUTE(file, elementSyntax, L"file", L"/Parser/Syntax@file[@name=\"" + name + L"\"]");
|
syntaxManager.name = name;
|
||||||
Console::WriteLine(L"Processing " + file + L" ...");
|
|
||||||
|
|
||||||
File syntaxFile = workingDir / file;
|
|
||||||
auto syntaxInput = syntaxFile.ReadAllTextByBom();
|
|
||||||
auto syntax = ruleParser.ParseFile(syntaxInput);
|
|
||||||
EXIT_IF_PARSER_FAIL(errors, L"Syntax errors found in file: " + syntaxFile.GetFilePath().GetFullPath());
|
|
||||||
|
|
||||||
List<Ptr<GlrSyntaxFile>> syntaxFiles;
|
List<Ptr<GlrSyntaxFile>> syntaxFiles;
|
||||||
syntaxFiles.Add(syntax);
|
for (auto elementFile : XmlGetElements(elementSyntax, L"File"))
|
||||||
syntaxManager.name = name;
|
{
|
||||||
|
WString file;
|
||||||
|
READ_ATTRIBUTE(file, elementFile, L"file", L"/Parser/Syntax/File@file");
|
||||||
|
Console::WriteLine(L"Processing " + file + L" ...");
|
||||||
|
|
||||||
|
File syntaxFile = workingDir / file;
|
||||||
|
auto syntaxInput = syntaxFile.ReadAllTextByBom();
|
||||||
|
auto syntax = ruleParser.ParseFile(syntaxInput);
|
||||||
|
EXIT_IF_PARSER_FAIL(errors, L"Syntax errors found in file: " + syntaxFile.GetFilePath().GetFullPath());
|
||||||
|
syntaxFiles.Add(syntax);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (syntaxFiles.Count() == 0) EXIT_ERROR(L"Missing /Parser/Syntax/File");
|
||||||
CompileSyntax(astManager, lexerManager, syntaxManager, output, syntaxFiles);
|
CompileSyntax(astManager, lexerManager, syntaxManager, output, syntaxFiles);
|
||||||
EXIT_IF_COMPILE_FAIL(global);
|
EXIT_IF_COMPILE_FAIL(global);
|
||||||
|
|
||||||
@@ -326,7 +346,7 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EXIT_ERROR(L"Missing /Parser/Asts");
|
EXIT_ERROR(L"Missing /Parser/Syntax");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -334,7 +354,7 @@ int main(int argc, char* argv[])
|
|||||||
for (auto elementAst : XmlGetElements(elementAsts, L"Ast"))
|
for (auto elementAst : XmlGetElements(elementAsts, L"Ast"))
|
||||||
{
|
{
|
||||||
auto name = XmlGetAttribute(elementAst, L"name")->value.value;
|
auto name = XmlGetAttribute(elementAst, L"name")->value.value;
|
||||||
auto astOutput = output->astOutputs[astManager.Files()[name]];
|
auto astOutput = output->astOutputs[astManager.FileGroups()[name]];
|
||||||
|
|
||||||
if (auto elementBlocked = XmlGetElement(elementAst, L"BlockedUtilities"))
|
if (auto elementBlocked = XmlGetElement(elementAst, L"BlockedUtilities"))
|
||||||
{
|
{
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user