예제 #1
0
        CreateActionTable <SYMBOL_ENUM, TREE_NODE>(Productions <SYMBOL_ENUM, TREE_NODE> productions,
                                                   PrecedenceTable <SYMBOL_ENUM> precedenceTable,
                                                   GrammarReport <SYMBOL_ENUM, TREE_NODE> report,
                                                   int lookaheadWidth)

            where SYMBOL_ENUM : struct
            where TREE_NODE : class
        {
            if (productions == null)
            {
                return(null);
            }
            if (lookaheadWidth < 1)
            {
                throw new ArgumentException("Lookahead width is too small");
            }

            precedenceTable.Validate(lookaheadWidth);

            BuilderSets <SYMBOL_ENUM, TREE_NODE> builder_sets = BuilderSets.Create(productions, lookaheadWidth);

            report.Setup(productions, builder_sets);

            {
                IEnumerable <Tuple <SYMBOL_ENUM, bool> > err_recur_lhs = productions.Entries
                                                                         // do not check Auto recursive
                                                                         .Where(prod => ((prod.Recursive == RecursiveEnum.No) && builder_sets.CoverSets.IsRecursive(prod.LhsNonTerminal)) ||
                                                                                ((prod.Recursive == RecursiveEnum.Yes) && !builder_sets.CoverSets.IsRecursive(prod.LhsNonTerminal)))
                                                                         .Select(prod => Tuple.Create(prod.LhsNonTerminal, !builder_sets.CoverSets.IsRecursive(prod.LhsNonTerminal))).Distinct().ToArray();
                if (err_recur_lhs.Any())
                {
                    if (err_recur_lhs.Where(it => it.Item2).Any())
                    {
                        report.AddError("Productions incorrectly marked as recursive: " + err_recur_lhs.Where(it => it.Item2).Select(it => "\"" + productions.SymbolsRep.Get(it.Item1) + "\"").Join(",") + ".");
                    }
                    if (err_recur_lhs.Where(it => !it.Item2).Any())
                    {
                        report.AddError("Productions incorrectly marked as non-recursive: " + err_recur_lhs.Where(it => !it.Item2).Select(it => "\"" + productions.SymbolsRep.Get(it.Item1) + "\"").Join(",") + ".");
                    }
                    return(null);
                }
            }

            Dfa <SYMBOL_ENUM, TREE_NODE> dfa = Worker.CreateDfa(productions, lookaheadWidth, builder_sets.PrecomputedRhsFirsts,
                                                                builder_sets.HorizonSets);

            report.Setup(dfa);

            return(new ActionBuilder <SYMBOL_ENUM, TREE_NODE>().FillActionTable(productions, builder_sets.FirstSets,
                                                                                builder_sets.CoverSets,
                                                                                builder_sets.HorizonSets,
                                                                                lookaheadWidth, dfa, precedenceTable, report));
        }
예제 #2
0
 public void Setup(Productions <SYMBOL_ENUM, TREE_NODE> productions, BuilderSets <SYMBOL_ENUM, TREE_NODE> builderSets)
 {
     this.productions = productions;
     this.builderSets = builderSets;
 }