Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
 public SymToken(SymToken aToken)
 {
     iValue    = aToken.Value;
     iClass    = aToken.Class;
     iType     = aToken.Type;
     iPosition = aToken.Position;
     iTag      = aToken.Tag;
 }
Ejemplo n.º 7
0
        public SymToken PopHead()
        {
            System.Diagnostics.Debug.Assert(Count > 0);
            SymToken ret = PeekHead;

            iTokens.RemoveAt(0);
            return(ret);
        }
Ejemplo n.º 8
0
        protected virtual void AddToCurrentLevel(SymToken aToken)
        {
            System.Diagnostics.Debug.Write(aToken.Value);

            SymNodeToken node = new SymNodeToken(aToken);

            iTree.CurrentNode.Add(node);
        }
Ejemplo n.º 9
0
        public void ForceCombine(SymToken aToken)
        {
            System.Diagnostics.Debug.Assert(Class != SymToken.TClass.EClassNull);
            //
            string newValue = iValue + aToken.Value;

            iValue = newValue;
        }
Ejemplo n.º 10
0
        public SymToken PopTail()
        {
            System.Diagnostics.Debug.Assert(Count > 0);
            SymToken ret = PeekTail;

            iTokens.RemoveAt(iTokens.Count - 1);
            return(ret);
        }
Ejemplo n.º 11
0
 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;
 }
Ejemplo n.º 12
0
 public void Append(SymToken aToken)
 {
     iTokens.Add(aToken);
     //
     if (iTokenHandlers != null)
     {
         iTokenHandlers(aToken);
     }
 }
Ejemplo n.º 13
0
        public void RegisterClosingToken(SymToken aToken, SymTokenBalancerMatchCriteria aCriteria)
        {
            SymToken copy = new SymToken(aToken);

            copy.Tag = aCriteria;
            //
            if (IsTokenExactMatch(copy, iClosingTokens) == false)
            {
                iClosingTokens.Append(copy);
            }
        }
Ejemplo n.º 14
0
        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);
        }
Ejemplo n.º 15
0
        public int TokenCount(SymToken aTokenToCount)
        {
            int count = 0;

            //
            foreach (SymToken t in this)
            {
                if (t.Equals(aTokenToCount))
                {
                    ++count;
                }
            }
            //
            return(count);
        }
Ejemplo n.º 16
0
        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);
        }
Ejemplo n.º 17
0
        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);
        }
Ejemplo n.º 18
0
        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;
        }
Ejemplo n.º 19
0
        public int LastIndexOf(SymToken aToken, int aStartIndex)
        {
            int index = iTokens.LastIndexOf(aToken, aStartIndex);

            return(index);
        }
Ejemplo n.º 20
0
        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();
                }
            }
        }
Ejemplo n.º 21
0
        public bool IsPresent(SymToken aToken)
        {
            int index = IndexOf(aToken);

            return(index >= 0 && index < Count);
        }
Ejemplo n.º 22
0
 public SymTokenBalancerNodeEmittedElement(SymToken aToken, SymTokenBalancerMatchCriteria aMatchCriteria)
     : base(aMatchCriteria)
 {
     iToken = aToken;
 }
Ejemplo n.º 23
0
 public SymTokenBalancerNode(SymToken aToken)
     : base(aToken)
 {
 }
Ejemplo n.º 24
0
        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);
        }
Ejemplo n.º 25
0
        public int IndexOf(SymToken aToken)
        {
            int index = iTokens.IndexOf(aToken);

            return(index);
        }