Example #1
0
 internal int Add(Token item)
 {
     return this.m_Array.Add(item);
 }
Example #2
0
        private ParseResult ParseLALR(ref Token nextToken)
        {
            // This function analyzes a token and either:
            // 1. Makes a SINGLE reduction and pushes a complete Reduction object on the m_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
            // If an action is performed that requires controlt to be returned to the user, the function returns true.
            // The Message parameter is then set to the type of action.
            var result = default(ParseResult);
            var parseAction = this.m_LRStates[this.m_CurrentLALR][nextToken.Parent];

            // Work - shift or reduce
            if (parseAction != null)
            {
                this.m_HaveReduction = false;

                // Will be set true if a reduction is made
                // 'Debug.WriteLine("Action: " & ParseAction.Text)
                switch (parseAction.Type)
                {
                    case LRActionType.Accept:
                        this.m_HaveReduction = true;
                        result = ParseResult.Accept;

                        break;
                    case LRActionType.Shift:
                        this.m_CurrentLALR = parseAction.Value;
                        nextToken.State = (short)this.m_CurrentLALR;
                        this.m_Stack.Push(ref nextToken);
                        result = ParseResult.Shift;

                        break;
                    case LRActionType.Reduce:

                        // Produce a reduction - remove as many tokens as members in the rule & push a nonterminal token
                        var prod = this.m_ProductionTable[parseAction.Value];

                        // ======== Create Reduction
                        Token head;
                        short n;
                        if (this.m_TrimReductions && prod.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 m_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 m_Stack).
                            // In this case, to save code, the value popped of the m_Stack is changed into the head.
                            head = this.m_Stack.Pop();
                            head.Parent = prod.Head();

                            result = ParseResult.ReduceEliminated;

                            // Build a Reduction
                        }
                        else
                        {
                            this.m_HaveReduction = true;
                            var newReduction = new Reduction(prod.Handle().Count());

                            var with2 = newReduction;
                            with2.Parent = prod;
                            for (n = (short)(prod.Handle().Count() - 1); n >= 0; n += -1)
                            {
                                with2[n] = this.m_Stack.Pop();
                            }

                            head = new Token(prod.Head(), newReduction);
                            result = ParseResult.ReduceNormal;
                        }

                        // ========== Goto
                        var index = this.m_Stack.Top().State;

                        // ========= If n is -1 here, then we have an Internal Table Error!!!!
                        n = this.m_LRStates[index].IndexOf(prod.Head());
                        if (n != -1)
                        {
                            this.m_CurrentLALR = this.m_LRStates[index][n].Value;

                            head.State = (short)this.m_CurrentLALR;
                            this.m_Stack.Push(ref head);
                        }
                        else
                        {
                            result = ParseResult.InternalError;
                        }

                        break;
                }
            }
            else
            {
                // === Syntax Error! Fill Expected Tokens
                this.m_ExpectedSymbols.Clear();

                // .Count - 1
                foreach (LRAction action in this.m_LRStates[this.m_CurrentLALR])
                {
                    switch (action.Symbol.Type)
                    {
                        case SymbolType.Content:
                        case SymbolType.End:
                        case SymbolType.GroupStart:
                        case SymbolType.GroupEnd:
                            this.m_ExpectedSymbols.Add(action.Symbol);
                            break;
                    }
                }

                result = ParseResult.SyntaxError;
            }

            return result;

            // Very important
        }
Example #3
0
        private Token LookaheadDFA()
        {
            // This function implements the DFA for th parser's lexer.
            // It generates a token which is used by the LALR state
            // machine.
            var target = 0;
            var result = new Token();

            // ===================================================
            // Match DFA token
            // ===================================================
            var done = false;
            int currentDFA = this.m_DFA.InitialState;
            var currentPosition = 1;

            // Next byte in the input Stream
            var lastAcceptState = -1;

            // We have not yet accepted a character string
            var lastAcceptPosition = -1;

            var ch = this.Lookahead(1);

            // NO MORE DATA
            // ReSharper disable once PossibleNullReferenceException
            if (!(string.IsNullOrEmpty(ch) | ch[0] == 65535))
            {
                while (!done)
                {
                    // This code searches all the branches of the current DFA state
                    // for the next character in the input Stream. If found the
                    // target state is returned.
                    ch = this.Lookahead(currentPosition);

                    // End reached, do not match
                    bool found;
                    if (string.IsNullOrEmpty(ch))
                    {
                        found = false;
                    }
                    else
                    {
                        var n = 0;
                        found = false;
                        while (n < this.m_DFA[currentDFA].Edges.Count & !found)
                        {
                            var edge = this.m_DFA[currentDFA].Edges[n];

                            // ==== Look for character in the Character Set Table
                            if (edge.Characters.Contains(ch[0]))
                            {
                                found = true;
                                target = edge.Target;

                                // .TableIndex
                            }

                            n += 1;
                        }
                    }

                    // This block-if statement checks whether an edge was found from the current state. If so, the state and current
                    // position advance. Otherwise it is time to exit the main loop and report the token found (if there was one).
                    // If the LastAcceptState is -1, then we never found a match and the Error Token is created. Otherwise, a new
                    // token is created using the Symbol in the Accept State and all the characters that comprise it.
                    if (found)
                    {
                        // This code checks whether the target state accepts a token.
                        // If so, it sets the appropiate variables so when the
                        // algorithm in done, it can return the proper token and
                        // number of characters.

                        // NOT is very important!
                        if (this.m_DFA[target].Accept != null)
                        {
                            lastAcceptState = target;
                            lastAcceptPosition = currentPosition;
                        }

                        currentDFA = target;
                        currentPosition += 1;

                        // No edge found
                    }
                    else
                    {
                        done = true;

                        // Lexer cannot recognize symbol
                        if (lastAcceptState == -1)
                        {
                            result.Parent = this.m_SymbolTable.GetFirstOfType(SymbolType.Error);
                            result.Data = this.LookaheadBuffer(1);

                            // Create Token, read characters
                        }
                        else
                        {
                            result.Parent = this.m_DFA[lastAcceptState].Accept;
                            result.Data = this.LookaheadBuffer(lastAcceptPosition);

                            // Data contains the total number of accept characters
                        }
                    }

                    // DoEvents
                }
            }
            else
            {
                // End of file reached, create End Token
                result.Data = string.Empty;
                result.Parent = this.m_SymbolTable.GetFirstOfType(SymbolType.End);
            }

            // ===================================================
            // Set the new token's position information
            // ===================================================
            // Notice, this is a copy, not a linking of an instance. We don't want the user
            // to be able to alter the main value indirectly.
            result.Position().Copy(this.m_SysPosition);

            return result;
        }
Example #4
0
 public void PushInput(ref Token theToken)
 {
     this.m_InputTokens.Push(theToken);
 }
Example #5
0
        public bool Open(TextReader reader)
        {
            var start = new Token();

            this.Restart();
            this.m_Source = reader;

            // === Create stack top item. Only needs state
            start.State = this.m_LRStates.InitialState;
            this.m_Stack.Push(ref start);

            return true;
        }
Example #6
0
 public void EnqueueInput(ref Token theToken)
 {
     this.m_InputTokens.Enqueue(ref theToken);
 }