Beispiel #1
0
        public void AddKeyEvent(KeyTable table, UnityAction action)
        {
            if (!actionTable.ContainsKey(table))
            {
                actionTable.Add(table, new List <UnityAction>());
            }

            actionTable[table].Add(action);
        }
Beispiel #2
0
 /// <summary>
 ///     Adds a shift command to the action table at the position between the given element and given currentState, with the
 ///     given actions as the values.
 /// </summary>
 /// <param name="element"></param>
 /// <param name="currentState"></param>
 /// <param name="actions"></param>
 private void addAction(Terminal <T> element, int currentState, params ParserAction <T>[] actions)
 {
     //if the column already exists
     if (ActionTable.ContainsKey(currentState, element))
     {
         //add the actions
         ActionTable[currentState, element].AddRange(actions);
     }
     //otherwise, create new
     else
     {
         ActionTable.Add(currentState, element, actions.ToList());
     }
 }
Beispiel #3
0
        /// <summary>
        ///     Gets the action(s) given the current state and the next input.
        /// </summary>
        /// <param name="state"></param>
        /// <param name="nextInput"></param>
        /// <exception cref="System.ArgumentNullException" />
        /// <returns>
        ///     A array of ShiftActions if the operation is to move, ReduceActions if the operation is to Reduce, or AcceptActions
        ///     if the parse is valid.
        ///     Returns null if the action does not exist.
        /// </returns>
        public ParserAction <T>[] this[int currentState, GrammarElement <T> nextInput]
        {
            get
            {
                if (nextInput == null)
                {
                    throw new ArgumentNullException("nextInput");
                }

                if (nextInput is Terminal <T> )
                {
                    //if the given state is in the table
                    if (ActionTable.ContainsKey(currentState))
                    {
                        var actions = new List <ParserAction <T> >();
                        //if the next input is in the table
                        if (ActionTable[currentState].ContainsKey((Terminal <T>)nextInput))
                        {
                            Terminal <T> key = ActionTable[currentState].GetKey((Terminal <T>)nextInput);

                            //if the stored column is not negated
                            if (!key.Negated)
                            {
                                //return the action
                                actions.AddRange(ActionTable[currentState][key].ToArray());
                            }
                        }
                        //Negated values will never match the end of input element
                        if (!((Terminal <T>)nextInput).EndOfInput)
                        {
                            //Negated values act as an 'and' clause instead of an 'or' clause
                            //input is not 'a' and input is not 'b', instead of input is not 'a' or input is not 'b'

                            //If all of the negated keys do not equal the next input.
                            if (ActionTable[currentState].All(a => (a.Key.Negated && !a.Key.Equals(nextInput)) || !a.Key.Negated))
                            {
                                //if the state is contained in the table, and if there is a negated input element that does not match the given input
                                //A Terminal with a null value that is negated will match anything except END_OF_INPUT.
                                KeyValuePair <Terminal <T>, List <ParserAction <T> > > result = ActionTable[currentState].FirstOrDefault(a => a.Key.Negated && !a.Key.Equals(nextInput));
                                if (!result.Equals(default(KeyValuePair <Terminal <T>, List <ParserAction <T> > >)))
                                {
                                    actions.AddRange(result.Value.ToArray());
                                }
                            }
                        }
                        return(actions.ToArray());
                    }
                }
                else
                {
                    //if the given state and next input are in the table
                    if (GotoTable.ContainsKey(currentState) &&
                        GotoTable[currentState].ContainsKey((NonTerminal <T>)nextInput))
                    {
                        //return a new shift action representing the goto movement.
                        return(new[] { new ShiftAction <T>(this, GotoTable[currentState, (NonTerminal <T>)nextInput].Value) });
                    }
                }

                //the item does not exist in the table, return null.
                return(null);
            }
        }