Exemple #1
0
        /// <summary>
        /// Adds to this node all the choices of another node.
        /// </summary>
        public void Merge(GrammarRuleNode other)
        {
            var n = other.GetNumChoices();

            for (var i = 0; i < n; i++)
            {
                AddChoice(other.GetChoice(i));
            }
        }
Exemple #2
0
 /// <summary>
 /// Parses each of a rule's production choices.
 /// </summary>
 void ParseProductions(IEvolutionState state, GrammarRuleNode retResult, IGELexer lexer, GPFunctionSet gpfs)
 {
     do
     {
         var token = lexer.NextToken();
         if (lexer.MatchingIndex == RULE)
         {
             retResult.AddChoice(GetRule(_rules, token));
             token = lexer.NextToken();
         }
         else
         {
             if (lexer.MatchingIndex != LPAREN) //first expect '('
             {
                 state.Output.Fatal("GE Grammar Error - Unexpected token for rule: " + retResult.Head +
                                    "Expecting '('.");
             }
             token = lexer.NextToken();
             if (lexer.MatchingIndex != FUNCTION) //now expecting function
             {
                 state.Output.Fatal("GE Grammar Error - Expecting a function name after first '(' for rule: " +
                                    retResult.Head + " Error: " + token);
             }
             else
             {
                 if (!gpfs.NodesByName.ContainsKey(token))
                 {
                     state.Output.Fatal("GPNode " + token + " is not defined in the function set.");
                 }
                 var grammarfuncnode = new GrammarFunctionNode(gpfs, token);
                 token = lexer.NextToken();
                 while (lexer.MatchingIndex != RPAREN)
                 {
                     if (lexer.MatchingIndex != RULE) //this better be the name of a rule node
                     {
                         state.Output.Fatal(
                             "GE Grammar Error - Expecting a rule name as argument for function definition: "
                             + grammarfuncnode.Head + " Error on : " + token);
                     }
                     grammarfuncnode.AddArgument(GetRule(_rules, token));
                     token = lexer.NextToken();
                 }
                 retResult.AddChoice(grammarfuncnode);
             }
             //after right paren, should see either '|' or newline
             token = lexer.NextToken();
             if (lexer.MatchingIndex != PIPE && lexer.MatchingIndex != Constants.GE_LEXER_FAILURE)
             {
                 state.Output.Fatal("GE Grammar Error - Expecting either '|' delimiter or newline. Error on : " +
                                    token);
             }
         }
     } while (lexer.MatchingIndex == PIPE);
 }
Exemple #3
0
 /// <summary>
 /// Returns a rule from the hashmap.  If one does not exist, creates a rule with the
 /// given head and stores, then returns that.
 /// </summary>
 GrammarRuleNode GetRule(Hashtable rules, String head)
 {
     if (rules.ContainsKey(head))
     {
         return((GrammarRuleNode)rules[head]);
     }
     else
     {
         var node = new GrammarRuleNode(head);
         rules[head] = node;
         return(node);
     }
 }
Exemple #4
0
 /// <summary>
 /// Parses the rules from a grammar and returns the resulting GrammarRuleNode root.
 /// </summary>
 public GrammarRuleNode ParseRules(IEvolutionState state, TextReader reader, GPFunctionSet gpfs)
 {
     _rules = new Hashtable();
     try
     {
         String line;
         while ((line = reader.ReadLine()) != null)
         {
             GrammarRuleNode rule = ParseRule(state, new GELexer(line.Trim(), DEFAULT_REGEXES), gpfs);
             if (rule != null && _root == null)
             {
                 _root = rule;
             }
         }
     }
     catch (IOException)
     {
     } // do nothing
     state.Output.ExitIfErrors();
     return(_root);
 }
Exemple #5
0
        /// <summary>
        /// Parses a rule, one rule per line, from the lexer.
        /// Adds to the existing hashmap if there's already a rule there.
        /// </summary>
        GrammarRuleNode ParseRule(IEvolutionState state, IGELexer lexer, GPFunctionSet gpfs)
        {
            GrammarRuleNode retResult = null;

            string token = lexer.NextToken();

            if (lexer.MatchingIndex == COMMENT)
            {
                return(null);                //ignore the comment
            }
            if (lexer.MatchingIndex == RULE) //rule head, good, as expected...
            {
                lexer.NextToken();
                if (lexer.MatchingIndex != EQUALS)
                {
                    state.Output.Fatal("GE Grammar Error: Expecting equal sign after rule head: " + token);
                }
                retResult = GetRule(_rules, token);
                ParseProductions(state, retResult, lexer, gpfs);
            }
            else
            {
                state.Output.Fatal("GE Grammar Error - Unexpected token: Expecting rule head.: " + token);
            }
            return(retResult);
            // IMPLEMENTED
            // Need to parse the rule using a recursive descent parser
            // If there was an error, then try to call state.output.error(...).
            //
            // Don't merge into any existing rule -- I do that in parseRules below.  Instead, just pull out
            // rules and hang them into your "new rule" as necessary.
            // Use getRule(rules, "<rulename>") to extract the rule representing the current rule name which you
            // can hang inside there as necessary.
            //
            // If you have to you can call state.output.fatal(...) which will terminate the program,
            // but piling up some errors might be useful.  I'll handle the exitIfErors() in parseRules below
            //
            // Return null if there was no rule to parse (blank line or all comments) but no errors.
            // Also return null if you called state.output.error(...).
        }
Exemple #6
0
        GPNode MakeSubtree(IList <int> index, IList <int> genome,
                           IEvolutionState es, GPFunctionSet gpfs, GrammarRuleNode rule,
                           int treeNum, int threadNum, IDictionary <int, GPNode> ercMapsForFancyPrint, IGPNodeParent parent, byte argPosition)
        {
            //have we exceeded the length of the genome?  No point in going further.
            if (index[0] >= genome.Count)
            {
                throw new BigTreeException();
            }

            //expand the rule with the chromosome to get a body element
            int i;

            //non existant rule got passed in
            if (rule == null)
            {
                es.Output.Fatal("An undefined rule exists within the grammar.");
            }

            //more than one rule to consider, pick one based off the genome, and consume the current gene
            // avoid mod operation as much as possible
            if (rule.GetNumChoices() > 1)
            {
                i = (genome[index[0]] - (int)GetMinGene(index[0])) % rule.GetNumChoices();
            }
            else
            {
                i = 0;
            }
            index[0]++;
            GrammarNode choice = rule.GetChoice(i);

            // if body is another rule head
            //look up rule
            if (choice is GrammarRuleNode)
            {
                var nextrule = (GrammarRuleNode)choice;
                return(MakeSubtree(index, genome, es, gpfs, nextrule,
                                   treeNum, threadNum, ercMapsForFancyPrint, parent, argPosition));
            }
            else //handle functions
            {
                GrammarFunctionNode funcgrammarnode = (GrammarFunctionNode)choice;

                GPNode validNode = funcgrammarnode.GetGPNodePrototype();

                int numChildren = validNode.Children.Length;
                //index 0 is the node itself
                int numChildrenInGrammar = funcgrammarnode.GetNumArguments();

                //does the grammar contain the correct amount of children that the GPNode requires
                if (numChildren != numChildrenInGrammar)
                {
                    es.Output.Fatal("GPNode " + validNode.ToStringForHumans() + " requires "
                                    + numChildren + " children.  "
                                    + numChildrenInGrammar
                                    + " children found in the grammar.");
                }

                //check to see if it is an ERC node
                if (validNode is ERC)
                {
                    // have we exceeded the length of the genome?  No point in going further.
                    if (index[0] >= genome.Count)
                    {
                        throw new BigTreeException();
                    }

                    // ** do we actually need to maintain two vlaues ? key and originalVal ?
                    // ** there is no problem if we use the originalVal for both ERCBank and
                    // ** ercMapsForFancyPrint, moreover, this will also make the reverse-mapping case
                    // ** easier -- khaled

                    // these below two lines are from the original code --
                    // key for ERC hashtable look ups is the current index within the genome.  Consume it.
                    //int key = genome[index[0]] - (int)GetMinGene(index[0]);
                    //int originalVal = genome[index[0]];

                    // this single line is khaled's mod --
                    int genomeVal = genome[index[0]];
                    index[0]++;

                    validNode = ObtainERC(es, genomeVal, threadNum, validNode, ercMapsForFancyPrint);
                }
                //non ERC node
                else
                {
                    validNode = validNode.LightClone();
                }

                //get the rest.
                for (int j = 0, childNumber = 0; j < funcgrammarnode.GetNumArguments(); j++)
                {
                    //get and link children to the current GPNode
                    validNode.Children[childNumber] = MakeSubtree(index, genome, es, gpfs,
                                                                  (GrammarRuleNode)funcgrammarnode.GetArgument(j), treeNum, threadNum,
                                                                  ercMapsForFancyPrint, validNode, (byte)childNumber);

                    if (validNode.Children[childNumber] == null)
                    {
                        return(null);
                    }
                    childNumber++;
                }
                validNode.ArgPosition = argPosition;
                validNode.Parent      = parent;
                return(validNode);
            }
        }
Exemple #7
0
        public override void Setup(IEvolutionState state, IParameter paramBase)
        {
            base.Setup(state, paramBase);

            var def = DefaultBase;

            var p = paramBase.Push(P_GPSPECIES);

            GPSpecies = (GPSpecies)(state.Parameters.GetInstanceForParameterEq(p, def.Push(P_GPSPECIES), typeof(GPSpecies)));
            GPSpecies.Setup(state, p);

            // check to make sure that our individual prototype is a GPIndividual
            if (!(I_Prototype is IntegerVectorIndividual))
            {
                state.Output.Fatal("The Individual class for the Species " + GetType().Name + " must be a subclass of ge.GEIndividual.", paramBase);
            }

            ERCBank = Hashtable.Synchronized(new Hashtable());

            // load the grammars, one per ADF tree
            var gpi         = (GPIndividual)(GPSpecies.I_Prototype);
            var trees       = gpi.Trees;
            var numGrammars = trees.Length;

            ParserPrototype = (GrammarParser)state.Parameters.GetInstanceForParameterEq(
                paramBase.Push(P_PARSER),
                def.Push(P_PARSER),
                typeof(GrammarParser));

            Grammar = new GrammarRuleNode[numGrammars];
            for (var i = 0; i < numGrammars; i++)
            {
                p   = paramBase.Push(P_FILE);
                def = DefaultBase;

                //var grammarFile = state.Parameters.GetFile(p, def.Push(P_FILE).Push("" + i));
                Stream grammarFile = state.Parameters.GetResource(p, def.Push(P_FILE).Push("" + i));

                if (grammarFile == null)
                {
                    state.Output.Fatal("Error retrieving grammar file(s): " + def + "." + P_FILE + "." + i + " is undefined.");
                }

                GPFunctionSet gpfs = trees[i].Constraints((GPInitializer)state.Initializer).FunctionSet;
                // now we need different parser object for each of the grammars,
                // why? see GrammarParser.java for details -- khaled
                GrammarParser[i] = (GrammarParser)ParserPrototype.Clone();
                StreamReader reader = new StreamReader(grammarFile);
                Grammar[i] = GrammarParser[i].ParseRules(state, reader, gpfs);

                // Enumerate the grammar tree -- khaled
                GrammarParser[i].EnumerateGrammarTree(Grammar[i]);
                // Generate the predictive parse table -- khaled
                GrammarParser[i].PopulatePredictiveParseTable(Grammar[i]);

                try
                {
                    reader.Close();
                }
                catch (IOException e)
                {
                    // do nothing
                }
            }
            // get the initialization scheme -- khaled
            InitScheme = state.Parameters.GetString(paramBase.Push(P_INITSCHEME), def.Push(P_INITSCHEME));
            if (InitScheme != null && InitScheme.Equals("sensible"))
            {
                state.Output.WarnOnce("Using a \"hacked\" version of \"sensible initialization\"");
            }
            else
            {
                state.Output.WarnOnce("Using default GE initialization scheme");
            }

            // setup the "passes" parameters
            int MAXIMUM_PASSES = 1024;

            Passes = state.Parameters.GetInt(paramBase.Push(P_PASSES), def.Push(P_PASSES), 1);
            if (Passes < 1 || Passes > MAXIMUM_PASSES)
            {
                state.Output.Fatal("Number of allowed passes must be >= 1 and <="
                                   + MAXIMUM_PASSES + ", likely small, such as <= 16.",
                                   paramBase.Push(P_PASSES), def.Push(P_PASSES));
            }
            int oldpasses = Passes;

            Passes = NextPowerOfTwo(Passes);
            if (oldpasses != Passes)
            {
                state.Output.Warning("Number of allowed passes must be a power of 2.  Bumping from "
                                     + oldpasses + " to " + Passes, paramBase.Push(P_PASSES), def.Push(P_PASSES));
            }
        }