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;
            }
        }
示例#2
0
        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);
        }
示例#3
0
 protected virtual void NotifyEventLevelFinished(int aLevelCount, SymNode aOldLevel, SymNode aNewLevel)
 {
     if (EventLevelFinished != null)
     {
         EventLevelFinished(aLevelCount, aOldLevel, aNewLevel);
     }
 }
示例#4
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);
        }
示例#5
0
        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);
                }
            }
        }
示例#6
0
        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);
                }
            }
        }
示例#7
0
 protected override void ExtractToContainer(SymNode aNode, SymTokenContainer aContainer)
 {
     if (aNode is SymTokenBalancerNodeEmittedElement)
     {
         SymTokenBalancerNodeEmittedElement node = (SymTokenBalancerNodeEmittedElement)aNode;
         node.AddToContainerIfEmittable(aContainer);
     }
 }
示例#8
0
 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);
        }
示例#10
0
        private SymNode CalculateNewParentNode()
        {
            SymNode ret = WorkerContext.Document.CurrentNode;

            //
            if (iDyingAction != TDyingAction.EWhenDyingTakeNoAction && WorkerContext.Document.CurrentNode.HasParent)
            {
                ret = WorkerContext.Document.CurrentNode.Parent;
            }
            //
            return(ret);
        }
示例#11
0
 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);
     }
 }
示例#12
0
        public override void Replace(SymNode aReplacement)
        {
            if (HasPrevious && Previous is SymTokenBalancerNodeEmittedElement)
            {
                Previous.Remove();
            }
            if (HasNext && Next is SymTokenBalancerNodeEmittedElement)
            {
                Next.Remove();
            }

            base.Replace(aReplacement);
        }
示例#13
0
        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));
        }
示例#15
0
        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);
                }
            }
        }
示例#16
0
        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();
                            }
                        }
                    }
                }
            }
        }
示例#17
0
    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;
        }
    }
示例#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;
        }
示例#19
0
    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]);
        }
    }
示例#20
0
        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();
        }
示例#21
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();
                }
            }
        }
示例#22
0
 protected virtual void ExtractToContainer(SymNode aNode, SymTokenContainer aContainer)
 {
 }
示例#23
0
    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);
    }
示例#24
0
        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);
        }
示例#25
0
 protected virtual bool NodeIsExtractable(SymNode aNode)
 {
     return(false);
 }
 private void TokenBalancer_EventLevelFinished(int aLevelCount, SymNode aOldLevel, SymNode aNewLevel)
 {
 }
示例#27
0
 public SymArgumentSubLevel(SymNode aCopyFrom)
 {
     AppendChildrenFrom(aCopyFrom);
 }
示例#28
0
 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);
        }