From fb09faf5be97243becc68feefed319cebe1842a1 Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Sun, 14 Nov 2004 18:56:13 +0000 Subject: [PATCH] Parser bug-fix This was SVN commit r1313. --- source/main.cpp | 5 ++++- source/ps/Parser.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++-- source/ps/Parser.h | 7 ++++--- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/source/main.cpp b/source/main.cpp index ae8d621daf..3e3cf69ea2 100755 --- a/source/main.cpp +++ b/source/main.cpp @@ -853,7 +853,7 @@ static void Init(int argc, char* argv[]) MICROLOG(L"In init"); // If you ever want to catch a particular allocation: - //_CrtSetBreakAlloc(7239); + //_CrtSetBreakAlloc(32894); #ifdef _MSC_VER u64 TSC=rdtsc(); @@ -1213,6 +1213,9 @@ int main(int argc, char* argv[]) MICROLOG(L"Init"); Init(argc, argv); + extern void PerformTests(); + PerformTests(); + while(!quit) { MICROLOG(L"(Simulation) Frame"); diff --git a/source/ps/Parser.cpp b/source/ps/Parser.cpp index 457f1e7bb6..84ba561582 100755 --- a/source/ps/Parser.cpp +++ b/source/ps/Parser.cpp @@ -336,7 +336,7 @@ bool CParserLine::ParseString(const CParser& Parser, string strLine) strLine = strLine.substr(0,pos); */ - // Divide string into smaller vectors, seperators are unusual signs + // Divide string into smaller vectors, separators are unusual signs // * * * * for (i=0; im_Type == typeNull) + { + // Match without doing anything (leaving Match==true) + } + // CHECK NAME else { @@ -705,7 +711,7 @@ bool CParserLine::ParseString(const CParser& Parser, string strLine) m_Arguments.push_back(value); // Now BREAK EVERYTHING ! - // We're done, we found are match and let's get out + // We're done, we found our match and let's get out LookNoFurther = true; //Match = true; break; @@ -846,7 +852,44 @@ bool CParser::InputTaskType(const string& strName, const string& strSyntax) else if (strSyntax[i] == START_DYNAMIC || strSyntax[i] == START_OPTIONAL) { + + // Slight hack: because things are stored in a binary tree, + // it can't handle "<[a][b]>" -- the <...> node has only + // one slot for an optional [...] node. To avoid this problem, + // typeNull nodes are used to indicate things that always + // succeed but can have altnodes attached: +/* + parent parent + \ ===> \ + <...> ===> <...> <-- CurNode + / \ / \ + / \ / \ +next [a] Null [a] <-- added NewNode + / \ + next [b] +*/ + if (CurNode->m_AltNode) + { + + // Rearrange the tree, as shown above: + + // Create NewNode + CParserTaskTypeNode* NewNode = new CParserTaskTypeNode(); + NewNode->m_ParentNode = CurNode; + NewNode->m_Letter = '\0'; + NewNode->m_Type = typeNull; + + // Copy 'next' into NewNode + NewNode->m_NextNode = CurNode->m_NextNode; + // Replace 'next' with NewNode inside CurNode + CurNode->m_NextNode = NewNode; + + // Update CurNode, so the following code inserts into [b] + CurNode = NewNode; + } + // Dive into the alternative node + assert(! CurNode->m_AltNode); CurNode->m_AltNode = new CParserTaskTypeNode(); CurNode->m_AltNode->m_ParentNode = CurNode; @@ -891,6 +934,7 @@ bool CParser::InputTaskType(const string& strName, const string& strSyntax) { // Check if this is the first input // CONSTRUCT A CHILD NODE + assert(! CurNode->m_NextNode); CurNode->m_NextNode = new CParserTaskTypeNode(); CurNode->m_NextNode->m_ParentNode = CurNode; @@ -938,6 +982,7 @@ bool CParser::InputTaskType(const string& strName, const string& strSyntax) if (Extract == false) { // CONSTRUCT A CHILD NODE + assert(! CurNode->m_NextNode); CurNode->m_NextNode = new CParserTaskTypeNode(); CurNode->m_NextNode->m_ParentNode = CurNode; diff --git a/source/ps/Parser.h b/source/ps/Parser.h index 3acce8da9e..3e7dd0eff0 100755 --- a/source/ps/Parser.h +++ b/source/ps/Parser.h @@ -50,7 +50,8 @@ enum _ParserValueType typeIdent, typeValue, typeRest, - typeAddArg + typeAddArg, + typeNull }; //------------------------------------------------- @@ -117,7 +118,7 @@ public: // Free node pointers that are below this void DeleteChildren(); - // Either the node is a letter or a type, if m_Leter is '\0' + // Either the node is a letter or a type, if m_Letter is '\0' // then check m_Type what it is char m_Letter; _ParserValueType m_Type; @@ -134,7 +135,7 @@ public: // false means AltNode is just an optional part [...] bool m_AltNodeRepeatable; - // Whenever a dynamic argument is used, it's first node is stored in this + // Whenever a dynamic argument is used, its first node is stored in this // as an alternative node. The parser first checks if there is an // alternative route, and if it applies to the next node. If not, proceed // as usual with m_String and the next node