Beispiel #1
0
 /// <summary>
 ///     Performs the given action on the given stack, branches, and current index based on the current item.
 ///     Returns whether the action was to accept.
 /// </summary>
 /// <param name="syntax"></param>
 /// <param name="stateStack"></param>
 /// <param name="currentBranches"></param>
 /// <param name="action"></param>
 /// <param name="currentIndex"></param>
 /// <returns></returns>
 protected bool PerformAction(bool syntax, Terminal <T> currentItem, Stack <KeyValuePair <int, GrammarElement <T> > > stateStack, List <SyntaxNode <T> > currentBranches, ParserAction <T> action, ref int currentIndex)
 {
     if (action is ShiftAction <T> )
     {
         Shift(stateStack, currentItem, action);
         currentIndex++;
     }
     else if (action is ReduceAction <T> )
     {
         Reduce(syntax, stateStack, currentBranches, action, ref currentIndex);
         currentIndex++;
     }
     else if (action is AcceptAction <T> )
     {
         return(true);
     }
     return(false);
 }
Beispiel #2
0
        /// <summary>
        ///     Reduces the given action, reflecting the changes on the given stack, branches, and index.
        /// </summary>
        /// <param name="syntax"></param>
        /// <param name="stateStack"></param>
        /// <param name="currentBranches"></param>
        /// <param name="action"></param>
        protected void Reduce(bool syntax, Stack <KeyValuePair <int, GrammarElement <T> > > stateStack, List <SyntaxNode <T> > currentBranches, ParserAction <T> action, ref int currentIndex)
        {
            if (action is ReduceAction <T> )
            {
                var r = (ReduceAction <T>)action;

                var e = new List <GrammarElement <T> >();

                //pop the number of elements in the RHS of the item
                for (var c = 0; c < r.ReduceItem.ProductionElements.Length; c++)
                {
                    e.Add(stateStack.Pop().Value);
                }
                e.Reverse();

                //create a new branch with the value as the LHS of the reduction item.
                var newBranch = new SyntaxNode <T>(r.ReduceItem.LeftHandSide);


                //Determine whether to add each element to the new branch based on whether it should be kept.
                foreach (GrammarElement <T> element in e)
                {
                    if (element is NonTerminal <T> )
                    {
                        if (element.Keep || syntax)
                        {
                            //find the first branch that matches the reduce element
                            SyntaxNode <T> b = currentBranches.Last(a => a.Value.Equals(element));
                            newBranch.AddChild(b);
                            currentBranches.Remove(b);
                        }
                        else
                        {
                            //find the first branch that matches the reduce element
                            SyntaxNode <T> b = currentBranches.Last(a => a.Value.Equals(element));
                            //get the children of the branch since we don't want the current value
                            IEnumerable <SyntaxNode <T> > branches = b.GetChildren();
                            //add the children
                            newBranch.AddChildren(branches);
                            currentBranches.Remove(b);
                        }
                    }
                    else
                    {
                        //if we should keep the terminal object, then add it to the new branch
                        if (element == null ||
                            element.Keep ||
                            syntax)
                        {
                            newBranch.AddChild(new SyntaxNode <T>(element));
                        }
                    }
                }

                currentBranches.Add(newBranch);

                //push the LHS non-terminal and the next state
                stateStack.Push(new KeyValuePair <int, GrammarElement <T> >(ParseTable.GotoTable[stateStack.Peek().Key, r.ReduceItem.LeftHandSide].Value, r.ReduceItem.LeftHandSide));

                currentIndex--;
            }
        }
Beispiel #3
0
 /// <summary>
 ///     Shifts the given action based on the given item, reflecting the given changes on the given stack.
 /// </summary>
 /// <param name="stateStack"></param>
 /// <param name="item"></param>
 /// <param name="action"></param>
 protected static void Shift(Stack <KeyValuePair <int, GrammarElement <T> > > stateStack, Terminal <T> item, ParserAction <T> action)
 {
     //push the state and item
     stateStack.Push(new KeyValuePair <int, GrammarElement <T> >(((ShiftAction <T>)action).NextState, item));
 }