public T Reduce <T>(T aggregator, ReduceAction <T> action)
        {
            T result = aggregator;

            foreach (WikiPageSection section in Subsections)
            {
                result = action(section, result);
            }
            return(result);
        }
Exemple #2
0
        private void DoReduce(Token token, ReduceAction action)
        {
            int reduceLength = action.Rule.Rhs.Length;

            State currentState;
            // Do not reduce if the rule is single nonterminal and TrimReductions is on
            bool skipReduce = ((TrimReductions) && (reduceLength == 1) && (action.Rule.Rhs[0] is SymbolNonterminal));

            if (skipReduce)
            {
                stateStack.Pop();
                currentState = stateStack.Peek();
            }
            else
            {
                Token[] tokens = new Token[reduceLength];
                for (int i = 0; i < reduceLength; i++)
                {
                    stateStack.Pop();
                    tokens[reduceLength - i - 1] = tokenStack.Pop();
                }
                NonterminalToken nttoken;
                if (reduceLength == 0)
                {
                    nttoken = new NonterminalToken(action.Rule, tokens, token.Location);
                }
                else
                {
                    nttoken = new NonterminalToken(action.Rule, tokens, tokens[reduceLength - 1].Location);
                }

                tokenStack.Push(nttoken);
                currentState = stateStack.Peek();

                if (OnReduce != null)
                {
                    ReduceEventArgs args = new ReduceEventArgs(action.Rule, nttoken, currentState);
                    OnReduce(this, args);
                    DoReleaseTokens(args.Token);

                    continueParsing = args.Continue;
                }
            }
            Action gotoAction = currentState.Actions.Get(action.Rule.Lhs);

            if (gotoAction is GotoAction)
            {
                DoGoto(token, (GotoAction)gotoAction);
            }
            else
            {
                throw new ParserException("Invalid action table in state");
            }
        }
        private void DoReduce(Token token, ReduceAction action)
        {
            int reduceLength = action.Rule.Rhs.Length;

            State currentState;
            bool  skipReduce = ((TrimReductions) &&
                                (reduceLength == 1) && (action.Rule.Rhs[0] is SymbolNonterminal));

            if (skipReduce)
            {
                stateStack.Pop();
                currentState = stateStack.Peek();
            }
            else
            {
                Token[] tokens = new Token[reduceLength];
                for (int i = 0; i < reduceLength; i++)
                {
                    stateStack.Pop();
                    tokens[reduceLength - i - 1] = tokenStack.Pop();
                }
                NonterminalToken nttoken = new NonterminalToken(action.Rule, tokens);
                tokenStack.Push(nttoken);
                currentState = stateStack.Peek();

                if (OnReduce != null)
                {
                    ReduceEventArgs args = new ReduceEventArgs(action.Rule,
                                                               nttoken,
                                                               currentState);
                    OnReduce(this, args);
                    DoReleaseTokens(args.Token);

                    continueParsing = args.Continue;
                }
            }
            lalr.Action gotoAction = currentState.Actions.Get(action.Rule.Lhs);

            if (gotoAction is GotoAction)
            {
                DoGoto(token, (GotoAction)gotoAction);
            }
            else
            {
                throw new ParserException("Tabla de acciones inválida en el estado");
            }
        }
Exemple #4
0
 public PureProduction(string name, int elemCount, ReduceAction action)
 {
     Name      = name;
     ElemCount = elemCount;
     Action    = action;
 }
Exemple #5
0
        private void SetAction(ParserState state, ProductionEntry key, ParserAction newAction)
        {
            if (key is NonTerminal nt)
            {
                Console.WriteLine();
            }

            if (state.Action.ContainsKey(key.ID))
            {
                var oldAction = state.Action[key.ID];
                if (oldAction.ToString() == newAction.ToString())
                {
                    return;
                }

                if (!(oldAction is AcceptAction) && !(newAction is AcceptAction))
                {
                    if (oldAction.Name != newAction.Name)
                    {
                        //Shift/Reduce Conflict
                        ShiftAction  shiftAction  = (oldAction.Name == "shift" ? oldAction : newAction) as ShiftAction;
                        ReduceAction reduceAction = (oldAction.Name == "shift" ? newAction : oldAction) as ReduceAction;

                        var prod = reduceAction.Production;
                        var term = key as Terminal;

                        //Resolve based on precedence and associativity
                        if (prod.Precendece > term.Precedence ||
                            (prod.Precendece == term.Precedence && prod.Associatvity == OperatorAssociativity.Left))
                        {
                            state.Action[key.ID] = reduceAction;
                        }
                        else
                        {
                            state.Action[key.ID] = shiftAction;
                        }

                        return;
                    }
                    else if (newAction is ReduceAction)
                    {
                        //Reduce/Reduce conflict
                        var newProd = (newAction as ReduceAction).Production;
                        var oldProd = (oldAction as ReduceAction).Production;

                        bool newFirst = false;

                        if (newProd.Lhs != oldProd.Lhs)
                        {
                            //Find the NonTerminal to appear first
                            newFirst = newProd.Lhs.ID < oldProd.Lhs.ID;
                        }
                        else
                        {
                            //Find the production to appear first
                            foreach (var p in newProd.Lhs.Productions)
                            {
                                if (p != newProd && p != oldProd)
                                {
                                    continue;
                                }
                                if (p == newProd)
                                {
                                    newFirst = true;
                                }
                                break;
                            }
                        }

                        //Resolve based on first appearance
                        if (newFirst)
                        {
                            state.Action[key.ID] = newAction;
                        }

                        return;
                    }
                    else
                    {
                        throw new Exception($"Conflict in state {state} on entry {key}. Cannot resolve shift/shift conflict.");
                    }
                }
            }

            state.Action[key.ID] = newAction;
        }