public int CountTokenByType(SymToken.TClass aClass) { int count = 0; // foreach (SymNode n in this) { if (n is SymNodeToken) { bool isSpecial = (n is SymTokenBalancerNode); // if (isSpecial == false) { SymToken t = ((SymNodeToken)n).Token; // if (t.Class == aClass) { ++count; } } } } // return(count); }
protected bool IsClosingTokenMatch(SymToken aToken, out SymTokenBalancerMatchCriteria aCriteria, int aLevelNumber) { aCriteria = null; bool matchFound = false; // int index = iClosingTokens.IndexOf(aToken); while (index >= 0 && matchFound == false) { SymToken token = iClosingTokens[index]; System.Diagnostics.Debug.Assert(token.Tag != null && token.Tag is SymTokenBalancerMatchCriteria); SymTokenBalancerMatchCriteria criteria = (SymTokenBalancerMatchCriteria)token.Tag; if (criteria.Matches(aLevelNumber)) { aCriteria = criteria; matchFound = true; } else { index = iClosingTokens.IndexOf(aToken, index + 1); } } return(matchFound); }
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 virtual bool OfferToken(SymToken aToken) { bool consumed = false; int currentLevelNumber = CurrentLevelNumber; SymTokenBalancerMatchCriteria tokenExtendedInfo; // Check for bracket matches if (IsOpeningTokenMatch(aToken, out tokenExtendedInfo, currentLevelNumber)) { LevelStarted(aToken, tokenExtendedInfo); consumed = true; } else if (IsClosingTokenMatch(aToken, out tokenExtendedInfo, currentLevelNumber)) { LevelFinished(aToken, tokenExtendedInfo); consumed = true; } // Always consume the token if it didn't match if (!consumed) { AddToCurrentLevel(aToken); consumed = true; } // return(consumed); }
protected bool IsTokenExactMatch(SymToken aToken, SymTokenContainer aContainerToSearch) { bool ret = false; // foreach (SymToken t in aContainerToSearch) { if (t.Equals(aToken)) { if (aToken.Tag != null && t.Tag != null) { if ((aToken.Tag is SymTokenBalancerMatchCriteria) && (t.Tag is SymTokenBalancerMatchCriteria)) { SymTokenBalancerMatchCriteria extendedInfo1 = (SymTokenBalancerMatchCriteria)aToken.Tag; SymTokenBalancerMatchCriteria extendedInfo2 = (SymTokenBalancerMatchCriteria)t.Tag; // if (extendedInfo1.Equals(extendedInfo2)) { ret = true; break; } } } } } // return(ret); }
public SymToken(SymToken aToken) { iValue = aToken.Value; iClass = aToken.Class; iType = aToken.Type; iPosition = aToken.Position; iTag = aToken.Tag; }
public SymToken PopHead() { System.Diagnostics.Debug.Assert(Count > 0); SymToken ret = PeekHead; iTokens.RemoveAt(0); return(ret); }
protected virtual void AddToCurrentLevel(SymToken aToken) { System.Diagnostics.Debug.Write(aToken.Value); SymNodeToken node = new SymNodeToken(aToken); iTree.CurrentNode.Add(node); }
public void ForceCombine(SymToken aToken) { System.Diagnostics.Debug.Assert(Class != SymToken.TClass.EClassNull); // string newValue = iValue + aToken.Value; iValue = newValue; }
public SymToken PopTail() { System.Diagnostics.Debug.Assert(Count > 0); SymToken ret = PeekTail; iTokens.RemoveAt(iTokens.Count - 1); return(ret); }
public SymTokenBalancerMatchCriteria(SymToken aDiametricToken, bool aEmit, bool aChangesLevel, TLevelExpectations aLevelExpectations, int aAssociatedLevel, TAssociatedBehaviour aAssociatedBehaviour) { iDiametricToken = aDiametricToken; iEmit = aEmit; iChangesLevel = aChangesLevel; iLevelExpectations = aLevelExpectations; iAssociatedLevel = aAssociatedLevel; iAssociatedBehaviour = aAssociatedBehaviour; }
public void Append(SymToken aToken) { iTokens.Add(aToken); // if (iTokenHandlers != null) { iTokenHandlers(aToken); } }
public void RegisterClosingToken(SymToken aToken, SymTokenBalancerMatchCriteria aCriteria) { SymToken copy = new SymToken(aToken); copy.Tag = aCriteria; // if (IsTokenExactMatch(copy, iClosingTokens) == false) { iClosingTokens.Append(copy); } }
public void Combine(SymToken aToken) { if (aToken.Value == ")" || Value == ")") { int x = 9; } System.Diagnostics.Debug.Assert(Class != SymToken.TClass.EClassNull); System.Diagnostics.Debug.Assert(aToken.CombiningAllowed == true); System.Diagnostics.Debug.Assert(CombiningAllowed == true); // ForceCombine(aToken); }
public int TokenCount(SymToken aTokenToCount) { int count = 0; // foreach (SymToken t in this) { if (t.Equals(aTokenToCount)) { ++count; } } // return(count); }
public virtual void RegisterBalancerTokens(bool aEmitLevelZeroBrackets) { // These are the important tokens relating to function arguments SymToken bracketTokenOpening = new SymToken("(", SymToken.TClass.EClassSymbol, SymToken.TType.ETypeUnidentified); SymToken bracketTokenClosing = new SymToken(")", SymToken.TClass.EClassSymbol, SymToken.TType.ETypeUnidentified); // When parsing a function name and arguments, we want to start a new level when we see the first opening // brace, but we don't want to emit the token. RegisterOpeningToken(bracketTokenOpening, bracketTokenClosing, aEmitLevelZeroBrackets, true, TLevelExpectations.ELevelExpectationsAtLevel, 0, TAssociatedBehaviour.EBehaviourRemoveReduntantBracketing); RegisterClosingToken(bracketTokenClosing, bracketTokenOpening, aEmitLevelZeroBrackets, true, TLevelExpectations.ELevelExpectationsAtLevel, 0, TAssociatedBehaviour.EBehaviourRemoveReduntantBracketing); // For other brackets, we want to reduce the complexity by removing any redundant entries RegisterOpeningToken(bracketTokenOpening, bracketTokenClosing, true, true, TLevelExpectations.ELevelExpectationsAboveLevelNumber, 0, TAssociatedBehaviour.EBehaviourRemoveReduntantBracketing); RegisterClosingToken(bracketTokenClosing, bracketTokenOpening, true, true, TLevelExpectations.ELevelExpectationsAboveLevelNumber, 0, TAssociatedBehaviour.EBehaviourRemoveReduntantBracketing); }
public override bool Equals(object aObject) { bool same = false; // if (aObject is SymToken) { SymToken otherToken = (SymToken)aObject; // if (otherToken.Class == Class) { if (otherToken.Type == Type) { same = (otherToken.Value == Value); } } } // return(same); }
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; }
public int LastIndexOf(SymToken aToken, int aStartIndex) { int index = iTokens.LastIndexOf(aToken, aStartIndex); return(index); }
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(); } } }
public bool IsPresent(SymToken aToken) { int index = IndexOf(aToken); return(index >= 0 && index < Count); }
public SymTokenBalancerNodeEmittedElement(SymToken aToken, SymTokenBalancerMatchCriteria aMatchCriteria) : base(aMatchCriteria) { iToken = aToken; }
public SymTokenBalancerNode(SymToken aToken) : base(aToken) { }
public void RegisterClosingToken(SymToken aToken, SymToken aDiametricToken, bool aEmit, bool aStartsNewLevel, TLevelExpectations aLevelExpectations, int aAssociatedLevel, TAssociatedBehaviour aBehaviour) { SymTokenBalancerMatchCriteria criteria = new SymTokenBalancerMatchCriteria(aDiametricToken, aEmit, aStartsNewLevel, aLevelExpectations, aAssociatedLevel, aBehaviour); RegisterClosingToken(aToken, criteria); }
public int IndexOf(SymToken aToken) { int index = iTokens.IndexOf(aToken); return(index); }