コード例 #1
0
        private bool DoReduction(Stack <Token> tokenStack, LookAheadBuffer lookAheadBuffer, ref ushort lalrState, LRAction parseAction)
        {
            Token head = null;
            //Produce a reduction - remove as many tokens as members in the rule & push a nonterminal token
            Production prod             = egtDataManager.GetProduction(parseAction.Value);
            bool       reductionSkipped = false;

            //Skip reduction?
            if ((TrimReductions && prod.ConsistsOfOneNonTerminal()) ||
                (SkipEmptyProductions && prod.Handle.Count == 0))
            {
                head             = tokenStack.Pop();
                head.Symbol      = prod.Head;
                reductionSkipped = true;
            }
            //Build a Reduction
            else
            {
                Reduction reduction = new Reduction(prod.Handle.Count, prod);

                //If a production has no handles, it has no location.
                //Set a would-be location instead.
                if (prod.Handle.Count == 0)
                {
                    reduction.StartPosition = reduction.EndPosition = lookAheadBuffer.Position;
                }
                else
                {
                    for (int i = prod.Handle.Count - 1; i >= 0; i--)
                    {
                        reduction[i] = tokenStack.Pop();
                    }
                }

                head = reduction;
            }

            //If n is -1 here, then we have an Internal Table Error!!!
            LRAction action = egtDataManager.GetLRActionList(tokenStack.Peek().State)[prod.Head];

            if (action == null)
            {
                OnInternalError();
                return(false);
            }

            lalrState = action.Value;

            head.State = lalrState;
            tokenStack.Push(head);

            if (!reductionSkipped)
            {
                OnReduction((Reduction)tokenStack.Peek());
            }
            return(true);
        }
コード例 #2
0
        // 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.
        private ParseResult ParseLALR(ref Token token)
        {
            LRAction    parseAction = lrStates[currentLALR][token.Parent];
            ParseResult parseResult = 0;

            if (parseAction != null)
            {
                haveReduction = false;
                switch (parseAction.Type)
                {
                case LRActionType.Shift:
                    currentLALR = parseAction.Value;
                    token.State = (short)currentLALR;
                    stack.Push(token);
                    parseResult = ParseResult.Shift;
                    break;

                case LRActionType.Reduce:
                    Production production = ProductionTable[parseAction.Value];
                    Token      head;

                    // 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.
                    if (TrimReductions && production.ContainsOneNonTerminal())
                    {
                        head        = stack.Pop();
                        head.Parent = production.Head;
                        parseResult = ParseResult.ReduceEliminated;
                    }
                    else
                    {
                        haveReduction = true;
                        Reduction newReduction = new Reduction(production.Handle.Count())
                        {
                            Parent = production
                        };
                        short n = (short)(production.Handle.Count() - 1);
                        while (n >= 0)
                        {
                            newReduction[n] = stack.Pop();
                            n--;
                        }
                        head        = new Token(production.Head, newReduction);
                        parseResult = ParseResult.ReduceNormal;
                    }

                    short index = stack.Peek().State;
                    short n2    = lrStates[index].IndexOf(production.Head);
                    if (n2 != -1)
                    {
                        currentLALR = lrStates[index][n2].Value;
                        head.State  = (short)currentLALR;
                        stack.Push(head);
                        break;
                    }
                    parseResult = ParseResult.InternalError;
                    break;

                case LRActionType.Accept:
                    haveReduction = true;
                    parseResult   = ParseResult.Accept;
                    break;
                }
            }
            else
            {
                ExpectedSymbols.Clear();
                foreach (LRAction LRAction in lrStates[currentLALR])
                {
                    switch (LRAction.Symbol.Type)
                    {
                    case SymbolType.Content:
                    case SymbolType.End:
                    case SymbolType.GroupStart:
                    case SymbolType.GroupEnd:
                        ExpectedSymbols.Add(LRAction.Symbol);
                        break;
                    }
                }
                parseResult = ParseResult.SyntaxError;
            }
            return(parseResult);
        }
コード例 #3
0
        private bool DoReduction(Stack<Token> tokenStack, LookAheadBuffer lookAheadBuffer, ref ushort lalrState, LRAction parseAction)
        {
            Token head = null;
            //Produce a reduction - remove as many tokens as members in the rule & push a nonterminal token
            Production prod = egtDataManager.GetProduction(parseAction.Value);
            bool reductionSkipped = false;

            //Skip reduction?
            if ((TrimReductions && prod.ConsistsOfOneNonTerminal())
                || (SkipEmptyProductions && prod.Handle.Count == 0))
            {
                head = tokenStack.Pop();
                head.Symbol = prod.Head;
                reductionSkipped = true;
            }
            //Build a Reduction
            else
            {
                Reduction reduction = new Reduction(prod.Handle.Count, prod);

                //If a production has no handles, it has no location.
                //Set a would-be location instead.
                if (prod.Handle.Count == 0)
                {
                    reduction.StartPosition = reduction.EndPosition = lookAheadBuffer.Position;
                }
                else
                {
                    for (int i = prod.Handle.Count - 1; i >= 0; i--)
                    {
                        reduction[i] = tokenStack.Pop();
                    }
                }

                head = reduction;
            }

            //If n is -1 here, then we have an Internal Table Error!!!
            LRAction action = egtDataManager.GetLRActionList(tokenStack.Peek().State)[prod.Head];
            if (action == null)
            {
                OnInternalError();
                return false;
            }

            lalrState = action.Value;

            head.State = lalrState;
            tokenStack.Push(head);

            if (!reductionSkipped)
            {
                OnReduction((Reduction)tokenStack.Peek());
            }
            return true;
        }
コード例 #4
0
 internal void Add(LRAction action)
 {
     actionList.Add(action);
 }
コード例 #5
0
        public bool Parse(TextReader reader)
        {
            if (egtDataManager == null)
            {
                OnNotLoadedError();
                return(false);
            }

            TokenQueueStack inputTokens = new TokenQueueStack();
            Stack <Token>   tokenStack  = new Stack <Token>();

            tokenStack.Push(new Token());
            Stack <Token>   groupStack      = new Stack <Token>();
            LookAheadBuffer lookAheadBuffer = new LookAheadBuffer(reader);
            ushort          lalrState       = 0;

            while (true)
            {
                if (inputTokens.Count == 0)
                {
                    inputTokens.Push(ProduceToken(groupStack, lookAheadBuffer));
                    OnTokenRead(inputTokens.Peek());
                }
                //Runaway group
                else if (groupStack.Count != 0)
                {
                    OnGroupError();
                    return(false); //Error; abort
                }
                else
                {
                    Token read = inputTokens.Peek();

                    switch (read.Type)
                    {
                    case SymbolType.Noise:
                        inputTokens.Pop();
                        break;

                    case SymbolType.Error:
                        OnLexicalError(read.EndPosition, read.Data);
                        return(false);    //Error; abort

                    default:
                        LRActionList actionList  = egtDataManager.GetLRActionList(lalrState);
                        LRAction     parseAction = actionList[read.Symbol];
                        if (parseAction == null)
                        {
                            HandleSyntaxError(actionList, read);
                            return(false);
                        }

                        switch (parseAction.Type)
                        {
                        case LRActionType.Accept:
                            OnCompleted(tokenStack.Peek().Tag);
                            return(true);

                        case LRActionType.Shift:
                            lalrState  = parseAction.Value;
                            read.State = lalrState;
                            tokenStack.Push(read);
                            //It now exists on the Token-Stack and must be eliminated from the queue.
                            inputTokens.Dequeue();
                            break;

                        case LRActionType.Reduce:
                            if (!DoReduction(tokenStack, lookAheadBuffer, ref lalrState, parseAction))
                            {
                                return(false);
                            }
                            break;
                        }
                        break;
                    }
                }
            }
        }
コード例 #6
0
 internal void Add(LRAction action)
 {
     actionList.Add(action);
 }