/// <summary>
            /// Read LALR state information.
            /// </summary>
            private void ReadLalrStates()
            {
                int index = ReadInt16Entry();

                ReadEmptyEntry();
                LalrStateAction[] stateTable = new LalrStateAction[m_entryCount / 4];
                for (int i = 0; i < stateTable.Length; i++)
                {
                    Symbol     symbol      = m_symbolTable[ReadInt16Entry()];
                    LalrAction action      = (LalrAction)ReadInt16Entry();
                    int        targetIndex = ReadInt16Entry();
                    ReadEmptyEntry();
                    stateTable[i] = new LalrStateAction(i, symbol, action, targetIndex);
                }

                // Create the transition vector
                LalrStateAction[] transitionVector = new LalrStateAction[m_symbolTable.Length];
                for (int i = 0; i < transitionVector.Length; i++)
                {
                    transitionVector[i] = null;
                }
                for (int i = 0; i < stateTable.Length; i++)
                {
                    transitionVector[stateTable[i].Symbol.Index] = stateTable[i];
                }

                LalrState lalrState = new LalrState(index, stateTable, transitionVector);

                m_lalrStateTable[index] = lalrState;
            }
            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);
            }