示例#1
0
        private LRParsingTable(int stateCount, ProductionTable productionTable)
        {
            this.Rows = new LRParsingTableRow[stateCount];

            int numRules = productionTable.Productions.Sum(production => production.Rules.Count);

            this.Productions = new Rule[numRules];

            for (int i = 0; i < this.Rows.Length; i++)
            {
                this.Rows[i] = new LRParsingTableRow();
            }
        }
示例#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);
        }