Beispiel #1
0
        public static Node Parse(GrammarDefinition grammar, string source)
        {
            FullLalrState lalrState = new FullLalrState();

            lalrState.StateStack.Add(grammar.Table[0]); //push state 0
            foreach (var tk in Lexer.Lex(grammar, source))
            {
                var currentSymbol = new TerminalSymbol(tk.Name);
DontConsumeToken:
                {
                    var currentState = lalrState.StateStack[lalrState.StateStack.Count - 1];

                    if (!currentState.ContainsKey(currentSymbol))
                    {
                        throw new GrammarException(tk.Location, $"token inesperado {tk.Source}");
                    }

                    var action = currentState[currentSymbol].First();
                    if (action is LalrShift)
                    {
                        var s = action as LalrShift;
                        lalrState.NodeStack.Add(Node.FromToken(tk));
                        lalrState.StateStack.Add(s.State);
                    }
                    else if (action is LalrReduce)
                    {
                        var prod = ((LalrReduce)action).Production;
                        Reduce(grammar, prod, lalrState);
                        currentState = lalrState.StateStack[lalrState.StateStack.Count - 1];
                        lalrState.StateStack.Add(((LalrGoto)currentState[prod.Head].First()).State);
                        goto DontConsumeToken;
                    }
                    else
                    {
                        //accept
                        SetParent(lalrState.NodeStack.First(), null);
                        return(lalrState.NodeStack.First());
                    }
                }
            }

            //should never get here
            throw new InvalidOperationException();
        }
Beispiel #2
0
        private static void Reduce(GrammarDefinition definition, GrammarProduction production, FullLalrState lalrState)
        {
            List <Node> toBeReduced = new List <Node>();

            for (int i = 0; i < production.Body.Count; i++)
            {
                toBeReduced.Add(lalrState.NodeStack[lalrState.NodeStack.Count - 1]);
                lalrState.NodeStack.RemoveAt(lalrState.NodeStack.Count - 1);
                lalrState.StateStack.RemoveAt(lalrState.StateStack.Count - 1);
            }

            toBeReduced.Reverse();
            lalrState.NodeStack.Add(Node.FromNodes(definition.ProductionNames[production], production, toBeReduced));
        }