Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        /// <summary>Executes a parse-action.</summary>
        /// <remarks>When this method is called, the parsing engine
        /// reads information from the source text and then reports what action was taken.
        /// This ranges from a token being read and recognized from the source, a parse
        /// reduction, or some type of error.</remarks>
        public ParseMessage Parse()
        {
            while (true)
            {
                if (m_inputTokens.Count == 0)
                {
                    // we must read a token.

                    Token token = RetrieveToken();

                    if (token == null)
                    {
                        throw new ParserException("RetrieveToken returned null");
                    }

                    if (token.Kind != SymbolType.Whitespace)
                    {
                        m_inputTokens.PushToken(token);

                        if (m_commentLevel == 0 && !CommentToken(token))
                        {
                            return(ParseMessage.TokenRead);
                        }
                    }
                }
                else if (m_commentLevel > 0)
                {
                    // we are in a block comment.

                    Token token = m_inputTokens.PopToken();

                    switch (token.Kind)
                    {
                    case SymbolType.CommentStart:
                        m_commentLevel++;
                        break;

                    case SymbolType.CommentEnd:
                        m_commentLevel--;
                        break;

                    case SymbolType.End:
                        return(ParseMessage.CommentError);
                    }
                }
                else
                {
                    // we are ready to parse.

                    Token token = m_inputTokens.PeekToken();
                    switch (token.Kind)
                    {
                    case SymbolType.CommentStart:
                        m_inputTokens.PopToken();
                        m_commentLevel++;
                        break;

                    case SymbolType.CommentLine:
                        m_inputTokens.PopToken();
                        DiscardLine();
                        break;

                    default:
                        ParseResult result = ParseToken(token);
                        switch (result)
                        {
                        case ParseResult.Accept:
                            return(ParseMessage.Accept);

                        case ParseResult.InternalError:
                            return(ParseMessage.InternalError);

                        case ParseResult.ReduceNormal:
                            return(ParseMessage.Reduction);

                        case ParseResult.Shift:
                            m_inputTokens.PopToken();
                            break;

                        case ParseResult.SyntaxError:
                            return(ParseMessage.SyntaxError);
                        }
                        break;
                    }     // switch
                }         // else
            }             // while
        }