Пример #1
0
        /// <summary>
        ///     Builds the parse table from the given node and starting element.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="startingElement"></param>
        private void buildParseTable(StateNode <GrammarElement <T>, LRItem <T>[]> node, NonTerminal <T> startingElement)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (startingElement == null)
            {
                throw new ArgumentNullException("startingElement");
            }

            //clear the tables
            ActionTable.Clear();
            GotoTable.Clear();

            //get the breadth-first traversal of the graph
            List <StateNode <GrammarElement <T>, LRItem <T>[]> > t = node.GetBreadthFirstTraversal().ToList();


            //add the transitions for each node in the traversal
            for (var i = 0; i < t.Count; i++)
            {
                //for each transition in the node, add either a shift action or goto action
                foreach (KeyValuePair <GrammarElement <T>, StateNode <GrammarElement <T>, LRItem <T>[]> > transition in t[i].FromTransitions)
                {
                    if (transition.Key is Terminal <T> )
                    {
                        //add a shift from this state to the next state
                        addAction((Terminal <T>)transition.Key, i, new ShiftAction <T>(this, t.IndexOf(transition.Value)));
                    }
                    else
                    {
                        addGoto((NonTerminal <T>)transition.Key, i, t.IndexOf(transition.Value));
                    }
                }

                //for each of the items in the state that are at the end of a production,
                //add either a reduce action or accept action
                foreach (LRItem <T> item in t[i].Value.Where(a => a.IsAtEndOfProduction()))
                {
                    //if we would reduce to the starting element, then accept
                    if (item.LeftHandSide.Equals(startingElement))
                    {
                        addAction(item.LookaheadElement, i, new AcceptAction <T>(this, item));
                    }
                    //otherwise, add a reduce action
                    else
                    {
                        addAction(item.LookaheadElement, i, new ReduceAction <T>(this, item));
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        ///     Adds the given key and value as a transition from this node to the given node.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void AddTransition(TKey key, StateNode <TKey, T> value)
        {
            //add a "from" transition so that the value knows
            //that we lead to it.

            if (!value.toTransitions.Contains(this))
            {
                value.toTransitions.Add(this);
            }

            fromTransitions.Add(key, value);
        }
Пример #3
0
        /// <summary>
        ///     Determines if the given node is contained by this node.
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        /// <summary>
        ///     Returns whether a node is contained by this node(and linked "from" nodes).
        /// </summary>
        /// <param name="comparer">The predicate used to determine if a node is contained.</param>
        /// <returns></returns>
        /// <summary>
        ///     Gets the depth first traversal of the children of this node.
        /// </summary>
        /// <exception cref="System.StackOverflowException" />
        /// <returns></returns>
        public IEnumerable <StateNode <TKey, T> > GetDepthFirstTraversal()
        {
            var stack     = new Stack <StateNode <TKey, T> >();
            var traversal = new Stack <StateNode <TKey, T> >();

            traversal.Push(this);
            stack.Push(this);
            while (stack.Count != 0)
            {
                StateNode <TKey, T> node = stack.Pop();
                foreach (KeyValuePair <TKey, StateNode <TKey, T> > transition in node.FromTransitions)
                {
                    stack.Push(transition.Value);
                    traversal.Push(transition.Value);
                }
            }
            return(traversal);
        }
Пример #4
0
 /// <summary>
 ///     Returns whether a node is contained by this node(and linked "from" nodes).
 /// </summary>
 /// <param name="comparer"></param>
 /// <param name="currentLoop"></param>
 /// <param name="maxLoop"></param>
 /// <returns></returns>
 /// <summary>
 ///     Returns whether the given node is contained in a "from" transition.
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 public bool ContainsFromTransition(StateNode <TKey, T> node)
 {
     return(GetBreadthFirstTraversal().Any(a => a == node));
 }
Пример #5
0
 /// <summary>
 ///     Determines if the graph contains the given node.
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 public bool Contains(StateNode <TKey, T> node)
 {
     return(Root.ContainsFromTransition(node));
 }
Пример #6
0
 /// <summary>
 ///     Creates a new StateGraph with the given rootNode as the Root.
 /// </summary>
 /// <param name="rootNode"></param>
 public StateGraph(StateNode <TKey, T> rootNode)
 {
     Root = rootNode;
 }