Update release

This commit is contained in:
vczh
2023-07-30 15:29:03 -07:00
parent b055346a9d
commit 562d5722d9
10 changed files with 1910 additions and 615 deletions
+1
View File
@@ -4254,6 +4254,7 @@ Event Receiver
,lostFocus(_sender) ,lostFocus(_sender)
,caretNotify(_sender) ,caretNotify(_sender)
,clipboardNotify(_sender) ,clipboardNotify(_sender)
,renderTargetChanged(_sender)
{ {
} }
+229 -4
View File
@@ -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;
} }
} }
} }
+7 -2
View File
@@ -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);
File diff suppressed because it is too large Load Diff
+169 -66
View File
@@ -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);
} }
} }
} }
+46 -26
View 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.