/// <summary> /// creates an entry with a single terminal /// </summary> /// <param name="terminal"></param> /// <param name="epsilonSymbols"></param> /// <param name="cfg"></param> /// <returns></returns> public static TableField <A> WithTerminal(Exprinal <A> terminal, Dictionary <int, DerivationNode <A> > epsilonSymbols, PerformanceCFG cfg) { var entries = new Dictionary <int, DerivationNode <A> > { { terminal.UnqiueId, new DerivationNode <A>(terminal) } }; return(new TableField <A>(entries, epsilonSymbols, cfg)); }
public static ContextFreeGrammar GenerateRandomCNF() { Nonterminal startS = new Nonterminal("S"); List <Nonterminal> nts = new List <Nonterminal>(); nts.Add(startS); //nonterminals int ntcount = rnd.Next(3, 6); while (nts.Count < ntcount) { var newNt = new Nonterminal("" + (char)('A' + rnd.Next(26))); //random NT name if (!nts.Contains(newNt)) { nts.Add(newNt); } } //terminals int tcount = rnd.Next(3, 6); List <GrammarSymbol> ts = new List <GrammarSymbol>(); while (ts.Count < tcount) { String name = "" + (char)('a' + rnd.Next(26)); var newT = new Exprinal <String>(name, name); if (!ts.Contains(newT)) { ts.Add(newT); } } //productions List <Production> prods = new List <Production>(); prods.Add(generateRandomCNFProduction(startS, nts, ts)); //add a production for Start with only NTs foreach (Nonterminal nt in nts) { prods.Add(generateRandomCNFProduction(nt, nts, ts)); //at least 1 prod per NT while (rnd.NextDouble() < 0.6) { prods.Add(generateRandomCNFProduction(nt, nts, ts)); //generate more prods } } return(new ContextFreeGrammar(startS, prods)); }
public FindDerivationProblem Generate(int targetLevel) { ContextFreeGrammar grammar = GrammarGenerator.GenerateRandom(); var productions = grammar.GetProductions(); var toAdd = new List <Production>(); //make sure every varaible has a resolution (production with #NT = 0) and an continuation (production with #NT > 0) foreach (Nonterminal nt in grammar.Variables) { var nt_prods = grammar.GetProductions(nt); //resolution check var p = nt_prods.ToList().Find(pp => pp.ContainsNoVariables); if (p == null) { GrammarSymbol t = Choose(grammar.GetNonVariableSymbols()); if (t == null) { t = new Exprinal <char>('x', "x"); } p = new Production(nt, new GrammarSymbol[] { t }); toAdd.Add(p); } //continuation check p = nt_prods.ToList().Find(pp => Derivation.countNT(pp.Rhs) >= 1); if (p == null) { //resolution check GrammarSymbol t = Choose(grammar.Variables); p = new Production(nt, new GrammarSymbol[] { Choose(grammar.Variables), Choose(grammar.Variables) }); toAdd.Add(p); } } //add new productions (for resolution and continuation) if (toAdd.Count != 0) { grammar = new ContextFreeGrammar(grammar.StartSymbol, grammar.GetProductions().Concat(toAdd)); } productions = grammar.GetProductions(); //type bool shouldBeAny = true; if (targetLevel == Generation.ANY) { shouldBeAny = (rnd.Next(0, 9) < 3); // 30% } if (targetLevel == Generation.MEDIUM) { shouldBeAny = (rnd.Next(0, 9) < 2); // 20% } if (targetLevel == Generation.HIGH) { shouldBeAny = (rnd.Next(0, 9) < 9); // 90% } int type = Derivation.DERIVATION_ALL; if (!shouldBeAny) { type = Derivation.DERIVATION_LEFTMOST; if (rnd.Next(0, 9) < 3) { type = Derivation.DERIVATION_RIGHTMOST; } } //nr of steps int steps = rnd.Next(5, 10); if (targetLevel == Generation.LOW) { steps = rnd.Next(3, 6); } if (targetLevel == Generation.MEDIUM) { steps = rnd.Next(7, 9); } if (targetLevel == Generation.HIGH) { steps = rnd.Next(10, 12); } List <GrammarSymbol[]> derivation = new List <GrammarSymbol[]>(steps + 1); var cur = new GrammarSymbol[] { grammar.StartSymbol }; derivation.Add(cur); for (int i = 0; i < steps; i++) { //get possible next steps IEnumerable <GrammarSymbol[]> next = Derivation.findAllDerivations(grammar.GetProductions(), cur, type); if (Derivation.countNT(cur) <= 1 && i != steps - 1) //don't end yet! { next = next.Where(pw => Derivation.countNT(pw) >= 1); } //try not to repeat var next_part = next.Except(derivation); if (next_part.Count() > 0) { next = next_part; } cur = Choose(next); //cut out repeat if (derivation.Contains(cur)) { int r_i = derivation.IndexOf(cur); derivation = derivation.GetRange(0, r_i); } //add next step derivation.Add(cur); } //replace all NTs while (Derivation.countNT(cur) > 0) { //get possible next steps IEnumerable <GrammarSymbol[]> next = Derivation.findAllDerivations(grammar.GetProductions(), cur, type); //filter int curNTs = Derivation.countNT(cur); next = next.Where(pw => Derivation.countNT(pw) < curNTs); cur = Choose(next); derivation.Add(cur); } String word = Derivation.partialWordToString(cur); return(new FindDerivationProblem(grammar, word, type, derivation)); }
public DerivationNode(Exprinal <A> symbol) { Symbol = symbol; }