예제 #1
0
        /// <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));
        }
예제 #3
0
        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;
 }