Esempio n. 1
0
        /// <summary>
        /// Gets array of expected currentToken symbols.
        /// </summary>
        public ReadOnlyCollection <Symbol> GetExpectedTokens()
        {
            List <Symbol> expectedTokens = new List <Symbol>(currentState.ActionCount);

#warning Do we need to recurse somehow on non-terminals?
            for (int i = 0; i < currentState.ActionCount; i++)
            {
                switch (currentState.GetAction(i).Symbol.Kind)
                {
                case SymbolKind.Terminal:
                case SymbolKind.End:
                    expectedTokens.Add(currentState.GetAction(i).Symbol);
                    break;
                }
            }
            return(expectedTokens.AsReadOnly());
        }
            private TokenParseResult ParseToken(Token nextToken)
            {
                LalrStateAction stateAction = m_currentLalrState.GetActionBySymbolIndex(nextToken.Symbol.Index);

                m_tokens.Clear();

                if (stateAction != null)
                {
                    //Work - shift or reduce
                    m_haveReduction = false;                     //Will be set true if a reduction is made
                    switch (stateAction.Action)
                    {
                    case LalrAction.Accept:
                        m_haveReduction = true;
                        return(TokenParseResult.Accept);

                    case LalrAction.Shift:
                        m_currentLalrState  = Grammar.LalrStateTable[stateAction.Value];
                        nextToken.LalrState = m_currentLalrState;
                        m_stack.Push(nextToken);
                        return(TokenParseResult.Shift);

                    case LalrAction.Reduce:
                        //Produce a reduction - remove as many tokens as members in the rule & push a nonterminal token
                        int  ruleIndex   = stateAction.Value;
                        Rule currentRule = Grammar.RuleTable[ruleIndex];

                        //======== Create Reduction
                        Token            head;
                        TokenParseResult parseResult;
                        if (TrimReductions && currentRule.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_stack.PopToken();
                            head.Symbol = currentRule.NonTerminal;
                            parseResult = TokenParseResult.ReduceEliminated;
                        }
                        else
                        {
                            //Build a Reduction
                            m_haveReduction = true;
                            Reduction reduction = new Reduction(currentRule);
                            for (int i = 0; i < currentRule.Count; i++)
                            {
                                reduction.InsertToken(0, m_stack.PopToken());
                            }
                            head        = new Token(currentRule.NonTerminal, reduction);
                            parseResult = TokenParseResult.ReduceNormal;
                        }

                        //========== Goto
                        LalrState nextState = m_stack.PeekToken().LalrState;

                        //========= If nextAction is null here, then we have an Internal Table Error!!!!
                        LalrStateAction nextAction = nextState.GetActionBySymbolIndex(currentRule.NonTerminal.Index);
                        if (nextAction != null)
                        {
                            m_currentLalrState = Grammar.LalrStateTable[nextAction.Value];
                            head.LalrState     = m_currentLalrState;
                            m_stack.Push(head);
                            return(parseResult);
                        }
                        else
                        {
                            return(TokenParseResult.InternalError);
                        }
                    }
                }
                else
                {
                    //=== Syntax Error! Fill Expected Tokens
                    for (int i = 0; i < m_currentLalrState.ActionCount; i++)
                    {
                        switch (m_currentLalrState.GetAction(i).Symbol.SymbolType)
                        {
                        case SymbolType.Terminal:
                        case SymbolType.End:
                            Token token = new Token(m_currentLalrState.GetAction(i).Symbol, "", m_tokenReader.LineNumber);
                            m_tokens.Push(token);
                            break;
                        }
                    }
                }

                return(TokenParseResult.SyntaxError);
            }