private void TokenBalancerEventLevelFinished(int aLevelCount, SymNode aOldLevel, SymNode aNewLevel) { switch (State) { case TState.EStateDefineName: MakeDefineName(); State = TState.EStateDefineArguments; break; case TState.EStateDefineArguments: if (aLevelCount == 0) { MakeDefineArgument(); State = TState.EStateMiddleWhiteSpace; } break; case TState.EStateDefineValue: case TState.EStateInitialWhiteSpace: case TState.EStateMiddleWhiteSpace: default: System.Diagnostics.Debug.Assert(false); break; } }
public override SymParserWorker.TTokenConsumptionType OfferToken(SymToken aToken) { iConsumedTokens.Append(aToken); if (aToken.Class == iTerminatingClassType) { // Work out which node will become the parent (if we are configured in that way) SymNode newParent = CalculateNewParentNode(); // Call back to parent class HandleTerminatingConditionMatch(aToken); // Reached the new line token. Stop receiving the tokens. We're done. WorkerContext.Parent.RemoveChild(this); // If the dying action was to make the relative parent node // the current one, then we must call CalculateNewParentNode again // after the HandleTerminatingConditionMatch callback - since // it may have changed the tree. if (iDyingAction == TDyingAction.EWhenDyingMakeRelativeParentNodeCurrent) { newParent = CalculateNewParentNode(); } // Update the document with the new parent node WorkerContext.Document.CurrentNode = newParent; } // return(TTokenConsumptionType.ETokenConsumed); }
protected virtual void NotifyEventLevelFinished(int aLevelCount, SymNode aOldLevel, SymNode aNewLevel) { if (EventLevelFinished != null) { EventLevelFinished(aLevelCount, aOldLevel, aNewLevel); } }
protected static int CountTokenByType(SymNode aNodeWithChildren, SymToken.TClass aClass) { int count = 0; // foreach (SymNode n in aNodeWithChildren) { bool isNodeToken = (n is SymNodeToken); // if (isNodeToken) { bool isSpecial = ((n is SymTokenBalancerNode) || (n is SymTokenBalancerNodeEmittedElement)); // if (isSpecial == false) { SymToken t = ((SymNodeToken)n).Token; // if (t.Class == aClass) { ++count; } } } } // return(count); }
public void ConvertEmittedElementsToRealTokenNodes(bool aRecurse) { int i = ChildCount; // while (i > 0) { SymNode child = this[--i]; // if (child is SymTokenBalancerNodeEmittedElement) { SymTokenBalancerNodeEmittedElement emittedElement = (SymTokenBalancerNodeEmittedElement)child; if (emittedElement.Emit) { SymNodeToken replacement = new SymNodeToken(emittedElement.Token); InsertChild(replacement, child); } child.Remove(); } else if (child is SymTokenBalancerMarkerLevelNode && aRecurse) { SymTokenBalancerMarkerLevelNode childLevel = (SymTokenBalancerMarkerLevelNode)child; childLevel.ConvertEmittedElementsToRealTokenNodes(aRecurse); } } }
public static void RemoveWhiteSpace(SymNode aNode, bool aRecurse) { int count = aNode.ChildCount; for (int i = count - 1; i >= 0; i--) { SymNode basicNode = aNode[i]; // If the node is whitespace, then remove it if (basicNode is SymNodeToken) { SymNodeToken tokenNode = (SymNodeToken)basicNode; bool isWhiteSpace = (tokenNode.Token.Class == SymToken.TClass.EClassWhiteSpace); // if (isWhiteSpace) { System.Diagnostics.Debug.Assert(basicNode.HasChildren == false); basicNode.Remove(); } } // Remove whitespace from this node's children if (basicNode.HasChildren && aRecurse) { RemoveWhiteSpace(basicNode, aRecurse); } } }
protected override void ExtractToContainer(SymNode aNode, SymTokenContainer aContainer) { if (aNode is SymTokenBalancerNodeEmittedElement) { SymTokenBalancerNodeEmittedElement node = (SymTokenBalancerNodeEmittedElement)aNode; node.AddToContainerIfEmittable(aContainer); } }
protected override void ExtractToDocument(SymNode aNode, SymTokenDocument aDocument) { if (aNode is SymTokenBalancerNodeEmittedElement) { SymTokenBalancerNodeEmittedElement node = (SymTokenBalancerNodeEmittedElement)aNode; node.AddToDocumentIfEmittable(aDocument); } }
public virtual SymArgument MakeArgument(SymNode aLevelToMakeArgumentsFrom) { SymArgument argument = new SymArgument(); // Convert (recursively) any emitted elements to real tokens if (aLevelToMakeArgumentsFrom is SymTokenBalancerMarkerLevelNode) { SymTokenBalancerMarkerLevelNode levelNode = (SymTokenBalancerMarkerLevelNode)aLevelToMakeArgumentsFrom; levelNode.ConvertEmittedElementsToRealTokenNodes(true /*recurse*/); } // Now actually obtain the argument tokens int count = aLevelToMakeArgumentsFrom.ChildCount; int i = 0; // while (i < count) { SymNode n = aLevelToMakeArgumentsFrom[0]; // We always remove any other nodes, irrespective of their type. // This is to ensure that the document tree does not get cluttered // with redundant argument token info. n.Remove(); // Now we decide what to do... if (n is SymTokenBalancerMarkerArgumentNode) { // We've reached the argument itself. This is the // signal to stop processing. We remove the argument node // since its not relevant to the production of the tree. break; } else if (n is SymTokenBalancerMarkerLevelNode) { // Create a new sub-argument node and copy over the // children. SymTokenBalancerMarkerLevelNode levelNode = (SymTokenBalancerMarkerLevelNode)n; SymArgumentSubLevel subLevel = levelNode.AsArgumentSubLevel(true); argument.CurrentNode.Add(subLevel); } else if (n is SymTokenBalancerNodeEmittedElement) { System.Diagnostics.Debug.Assert(false); // shouldn't get here anymore! } else if (n is SymNodeToken) { // Node is implicitly removed since it transfers // from one tree to another. argument.CurrentNode.Add(n); } count = aLevelToMakeArgumentsFrom.ChildCount; } // SymTokenUtils.RemoveWhiteSpace(argument, true); return(argument); }
private SymNode CalculateNewParentNode() { SymNode ret = WorkerContext.Document.CurrentNode; // if (iDyingAction != TDyingAction.EWhenDyingTakeNoAction && WorkerContext.Document.CurrentNode.HasParent) { ret = WorkerContext.Document.CurrentNode.Parent; } // return(ret); }
private void BuildRecursiveTokenValueString(SymNode aNode, ref StringBuilder aString) { if (aNode is SymNodeToken) { SymNodeToken tokenNode = (SymNodeToken)aNode; aString.Append(tokenNode.Token); } // foreach (SymNode child in aNode) { BuildRecursiveTokenValueString(child, ref aString); } }
public override void Replace(SymNode aReplacement) { if (HasPrevious && Previous is SymTokenBalancerNodeEmittedElement) { Previous.Remove(); } if (HasNext && Next is SymTokenBalancerNodeEmittedElement) { Next.Remove(); } base.Replace(aReplacement); }
protected override bool NodeIsExtractable(SymNode aNode) { bool ret = false; // if (aNode is SymTokenBalancerNodeEmittedElement) { SymTokenBalancerNodeEmittedElement node = (SymTokenBalancerNodeEmittedElement)aNode; ret = node.Emit; } // return(ret); }
public virtual SymArgument MakeArgument() { SymNode levelNodeToObtainArgumentsFrom = CurrentNode; // Try to work out whether we have a leve node at the current // scope which should be preferred t object levelNodeObject = levelNodeToObtainArgumentsFrom.ChildByType(typeof(SymTokenBalancerMarkerLevelNode)); if (levelNodeObject != null) { levelNodeToObtainArgumentsFrom = (SymNode)levelNodeObject; } return(MakeArgument(levelNodeToObtainArgumentsFrom)); }
protected virtual void PerformEndLevelBehaviour(SymNode aLevel, SymTokenBalancerMatchCriteria aCriteria) { #region Example step (11a) from LevelFinished method // // We then add the closing bracket to level |1| which means // that we can attempt to simplify level |2| entirely. This is the // situation prior to simplification. // // |0| [ROOT] // | // |1| [TEST] [(] [@] [)] // | // |2| [(] [*] [)] [+] [(] [*] [)] // | | // |3| [ ] [B] [ ] [+] [ ] [C] [ ] [E] // // aLevel would be the @ node at level |1|. // // We remove redundant bracketing from our children, i.e. those on level |2|, not from our own level. // Our parent takes care of removing this level's redundant bracketing (when it's level is completed) // or then when an argument separator token is handled. // // We must iterate through level |1|'s children to find other level nodes. We check whether each // child level node can be simplified by checking its children (i.e. our grandchildren). // #endregion if (aCriteria.IsAssociatedBehaviourRemoveRedundantBracketing) { int index = 0; object childLevelNodeObject = aLevel.ChildByType(typeof(SymTokenBalancerMarkerLevelNode), ref index); while (childLevelNodeObject != null) { SymTokenBalancerMarkerLevelNode childLevelNode = (SymTokenBalancerMarkerLevelNode)childLevelNodeObject; if (childLevelNode.CanBeSubsumed) { childLevelNode.Subsume(); } // Try to find next level node ++index; childLevelNodeObject = aLevel.ChildByType(typeof(SymTokenBalancerMarkerLevelNode), ref index); } } }
protected void SimplifyLevel(SymTokenBalancerMarkerLevelNode aLevel) { System.Diagnostics.Debug.Assert(aLevel.IsRoot == false && aLevel.HasParent); SymNode parent = aLevel.Parent; int levelNumber = parent.Depth; // int childCount = parent.ChildCount; while (--childCount >= 0) { SymNode possibleLevelNode = parent[childCount]; // We're looking to remove redundant bracketing from either side of the level // node. First check if we have a level node... if (possibleLevelNode is SymTokenBalancerMarkerLevelNode) { // Then check whether it has a previous and a next node. These should // be the SymTokenBalancerNodeEmittedElement nodes if (possibleLevelNode.HasPrevious && possibleLevelNode.HasNext) { if (possibleLevelNode.Previous is SymTokenBalancerNodeEmittedElement && possibleLevelNode.Next is SymTokenBalancerNodeEmittedElement) { if (LevelCanBeMergedWithParent(possibleLevelNode as SymTokenBalancerMarkerLevelNode)) { SymTokenBalancerNodeEmittedElement previous = (SymTokenBalancerNodeEmittedElement)possibleLevelNode.Previous; SymTokenBalancerNodeEmittedElement next = (SymTokenBalancerNodeEmittedElement)possibleLevelNode.Next; // Insert value node prior to previous node (which is the opening bracket token). parent.InsertChildrenFrom(possibleLevelNode, previous.Previous); // Remove the opening bracket token previous.Remove(); // Remove the level marker token possibleLevelNode.Remove(); // Remove the closing bracket token. next.Remove(); } } } } } }
public void detectSymmetry(int nLevel, List <Symbol> nState) { level = nLevel; state = nState; asymetryList.Clear(); elemCount = 0; int index = 0; symmetryNode = _getNode(ref index, level); _fillNodeValues(symmetryNode); returnValue = 0; for (int i = 0; i < asymetryList.Count; i++) { returnValue += asymetryList[i].delta * asymetryList[i].weight; } }
protected virtual void LevelStarted(SymToken aToken, SymTokenBalancerMatchCriteria aMatchCriteria) { System.Diagnostics.Debug.Write(System.Environment.NewLine + aToken.Value); // Always store the node element so that we can balance brackets SymTokenBalancerNodeEmittedElement node = new SymTokenBalancerNodeEmittedElement(aToken, aMatchCriteria); iTree.CurrentNode.Add(node); // Store the token (with the level) so we can check for open/close mis-matches SymTokenBalancerMarkerLevelNode levelNode = new SymTokenBalancerMarkerLevelNode(aMatchCriteria); iTree.CurrentNode.Add(levelNode); SymNode oldLevel = iTree.CurrentNode; SymNode newLevel = levelNode; NotifyEventLevelStarted(CurrentLevelNumber, oldLevel, newLevel); iTree.CurrentNode = levelNode; }
void _fillNodeValues(SymNode node) { sumElement se = new sumElement(); se.level = node.level; int leftSum = 0; for (int i = 0; i < node.leftBranches.Count; i++) { leftSum += node.leftBranches[i].allCount; } int rightSum = 0; for (int i = 0; i < node.rightBranches.Count; i++) { rightSum += node.rightBranches[i].allCount; } //se.delta = (leftSum + rightSum) == 0 ? 0 : (float)Mathf.Abs (leftSum - rightSum) / (float)(leftSum + rightSum); se.delta = (leftSum + rightSum) == 0 ? 0 : (float)Mathf.Abs(leftSum - rightSum) / (float)(node.allCount); se.weight = (float)node.allCount / (float)symmetryNode.allCount; asymetryList.Add(se); for (int i = 0; i < node.leftBranches.Count; i++) { _fillNodeValues(node.leftBranches[i]); } for (int i = 0; i < node.rightBranches.Count; i++) { _fillNodeValues(node.rightBranches[i]); } }
public void Subsume() { System.Diagnostics.Debug.Assert(IsComplete); // SymTokenBalancerNodeEmittedElement previous = EmittedElementPrevious; SymTokenBalancerNodeEmittedElement next = EmittedElementNext; // Insert all my children as siblings of myself (i.e. make my parent's // grandchildren its direct children - i.e. promote them up the tree // by one level). SymNode parent = Parent; ArrayList parentsChildren = Parent.Children; parent.InsertChildrenFrom(this /* my children */, previous.Previous /* move them before the opening bracket */); // Remove the opening bracket token previous.Remove(); // Remove the closing bracket token. next.Remove(); // Remove the level marker token, i.e myself Remove(); }
protected virtual void LevelFinished(SymToken aToken, SymTokenBalancerMatchCriteria aMatchCriteria) { #region Example // #define TEST1((( B )+( C ))+(E)) #region Key // |y| = level y // [x] = token of value 'x' // [*] = level marker node // [@] = (current) level marker node // [,] = argument node // [(] = opening level emitted token node // [)] = closing level emitted token node #endregion #region 1) First wave of opening level tokens processed... // // |0| [ROOT] // | // |1| [TEST] [(] [*] // | // |2| [(] [*] // | // |3| [(] [@] // | // |4| B // #endregion #region 2) Add closing level token to level |3|, which means that we can now // attempt to simplify level |4|. Level |4| does not contain any child // level nodes, so there is nothing to do here. // // |0| [ROOT] // | // |1| [TEST] [(] [*] // | // |2| [(] [@] // | // |3| [(] [*] [)] // | // |4| [ ] [B] [ ] // #endregion #region 3) Add plus symbol. This obviously becomes a child of the current node, // i.e. a child of level |2|. // // |0| [ROOT] // | // |1| [TEST] [(] [*] // | // |2| [(] [@] // | // |3| [(] [*] [)] [+] // | // |4| [ ] [B] [ ] // #endregion #region 4) Start new opening level node on level |3|. The newly added level node // on level |3| becomes the current node. // // |0| [ROOT] // | // |1| [TEST] [(] [*] // | // |2| [(] [*] // | // |3| [(] [*] [)] [+] [(] [@] // | | // |4| [ ] [B] [ ] // #endregion #region 5) Add the tokens near the 'C' to level |4| // // |0| [ROOT] // | // |1| [TEST] [(] [*] // | // |2| [(] [*] // | // |3| [(] [*] [)] [+] [(] [@] // | | // |4| [ ] [B] [ ] [ ] [C] [ ] // #endregion #region 6) Add closing level token to level |3|, which means that we can now // attempt to simplify level |4|, this time the [C] branch. // Since this branch does not contain any sub-level nodes, there is nothing // to be done and therefore levels |3| and |4| remain unchanged. // The level node at level |2| becomes the current node. // // |0| [ROOT] // | // |1| [TEST] [(] [*] // | // |2| [(] [@] // | // |3| [(] [*] [)] [+] [(] [*] [)] // | | // |4| [ ] [B] [ ] [ ] [C] [ ] // #endregion #region 7a) Add closing level token to level |2|, which means that we can now // attempt to simplify level |3|. // // |0| [ROOT] // | // |1| [TEST] [(] [*] // | // |2| [(] [@] [)] // | // |3| [(] [*] [)] [+] [(] [*] [)] // | | // |4| [ ] [B] [ ] [ ] [C] [ ] // #endregion #region 7b) We iterate through all the child level nodes of level |3| looking // to see if any of their children are simple enough to merge up into level // |3| itself. There are two level nodes in level |3| and both contain // children that are considered simple enough to merge up. This is because // they contain only a single non-whitespace node so we can simplify the level by // merging [B] from level |4| into level |3|. Likewise for [C]. // // This means that the bracketry on level |3| is redundant since level // |4| contains two sets of only a single non-whitespace token. Level |4| // is therefore entirely removed. // // The node at level |1| becomes the current node now. // // |0| [ROOT] // | // |1| [TEST] [(] [@] // | // |2| [(] [*] [)] // | // |3| [ ] [B] [ ] [+] [ ] [C] [ ] // #endregion #region 8) Add the plus symbol to level |2|. Then we start a new level // as a result of adding the opening bracket prior to 'E.' // This new level node at level |2| now becomes the current node. // // |0| [ROOT] // | // |1| [TEST] [(] [*] // | // |2| [(] [*] [)] [+] [(] [@] // | | // |3| [ ] [B] [ ] [+] [ ] [C] [ ] // #endregion #region 9) Now add the 'E' token to level |3|. // // |0| [ROOT] // | // |1| [TEST] [(] [*] // | // |2| [(] [*] [)] [+] [(] [@] // | | // |3| [ ] [B] [ ] [+] [ ] [C] [ ] [E] #endregion #region 10) We then add the closing bracket to level |2| which means // that we can attempt to simplify level |3|'s 'E' branch. There's nothing // to do though, since it doesn't contain any child level nodes. // The level node at level |1| again becomes current. // // |0| [ROOT] // | // |1| [TEST] [(] [@] // | // |2| [(] [*] [)] [+] [(] [*] [)] // | | // |3| [ ] [B] [ ] [+] [ ] [C] [ ] [E] #endregion #region 11a) We then add the closing bracket to level |1| which means // that we can attempt to simplify level |2| entirely. This is the // situation prior to simplification. // // |0| [ROOT] // | // |1| [TEST] [(] [@] [)] // | // |2| [(] [*] [)] [+] [(] [*] [)] // | | // |3| [ ] [B] [ ] [+] [ ] [C] [ ] [E] #endregion #region 11b) The two level nodes have been taged as *1 and *2 to make it // easier to explain the process. First we attempt to simplify level *1. // However, since its children consist of more than a single non-whitespace // token, we cannot make level |3|'s " B + C " branch as a replacement // for the bracket *1 tokens. Therefore this remains unchanged // // // |0| [ROOT] // | // |1| [TEST] [(] [@] [)] // | // |2| [(] [*1] [)] [+] [(] [*2] [)] // | | // |3| [ ] [B] [ ] [+] [ ] [C] [ ] [E] #endregion #region 11c) The level *2 node, however, contains only a single non-whitespace // child token, so it can be simplified. The level *2 node is replaced by // its child (E). // // The final tree looks like this, with the root as the current node once more: // // // |0| [@ROOT@] // | // |1| [TEST] [(] [*] [)] // | // |2| [(] [*] [)] [+] [E] // | // |3| [ ] [B] [ ] [+] [ ] [C] [ ] #endregion #endregion System.Diagnostics.Debug.Write(aToken.Value); System.Diagnostics.Debug.WriteLine(" "); // First of all, check if the current node has a parent. If we're at the root // node and we see a closing token, then we've got an imbalanced stack. if (iTree.CurrentNode.IsRoot) { NotifyEventLevelsImbalanced(); } else { // We expect the parent to be a level node System.Diagnostics.Debug.Assert(iTree.CurrentNode is SymTokenBalancerMarkerLevelNode); // Notify that we're about to change levels SymTokenBalancerMarkerLevelNode currentLevel = (SymTokenBalancerMarkerLevelNode)iTree.CurrentNode; SymNode newLevel = currentLevel.Parent; // The new level should not be null in this case System.Diagnostics.Debug.Assert(newLevel != null); // Check whether the closing token type is the same type as was used to start // the level. E.g. for this case is "([ANDMORE)]" which has a mis-match // between the opening and closing braces on each level. We can't simplify this // during the 'end level behaviour' stage. bool levelsBalanced = currentLevel.MatchCriteria.DiametricToken.Equals(aToken); // Switch levels iTree.CurrentNode = newLevel; // We have to refetch up-to-date match info, since we've changed levels, and the match // info that was used to enter this method is associated with the previous level // (not the new level number, which is now one less). SymTokenBalancerMatchCriteria matchCriteria; if (IsClosingTokenMatch(aToken, out matchCriteria, CurrentLevelNumber) == false) { matchCriteria = aMatchCriteria; } // Always store the node element so that we can balance brackets SymTokenBalancerNodeEmittedElement node = new SymTokenBalancerNodeEmittedElement(aToken, matchCriteria); iTree.CurrentNode.Add(node); // We have finished the current level. E.g. see step 6. Need to simplify level |2|, where possible. PerformEndLevelBehaviour(currentLevel); if (levelsBalanced) { // Notify that we've finished some level NotifyEventLevelFinished(CurrentLevelNumber, currentLevel, newLevel); } else { // Imbalance NotifyEventLevelsImbalanced(); } } }
protected virtual void ExtractToContainer(SymNode aNode, SymTokenContainer aContainer) { }
SymNode _getNode(ref int index, int level) { if (index >= state.Count) { return(null); } SymNode node = new SymNode(); node.level = level; node.stemCount = 0; node.allCount = 0; node.leftBranches = new List <SymNode> (); node.rightBranches = new List <SymNode> (); int stack = 1; while (index < state.Count && (stack >= 1)) { if ((state[index].symName == "S") || (state[index].symName == "L")) { elemCount++; node.stemCount++; index++; } else if (state[index].symName == "B") { if (level > 0) { index++; if (state[index].parameters["angle"].value > 0) { node.leftBranches.Add(_getNode(ref index, level - 1)); } else { node.rightBranches.Add(_getNode(ref index, level - 1)); } } else { stack++; index++; } } else if ((state[index].symName == "E") || (state[index].symName == "T")) { elemCount++; node.stemCount++; stack--; index++; } } int leftSum = 0; for (int i = 0; i < node.leftBranches.Count; i++) { leftSum += node.leftBranches[i].allCount; } int rightSum = 0; for (int i = 0; i < node.rightBranches.Count; i++) { rightSum += node.rightBranches[i].allCount; } node.allCount = node.stemCount + leftSum + rightSum; return(node); }
private AstNode ParseTerm() { AstNode node = null; if (TryParseToken(TokenType.Operator, "-")) { node = NODE_LINENO(new CallNode(ParseTerm(), NODE_LINENO(new SymNode("-@"), t), null), t); } else if (TryParseToken(TokenType.Operator, "+")) { node = ParseTerm(); } else if (TryParseToken(TokenType.Operator, "!")) { node = NODE_LINENO(new CallNode(ParseTerm(), NODE_LINENO(new SymNode("!"), t), null), t); } else { node = ParseSimpleTerm(); } if (node == null) { return(null); } while (true) { if (TryParseToken(TokenType.Separator, ".")) { string name = ParseName(); SymNode named = NODE_LINENO(new SymNode(name), t); if (TryParseToken(TokenType.Separator, "{")) { node = NODE_LINENO(new CallNode(node, named, ParseBlockExpression(true)), t); } else if (TryParseToken(TokenType.Operator, "=")) // A.method = something { var sym = NODE_LINENO(new SymNode(named.name + "="), t); return(NODE_LINENO(new CallNode(node, sym, ParseExpressionListAsArgs()), t)); } else if (NextTokenStartsExpressionList()) { node = NODE_LINENO(new CallNode(node, named, ParseExpressionListAsArgs()), t); } else { node = NODE_LINENO(new CallNode(node, named, null), t); } continue; } if (TryParseToken(TokenType.Separator, "::")) { string name = ParseName(); node = NODE_LINENO(new Colon2Node(node, NODE_LINENO(new SymNode(name), t)), t); continue; } if (TryParseToken(TokenType.Separator, "[")) { AstNode indexexpr = ParseExpression(); ParseToken(TokenType.Separator, "]"); node = NODE_LINENO(new ArrayRefNode(node, indexexpr), t); continue; } break; } return(node); }
protected virtual bool NodeIsExtractable(SymNode aNode) { return(false); }
private void TokenBalancer_EventLevelFinished(int aLevelCount, SymNode aOldLevel, SymNode aNewLevel) { }
public SymArgumentSubLevel(SymNode aCopyFrom) { AppendChildrenFrom(aCopyFrom); }
protected virtual void ExtractToDocument(SymNode aNode, SymTokenDocument aDocument) { }
private void EvaluateDefineNodes(SymNode aNode, SymTokenDocument aDocument, SymParserDocumentContext aContext) { foreach (SymNode n in aNode) { if (n is SymTokenBalancerMarkerLevelNode) { bool added = false; // SymTokenBalancerMarkerLevelNode levelNode = (SymTokenBalancerMarkerLevelNode)n; if (levelNode.IsFunction) { SymNodeToken functionNameNode = levelNode.FunctionName; // if (functionNameNode.Token.Equals(iDefinedNodeToken)) { SymTokenContainer defineName = levelNode.ChildTokens; string flattened = defineName.CoalescedTokenValue; // Get definition result bool isDefined = aContext.DefineDirectory.IsDefined(flattened); SymToken isDefinedToken = new SymToken(isDefined.ToString().ToLower(), SymToken.TClass.EClassAlphaNumeric, SymToken.TType.ETypeAlphaNumericNormal); // Remove already added "defined" text node from output document if (aDocument.CurrentNode.LastChild is SymNodeToken) { SymNodeToken last = (SymNodeToken)aDocument.CurrentNode.LastChild; if (last.Token.Equals(iDefinedNodeToken)) { last.Remove(); } } // Add result aDocument.CurrentNode.Add(new SymNodeToken(isDefinedToken)); added = true; } } if (added == false) { if (levelNode.HasPrevious && levelNode.Previous is SymTokenBalancerNodeEmittedElement) { levelNode.EmittedElementPrevious.AddToDocumentIfEmittable(aDocument); } SymNode newLevelNode = new SymNodeAddAsChild(); aDocument.CurrentNode.Add(newLevelNode); aDocument.CurrentNode = newLevelNode; EvaluateDefineNodes(n, aDocument, aContext); aDocument.MakeParentCurrent(); if (levelNode.HasNext && levelNode.Next is SymTokenBalancerNodeEmittedElement) { levelNode.EmittedElementNext.AddToDocumentIfEmittable(aDocument); } } } else if (n is SymNodeToken) { SymNodeToken node = (SymNodeToken)n; SymNodeToken copy = new SymNodeToken(node.Token); aDocument.CurrentNode.Add(copy); } else if (n is SymTokenBalancerNodeEmittedElement) { // Handled when the level marker is reached } } }
public static SymNodeConditionalExpression FindMostRecentConditionalExpression(SymNode aCurrentNode) { SymNodeConditionalExpression ret = null; // SymNodeEnumeratorUpTreeSiblingsFirst iterator = new SymNodeEnumeratorUpTreeSiblingsFirst(aCurrentNode); // foreach (SymNode node in iterator) { if (node is SymNodeConditionalExpression) { ret = (SymNodeConditionalExpression)node; break; } } // return(ret); }