Пример #1
0
        /// <summary>Adds an new LRAction to this table.</summary>
        /// <param name="p_symbol">The Symbol.</param>
        /// <param name="p_action">The Action.</param>
        /// <param name="p_value">The value.</param>
        public void AddItem(Symbol p_symbol, Action p_action, int p_value)
        {
            LRAction item = new LRAction();

            item.Symbol = p_symbol;
            item.Action = p_action;
            item.Value  = p_value;
            m_members.Add(item);
        }
Пример #2
0
        /// <summary>Produces a reduction.</summary>
        /// <remarks>Removes as many tokens as members in the rule and pushes a
        ///          non-terminal token.</remarks>
        private ParseResult Reduce(Rule p_rule)
        {
            ParseResult result;
            Token       head;

            if (m_trimReductions && p_rule.ContainsOneNonTerminal)
            {
                // The current rule only consists of a single nonterminal and can be trimmed from the
                // parse tree. Usually we create a new Reduction, assign it to the Data property
                // of Head and push it on the stack. However, in this case, the Data property of the
                // Head will be assigned the Data property of the reduced token (i.e. the only one
                // on the stack). In this case, to save code, the value popped of the stack is changed
                // into the head.
                head = m_tempStack.PopToken();
                head.SetParent(p_rule.RuleNonTerminal);

                result = ParseResult.ReduceEliminated;
            }
            else
            {
                Reduction reduction = new Reduction();
                reduction.ParentRule = p_rule;

                m_tempStack.PopTokensInto(reduction, p_rule.SymbolCount);

                head      = new Token();
                head.Data = reduction;
                head.SetParent(p_rule.RuleNonTerminal);

                m_haveReduction = true;
                result          = ParseResult.ReduceNormal;
            }

            int      index  = m_tempStack.PeekToken().State;
            LRAction action = m_LalrTables[index].GetActionForSymbol(p_rule.RuleNonTerminal.TableIndex);

            if (action != null)
            {
                head.State = m_LalrState = action.Value;;
                m_tempStack.PushToken(head);
            }
            else
            {
                throw new ParserException("Action for LALR state is null");
            }

            return(result);
        }
Пример #3
0
        /// This function analyzes a token and either:
        ///   1. Makes a SINGLE reduction and pushes a complete Reduction object on the stack
        ///   2. Accepts the token and shifts
        ///   3. Errors and places the expected symbol indexes in the Tokens list
        /// The Token is assumed to be valid and WILL be checked
        private ParseResult ParseToken(Token p_token)
        {
            ParseResult   result = ParseResult.InternalError;
            LRActionTable table  = m_LalrTables[m_LalrState];
            LRAction      action = table.GetActionForSymbol(p_token.TableIndex);

            if (action != null)
            {
                m_haveReduction = false;
                m_outputTokens.Clear();

                switch (action.Action)
                {
                case Action.Accept:
                    m_haveReduction = true;
                    result          = ParseResult.Accept;
                    break;

                case Action.Shift:
                    p_token.State = m_LalrState = action.Value;
                    m_tempStack.PushToken(p_token);
                    result = ParseResult.Shift;
                    break;

                case Action.Reduce:
                    result = Reduce(m_rules[action.Value]);
                    break;
                }
            }
            else
            {
                // syntax error - fill expected tokens.
                m_outputTokens.Clear();
                foreach (LRAction a in table.Members)
                {
                    SymbolType kind = a.Symbol.Kind;

                    if (kind == SymbolType.Terminal || kind == SymbolType.End)
                    {
                        m_outputTokens.PushToken(new Token(a.Symbol));
                    }
                }
                result = ParseResult.SyntaxError;
            }

            return(result);
        }