public LRParsingTableReportSection(LRParsingTable lRParsingTable) : base("LR-Parsing-Table")
        {
            var terminals   = new HashSet <string>();
            var productions = new HashSet <string>()
            {
                "S'"
            };

            foreach (var row in lRParsingTable.Rows)
            {
                foreach (var gt in row.GOTO)
                {
                    productions.Add(gt.Key);
                }
                foreach (var action in row.Actions)
                {
                    terminals.Add(action.Key);
                }
            }

            this.terminals   = terminals.ToArray();
            this.productions = productions.ToArray();
            this.rows        = lRParsingTable.Rows;
        }
Esempio n. 2
0
        public static LRParsingTable From(CLRStateGenerator stateMachine, ProductionTable productionTable)
        {
            var table        = new LRParsingTable(stateMachine.States.Count, productionTable);
            var kernelLookup = new Dictionary <Kernel, int>();
            var ruleLookup   = new Dictionary <Rule, int>();

            // Create rule lookup table
            int ptr = 0;

            foreach (var production in productionTable.Productions)
            {
                foreach (var rule in production.Rules)
                {
                    table.Productions[ptr] = rule;
                    ruleLookup[rule]       = ptr++;
                }
            }

            // Create state lookup table
            ptr = 0;
            foreach (var entry in stateMachine.States)
            {
                kernelLookup[entry.Key] = ptr++;
            }

            foreach (var stateEntry in stateMachine.States)
            {
                var tableRow = table.Rows[kernelLookup[stateEntry.Key]];
                foreach (var groupEntry in stateEntry.Value.GroupRulesBySymbolAfter())
                {
                    var symbol = groupEntry.Key;

                    // SHIFT?
                    if (symbol.Type == SymbolType.Token)
                    {
                        var action = new LRParsingTableAction(ActionType.Shift, kernelLookup[groupEntry.Value]);
                        Debug.Assert(!tableRow.Actions.ContainsKey(symbol.ID) || tableRow.Actions[symbol.ID].Type != ActionType.Reduce, $"Shift/reduce conflict in the syntax grammar");
                        tableRow.Actions.Add(symbol.ID, action);
                    }
                    // GOTO?
                    if (symbol.Type == SymbolType.Production)
                    {
                        int stateID = kernelLookup[groupEntry.Value];
                        tableRow.GOTO.Add(symbol.ID, stateID);
                    }
                }
                // REDUCE?
                foreach (var itemset in stateEntry.Value.Closure.Where(s => s.SymbolAfter == null))
                {
                    foreach (var lookahead in itemset.Lookahead)
                    {
                        if (tableRow.Actions.ContainsKey(lookahead.ID))
                        {
                            Debug.Assert(false, $"{tableRow.Actions[lookahead.ID].Type.ToString()}/Reduce conflict in the syntax grammar");
                        }
                        tableRow.Actions.Add(lookahead.ID, new LRParsingTableAction(ActionType.Reduce, ruleLookup[itemset.Rule]));
                    }
                }
            }

            table.Rows[1].Actions[Symbol.EndStream.ID] = new LRParsingTableAction(ActionType.Accept, -1);

            return(table);
        }