Example #1
0
        // BorderIndex = 0 - begin border
        // BorderIndex = 1 - end border
        public Token GetBorderToken(int BorderIndex = 0, bool IncludeNoise = false)
        {
            Reduction DataReduction = (Reduction)Data;
            int       TokenCount    = DataReduction.TokenCount;
            Token     TokenCandidate;

            for (int Counter = 1; Counter <= TokenCount; Counter++)
            {
                if (BorderIndex == 1)
                {
                    TokenCandidate = (Token)DataReduction.Tokens(TokenCount - Counter);
                }
                else
                {
                    TokenCandidate = (Token)DataReduction.Tokens(Counter - 1);
                }
                if (TokenCandidate.Type == SymbolType.Terminal)
                {
                    if (IncludeNoise && BorderIndex == 1 && TokenCandidate.EndNoise != null)
                    {
                        return(TokenCandidate.EndNoise);
                    }
                    else if (IncludeNoise && BorderIndex == 0 && TokenCandidate.BeginNoise != null)
                    {
                        return(TokenCandidate.BeginNoise);
                    }
                    else
                    {
                        return(TokenCandidate);
                    }
                }
                else //if (TokenCandidate.Type == SymbolType.Nonterminal)
                {
                    if (((Reduction)TokenCandidate.Data).TokenCount > 0)
                    {
                        Token TokenFromBottom = TokenCandidate.GetBorderToken(BorderIndex, IncludeNoise);
                        if (TokenFromBottom != null)
                        {
                            return(TokenFromBottom);
                        }
                    }
                }
            }
            return(null);
        }
Example #2
0
        /// <summary>
        ///     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
        ///     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.
        /// </summary>
        /// <param name="nextToken"></param>
        /// <returns></returns>
        private ParseResult ParseLALR(Token nextToken)
        {
            ParseResult result      = default(ParseResult);
            LRAction    parseAction = _lrStates[_currentLALR][(nextToken.Parent)];

            // Work - shift or reduce
            if ((parseAction != null))
            {
                _haveReduction = false;
                //Will be set true if a reduction is made
                //'Debug.WriteLine("Action: " & ParseAction.Text)

                switch (parseAction.Type)
                {
                case LRActionType.Accept:
                    _haveReduction = true;
                    result         = ParseResult.Accept;

                    break;

                case LRActionType.Shift:
                    _currentLALR    = parseAction.Value;
                    nextToken.State = (short)_currentLALR;
                    _stack.Push(nextToken);
                    result = ParseResult.Shift;

                    break;

                case LRActionType.Reduce:
                    //Produce a reduction - remove as many tokens as members in the rule & push a nonterminal token
                    Production prod = _productionTable[parseAction.Value];

                    //======== Create Reduction
                    Token head;
                    int   n;
                    if (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 _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        = _stack.Pop();
                        head.Parent = prod.RuleNonterminal;

                        result = ParseResult.ReduceEliminated;
                        //Build a Reduction
                    }
                    else
                    {
                        _haveReduction = true;
                        var newReduction = new Reduction(prod.Handle.Count);

                        newReduction.ParentRule = prod;
                        for (n = prod.Handle.Count - 1; n >= 0; n += -1)
                        {
                            newReduction[n] = _stack.Pop();
                        }

                        head = new Token(prod.RuleNonterminal, newReduction);
                        //bool IsFirst;
                        //if (_stack.Count == 0)
                        //{
                        //    IsFirst = true;
                        //}
                        //else
                        //{
                        //    IsFirst = false;
                        //}
                        //newReduction.EndNoise = _lastNoise;
                        result = ParseResult.ReduceNormal;
                    }

                    //========== Goto
                    short index = _stack.Peek().State;

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

                        head.State = (short)_currentLALR;
                        _stack.Push(head);
                    }
                    else
                    {
                        result = ParseResult.InternalError;
                    }
                    break;
                }
            }
            else
            {
                //=== Syntax Error! Fill Expected Tokens
                _expectedSymbols.Clear();
                //.Count - 1
                foreach (LRAction action in _lrStates[_currentLALR])
                {
                    switch (action.Symbol.Type)
                    {
                    case SymbolType.Terminal:
                    case SymbolType.End:
                    case SymbolType.GroupStart:
                    case SymbolType.GroupEnd:
                        _expectedSymbols.Add(action.Symbol);
                        break;
                    }
                }
                result = ParseResult.SyntaxError;
            }

            return(result);
        }