private void DeregisterGroupSymbolEvents(GroupSymbol groupSymbol)
 {
     groupSymbol.Changed -= new EventHandler(GroupSymbol_Changed);
     groupSymbol.SymbolsCollection.ItemsAdded      -= new Collections.CollectionItemsChangedEventHandler <ISymbol>(GroupSymbol_ItemsAdded);
     groupSymbol.SymbolsCollection.ItemsRemoved    -= new Collections.CollectionItemsChangedEventHandler <ISymbol>(GroupSymbol_ItemsRemoved);
     groupSymbol.SymbolsCollection.CollectionReset -= new Collections.CollectionItemsChangedEventHandler <ISymbol>(GroupSymbol_CollectionReset);
 }
        private void GroupSymbol_Changed(object sender, EventArgs e)
        {
            GroupSymbol groupSymbol = (GroupSymbol)sender;

            foreach (ISymbol symbol in groupSymbol.Flatten())
            {
                symbol.Enabled = groupSymbol.Enabled;
            }

            ClearCaches();
            OnChanged();
        }
Пример #3
0
 private GroupSymbol(GroupSymbol original, Cloner cloner)
     : base(original, cloner)
 {
     symbols = new ObservableSet <ISymbol>(original.Symbols.Select(s => cloner.Clone(s)));
 }
    private void Initialize() {
      #region symbol declaration
      var add = new Addition();
      var sub = new Subtraction();
      var mul = new Multiplication();
      var div = new Division();
      var mean = new Average();
      var sin = new Sine();
      var cos = new Cosine();
      var tan = new Tangent();
      var log = new Logarithm();
      var pow = new Power();
      var square = new Square();
      var root = new Root();
      var sqrt = new SquareRoot();
      var exp = new Exponential();

      var airyA = new AiryA();
      var airyB = new AiryB();
      var bessel = new Bessel();
      var cosineIntegral = new CosineIntegral();
      var dawson = new Dawson();
      var erf = new Erf();
      var expIntegralEi = new ExponentialIntegralEi();
      var fresnelCosineIntegral = new FresnelCosineIntegral();
      var fresnelSineIntegral = new FresnelSineIntegral();
      var gamma = new Gamma();
      var hypCosineIntegral = new HyperbolicCosineIntegral();
      var hypSineIntegral = new HyperbolicSineIntegral();
      var norm = new Norm();
      var psi = new Psi();
      var sineIntegral = new SineIntegral();

      var @if = new IfThenElse();
      var gt = new GreaterThan();
      var lt = new LessThan();
      var and = new And();
      var or = new Or();
      var not = new Not();
      var xor = new Xor();
      var variableCondition = new VariableCondition();

      var timeLag = new TimeLag();
      var integral = new Integral();
      var derivative = new Derivative();

      var constant = new Constant();
      constant.MinValue = -20;
      constant.MaxValue = 20;
      var variableSymbol = new Variable();
      var laggedVariable = new LaggedVariable();
      var autoregressiveVariable = new AutoregressiveTargetVariable();
      #endregion

      #region group symbol declaration
      var arithmeticSymbols = new GroupSymbol(ArithmeticFunctionsName, new List<ISymbol>() { add, sub, mul, div, mean });
      var trigonometricSymbols = new GroupSymbol(TrigonometricFunctionsName, new List<ISymbol>() { sin, cos, tan });
      var exponentialAndLogarithmicSymbols = new GroupSymbol(ExponentialFunctionsName, new List<ISymbol> { exp, log });
      var specialFunctions = new GroupSymbol(SpecialFunctionsName, new List<ISymbol> { airyA, airyB, bessel, cosineIntegral, dawson, erf, expIntegralEi, 
        fresnelCosineIntegral,fresnelSineIntegral,gamma,hypCosineIntegral,hypSineIntegral,norm, psi, sineIntegral});
      var terminalSymbols = new GroupSymbol(TerminalsName, new List<ISymbol> { constant, variableSymbol });
      var realValuedSymbols = new GroupSymbol(RealValuedSymbolsName, new List<ISymbol>() { arithmeticSymbols, trigonometricSymbols, exponentialAndLogarithmicSymbols, specialFunctions, terminalSymbols });

      var powerSymbols = new GroupSymbol(PowerFunctionsName, new List<ISymbol> { square, pow, sqrt, root });

      var conditionSymbols = new GroupSymbol(ConditionsName, new List<ISymbol> { @if, variableCondition });
      var comparisonSymbols = new GroupSymbol(ComparisonsName, new List<ISymbol> { gt, lt });
      var booleanOperationSymbols = new GroupSymbol(BooleanOperatorsName, new List<ISymbol> { and, or, not, xor });
      var conditionalSymbols = new GroupSymbol(ConditionalSymbolsName, new List<ISymbol> { conditionSymbols, comparisonSymbols, booleanOperationSymbols });

      var timeSeriesSymbols = new GroupSymbol(TimeSeriesSymbolsName, new List<ISymbol> { timeLag, integral, derivative, laggedVariable, autoregressiveVariable });
      #endregion

      AddSymbol(realValuedSymbols);
      AddSymbol(powerSymbols);
      AddSymbol(conditionalSymbols);
      AddSymbol(timeSeriesSymbols);

      #region subtree count configuration
      SetSubtreeCount(arithmeticSymbols, 2, 2);
      SetSubtreeCount(trigonometricSymbols, 1, 1);
      SetSubtreeCount(pow, 2, 2);
      SetSubtreeCount(root, 2, 2);
      SetSubtreeCount(square, 1, 1);
      SetSubtreeCount(sqrt, 1, 1);
      SetSubtreeCount(exponentialAndLogarithmicSymbols, 1, 1);
      SetSubtreeCount(specialFunctions, 1, 1);
      SetSubtreeCount(terminalSymbols, 0, 0);

      SetSubtreeCount(@if, 3, 3);
      SetSubtreeCount(variableCondition, 2, 2);
      SetSubtreeCount(comparisonSymbols, 2, 2);
      SetSubtreeCount(and, 2, 2);
      SetSubtreeCount(or, 2, 2);
      SetSubtreeCount(not, 1, 1);
      SetSubtreeCount(xor, 2, 2);

      SetSubtreeCount(timeLag, 1, 1);
      SetSubtreeCount(integral, 1, 1);
      SetSubtreeCount(derivative, 1, 1);
      SetSubtreeCount(laggedVariable, 0, 0);
      SetSubtreeCount(autoregressiveVariable, 0, 0);
      #endregion

      #region allowed child symbols configuration
      AddAllowedChildSymbol(StartSymbol, realValuedSymbols);
      AddAllowedChildSymbol(StartSymbol, powerSymbols);
      AddAllowedChildSymbol(StartSymbol, conditionSymbols);
      AddAllowedChildSymbol(StartSymbol, timeSeriesSymbols);
      AddAllowedChildSymbol(StartSymbol, specialFunctions);

      AddAllowedChildSymbol(DefunSymbol, realValuedSymbols);
      AddAllowedChildSymbol(DefunSymbol, powerSymbols);
      AddAllowedChildSymbol(DefunSymbol, conditionSymbols);
      AddAllowedChildSymbol(DefunSymbol, timeSeriesSymbols);
      AddAllowedChildSymbol(DefunSymbol, specialFunctions);

      AddAllowedChildSymbol(realValuedSymbols, realValuedSymbols);
      AddAllowedChildSymbol(realValuedSymbols, powerSymbols);
      AddAllowedChildSymbol(realValuedSymbols, conditionSymbols);
      AddAllowedChildSymbol(realValuedSymbols, timeSeriesSymbols);
      AddAllowedChildSymbol(realValuedSymbols, specialFunctions);

      AddAllowedChildSymbol(powerSymbols, variableSymbol, 0);
      AddAllowedChildSymbol(powerSymbols, laggedVariable, 0);
      AddAllowedChildSymbol(powerSymbols, autoregressiveVariable, 0);
      AddAllowedChildSymbol(powerSymbols, constant, 1);

      AddAllowedChildSymbol(square, realValuedSymbols, 0);
      AddAllowedChildSymbol(square, conditionSymbols, 0);
      AddAllowedChildSymbol(square, timeSeriesSymbols, 0);

      AddAllowedChildSymbol(sqrt, realValuedSymbols, 0);
      AddAllowedChildSymbol(sqrt, conditionSymbols, 0);
      AddAllowedChildSymbol(sqrt, timeSeriesSymbols, 0);

      AddAllowedChildSymbol(@if, comparisonSymbols, 0);
      AddAllowedChildSymbol(@if, booleanOperationSymbols, 0);
      AddAllowedChildSymbol(@if, conditionSymbols, 1);
      AddAllowedChildSymbol(@if, realValuedSymbols, 1);
      AddAllowedChildSymbol(@if, powerSymbols, 1);
      AddAllowedChildSymbol(@if, timeSeriesSymbols, 1);
      AddAllowedChildSymbol(@if, conditionSymbols, 2);
      AddAllowedChildSymbol(@if, realValuedSymbols, 2);
      AddAllowedChildSymbol(@if, powerSymbols, 2);
      AddAllowedChildSymbol(@if, timeSeriesSymbols, 2);

      AddAllowedChildSymbol(booleanOperationSymbols, comparisonSymbols);
      AddAllowedChildSymbol(comparisonSymbols, realValuedSymbols);
      AddAllowedChildSymbol(comparisonSymbols, powerSymbols);
      AddAllowedChildSymbol(comparisonSymbols, conditionSymbols);
      AddAllowedChildSymbol(comparisonSymbols, timeSeriesSymbols);

      AddAllowedChildSymbol(variableCondition, realValuedSymbols);
      AddAllowedChildSymbol(variableCondition, powerSymbols);
      AddAllowedChildSymbol(variableCondition, conditionSymbols);
      AddAllowedChildSymbol(variableCondition, timeSeriesSymbols);


      AddAllowedChildSymbol(timeLag, realValuedSymbols);
      AddAllowedChildSymbol(timeLag, powerSymbols);
      AddAllowedChildSymbol(timeLag, conditionSymbols);

      AddAllowedChildSymbol(integral, realValuedSymbols);
      AddAllowedChildSymbol(integral, powerSymbols);
      AddAllowedChildSymbol(integral, conditionSymbols);

      AddAllowedChildSymbol(derivative, realValuedSymbols);
      AddAllowedChildSymbol(derivative, powerSymbols);
      AddAllowedChildSymbol(derivative, conditionSymbols);
      #endregion
    }
Пример #5
0
    // initialize set of allowed symbols and define 
    // the allowed combinations of symbols
    private void Initialize() {
      #region Symbols
      var block = new SimpleSymbol("Block", "A group of statements", 1, byte.MaxValue);
      var stat = new SimpleSymbol("Statement", "A statement.", 1, 1);
      var ifThenElseStat = new SimpleSymbol("IfThenElseStat", "An if statement.", 2, 3);
      var whileStat = new SimpleSymbol("WhileStat", "A while statement.", 2, 2);
      whileStat.Enabled = false;

      var boolExpr = new SimpleSymbol("BooleanExpression", "A Boolean expression.", 1, 1);
      var numericalExpr = new SimpleSymbol("NumericalExpression", "A numerical expression.", 1, 1);

      var equal = new SimpleSymbol("Equal", "Equal comparator.", 2, 2);
      var lessThan = new SimpleSymbol("LessThan", "LessThan comparator.", 2, 2);
      var lessThanOrEqual = new SimpleSymbol("LessThanOrEqual", "LessThanOrEqual comparator.", 2, 2);
      var greaterThan = new SimpleSymbol("GreaterThan", "GreaterThan comparator.", 2, 2);
      var greaterThanOrEqual = new SimpleSymbol("GreaterThanOrEqual", "GreaterThanOrEqual comparator.", 2, 2);

      var conjunction = new SimpleSymbol("ConditionalAnd", "Conjunction comparator.", 2, byte.MaxValue);
      var disjunction = new SimpleSymbol("ConditionalOr", "Disjunction comparator.", 2, byte.MaxValue);
      var negation = new SimpleSymbol("Negation", "A negation.", 1, 1);

      var addition = new SimpleSymbol("Addition", "Addition operator.", 2, byte.MaxValue);
      var subtraction = new SimpleSymbol("Subtraction", "Subtraction operator.", 2, byte.MaxValue);
      var multiplication = new SimpleSymbol("Multiplication", "Multiplication operator.", 2, byte.MaxValue);
      var division = new SimpleSymbol("Division", "Division operator.", 2, byte.MaxValue);
      var modulus = new SimpleSymbol("Modulus", "Modulus operator.", 2, byte.MaxValue);

      var number = new Number();
      var logicalVal = new BooleanValue();

      var ahead = new SimpleSymbol("Ahead", "Immediately moves your robot ahead (forward) by distance measured in pixels.", 1, 1);
      var back = new SimpleSymbol("Back", "Immediately moves your robot backward by distance measured in pixels.", 1, 1);
      var fire = new SimpleSymbol("Fire", "Immediately fires a bullet.", 1, 1);
      var shotPower = new ShotPower();

      var getEnergy = new SimpleSymbol("GetEnergy", "Returns the robot's current energy.", 0, 0);
      var getHeading = new SimpleSymbol("GetHeading", "Returns the direction that the robot's body is facing, in degrees.", 0, 0);
      var getGunHeading = new SimpleSymbol("GetGunHeading", "Returns the direction that the robot's gun is facing, in degrees.", 0, 0);
      var getRadarHeading = new SimpleSymbol("GetRadarHeading", "Returns the direction that the robot's radar is facing, in degrees.", 0, 0);
      var getX = new SimpleSymbol("GetX", "Returns the X position of the robot. (0,0) is at the bottom left of the battlefield.", 0, 0);
      var getY = new SimpleSymbol("GetY", "Returns the Y position of the robot. (0,0) is at the bottom left of the battlefield.", 0, 0);

      var turnLeft = new SimpleSymbol("TurnLeft", "Immediately turns the robot's body to the left by degrees.", 1, 1);
      var turnRight = new SimpleSymbol("TurnRight", "Immediately turns the robot's body to the right by degrees.", 1, 1);
      var turnGunLeft = new SimpleSymbol("TurnGunLeft", "Immediately turns the robot's gun to the left by degrees.", 1, 1);
      var turnGunRight = new SimpleSymbol("TurnGunRight", "Immediately turns the robot's gun to the right by degrees.", 1, 1);
      var turnRadarLeft = new SimpleSymbol("TurnRadarLeft", "Immediately turns the robot's radar to the left by degrees.", 1, 1);
      var turnRadarRight = new SimpleSymbol("TurnRadarRight", "Immediately turns the robot's radar to the right by degrees.", 1, 1);

      var onBulletHit = new SimpleSymbol("OnBulletHit", "This method is called when one of your bullets hits another robot.", 2, 10);
      var onBulletMissed = new SimpleSymbol("OnBulletMissed", "This method is called when one of your bullets misses, i.e. hits a wall.", 2, 10);
      var onHitByBullet = new SimpleSymbol("OnHitByBullet", "This method is called when your robot is hit by a bullet.", 2, 10);
      var onHitRobot = new SimpleSymbol("OnHitRobot", "This method is called when your robot collides with another robot.", 2, 10);
      var onHitWall = new SimpleSymbol("OnHitWall", "This method is called when your robot collides with a wall.", 2, 10);
      var onScannedRobot = new SimpleSymbol("OnScannedRobot", "This method is called when your robot sees another robot, i.e. when the robot's radar scan \"hits\" another robot.", 2, 10);

      var run = new SimpleSymbol("Run", "The main method in every robot.", 1, 10);
      var tank = new SimpleSymbol("Tank", "The root of a Robocode Tank program.", 2, 7);

      var doNothing = new SimpleSymbol("DoNothing", "Do nothing this turn, meaning that the robot will skip its turn.", 0, 0);
      var emptyEvent = new SimpleSymbol("EmptyEvent", "This is a placeholder for an empty event.", 0, 0);
      #endregion

      #region Symbol Collections
      var controlSymbols = new ISymbol[] { ifThenElseStat, whileStat };
      var actionSymbols = new ISymbol[] {
        ahead, back, fire, turnGunLeft, turnGunRight, turnLeft, turnRadarLeft, turnRadarRight, turnRight
      };
      var functionSymbols = new ISymbol[] {
        getEnergy, getGunHeading, getHeading, getRadarHeading, getX, getY
      };

      var events = new GroupSymbol(EventsName, new ISymbol[] { run, onScannedRobot, onBulletHit, onBulletMissed, onHitByBullet, onHitRobot, onHitWall });
      var controlStatements = new GroupSymbol(ControlStatementsName, controlSymbols);
      var expressions = new GroupSymbol(ExpressionsName, new ISymbol[] { boolExpr, numericalExpr });
      var robocodeFunctions = new GroupSymbol(RobocodeFunctionsName, functionSymbols);
      var robocodeActions = new GroupSymbol(RobocodeActionsName, actionSymbols);
      var relationalOperators = new GroupSymbol(RelationalOperatorsName, new ISymbol[] { equal, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual });
      var logicalOperators = new GroupSymbol(LogicalOperators, new ISymbol[] { conjunction, disjunction, negation });
      var numericalOperators = new GroupSymbol(NumericalOperatorsName, new ISymbol[] { addition, subtraction, multiplication, division, modulus });
      #endregion

      #region Adding Symbols
      AddSymbol(tank);
      AddSymbol(stat);
      AddSymbol(block);
      AddSymbol(shotPower);
      AddSymbol(number);
      AddSymbol(logicalVal);
      AddSymbol(events);
      AddSymbol(expressions);
      AddSymbol(controlStatements);
      AddSymbol(robocodeFunctions);
      AddSymbol(robocodeActions);
      AddSymbol(relationalOperators);
      AddSymbol(logicalOperators);
      AddSymbol(numericalOperators);
      AddSymbol(emptyEvent);
      AddSymbol(doNothing);
      #endregion

      #region Grammar Definition
      // StartSymbol
      AddAllowedChildSymbol(StartSymbol, tank);

      // Tank
      AddAllowedChildSymbol(tank, run, 0);
      AddAllowedChildSymbol(tank, onScannedRobot, 1);
      AddAllowedChildSymbol(tank, onBulletHit, 2);
      AddAllowedChildSymbol(tank, onBulletMissed, 3);
      AddAllowedChildSymbol(tank, onHitByBullet, 4);
      AddAllowedChildSymbol(tank, onHitRobot, 5);
      AddAllowedChildSymbol(tank, onHitWall, 6);

      // Events
      AddAllowedChildSymbol(events, stat);

      // Block
      AddAllowedChildSymbol(block, stat);

      // Stat
      AddAllowedChildSymbol(stat, stat);
      AddAllowedChildSymbol(stat, block);
      AddAllowedChildSymbol(stat, controlStatements);
      AddAllowedChildSymbol(stat, robocodeFunctions);
      AddAllowedChildSymbol(stat, robocodeActions);
      AddAllowedChildSymbol(stat, emptyEvent);
      AddAllowedChildSymbol(stat, doNothing);

      // IfStat
      AddAllowedChildSymbol(ifThenElseStat, boolExpr, 0);
      AddAllowedChildSymbol(ifThenElseStat, stat, 1);
      AddAllowedChildSymbol(ifThenElseStat, emptyEvent, 1);
      AddAllowedChildSymbol(ifThenElseStat, doNothing, 1);
      AddAllowedChildSymbol(ifThenElseStat, stat, 2);
      AddAllowedChildSymbol(ifThenElseStat, emptyEvent, 2);
      AddAllowedChildSymbol(ifThenElseStat, doNothing, 2);

      // WhileStat
      AddAllowedChildSymbol(whileStat, boolExpr, 0);
      AddAllowedChildSymbol(whileStat, stat, 1);
      AddAllowedChildSymbol(whileStat, emptyEvent, 1);
      AddAllowedChildSymbol(whileStat, doNothing, 1);

      // Numerical Expressions
      AddAllowedChildSymbol(numericalExpr, number);
      AddAllowedChildSymbol(numericalExpr, robocodeFunctions);
      AddAllowedChildSymbol(numericalExpr, numericalOperators);
      AddAllowedChildSymbol(numericalOperators, number);
      AddAllowedChildSymbol(numericalOperators, robocodeFunctions);
      AddAllowedChildSymbol(numericalOperators, numericalOperators);

      // Logical Expressions
      AddAllowedChildSymbol(boolExpr, logicalVal);
      AddAllowedChildSymbol(boolExpr, logicalOperators);
      AddAllowedChildSymbol(logicalOperators, logicalVal);
      AddAllowedChildSymbol(logicalOperators, logicalOperators);
      AddAllowedChildSymbol(logicalOperators, relationalOperators);
      AddAllowedChildSymbol(relationalOperators, numericalExpr);

      // Functions and Actions
      AddAllowedChildSymbol(robocodeFunctions, numericalExpr);
      foreach (var a in robocodeActions.Symbols) {
        if (a.Name == fire.Name) AddAllowedChildSymbol(a, shotPower);
        else AddAllowedChildSymbol(a, numericalExpr);
      }
      #endregion
    }
 private void DeregisterGroupSymbolEvents(GroupSymbol groupSymbol) {
   groupSymbol.Changed -= new EventHandler(GroupSymbol_Changed);
   groupSymbol.SymbolsCollection.ItemsAdded -= new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_ItemsAdded);
   groupSymbol.SymbolsCollection.ItemsRemoved -= new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_ItemsRemoved);
   groupSymbol.SymbolsCollection.CollectionReset -= new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_CollectionReset);
 }
Пример #7
0
 private GroupSymbol(GroupSymbol original, Cloner cloner)
   : base(original, cloner) {
   symbols = new ObservableSet<ISymbol>(original.Symbols.Select(s => cloner.Clone(s)));
 }
Пример #8
0
    private CFGExpressionGrammar readGrammarBNFPrivate(String bnf) {
      CFGExpressionGrammar treeGrammar = new CFGExpressionGrammar();

      Dictionary<CFGProduction, List<string>> productions = new Dictionary<CFGProduction, List<string>>();
      GroupSymbol root = null;
      var rule = ruleRegex.Match(bnf);
      while (rule.Success) {
        GroupSymbol curRuleSymbolGroup = new GroupSymbol();
        curRuleSymbolGroup.Name = "Rule: " + rule.Groups["rulename"].Value;

        treeGrammar.AddSymbol(curRuleSymbolGroup);
        if (root == null) {
          root = curRuleSymbolGroup;
        }

        var production = productionRegex.Match(rule.Groups["production"].Value);

        while (production.Success) {
          string productionName = production.Groups["production"].Value.Trim();
          if (!String.IsNullOrWhiteSpace(productionName)) {
            // production rule already exists
            // increase initial frequency
            if (curRuleSymbolGroup.SymbolsCollection.Any(x => x.Name.Equals(productionName))) {
              var symbol = (CFGSymbol)curRuleSymbolGroup.SymbolsCollection.First(x => x.Name.Equals(productionName));
              symbol.InitialFrequency++;
            } else {

              List<string> parts = new List<string>();
              parts.Add(String.Empty);

              var subRule = ruleInProdRegex.Match(productionName);

              List<string> rulesInProduction = new List<string>();
              while (subRule.Success) {
                if (!String.IsNullOrEmpty(subRule.Groups["subrule"].Value)) {
                  rulesInProduction.Add(subRule.Groups["subrule"].Value);
                  subRule = subRule.NextMatch();
                  parts.Add(String.Empty);
                  continue;
                }

                var part = String.Join(String.Empty, Enumerable.Range(1, subRule.Groups.Count - 1).Select(x => subRule.Groups[x].Value));
                // unescape characters so that tab and newline can be defined in the grammar
                if (part.Contains('\\')) {
                  part = part.Replace("\\n", Environment.NewLine);
                  part = Regex.Unescape(part);
                }
                parts[parts.Count - 1] = parts[parts.Count - 1] + part;

                subRule = subRule.NextMatch();
              }

              CFGProduction productionSymbol = new CFGProduction(productionName, parts.Count == 0
                                                                                 ? new List<string>() { productionName }
                                                                                 : parts);
              productions.Add(productionSymbol, rulesInProduction);
              curRuleSymbolGroup.SymbolsCollection.Add(productionSymbol);
            }
          }
          production = production.NextMatch();
        }
        rule = rule.NextMatch();
      }

      // assign subrules for start symbol
      var ruleGroupSymbol = treeGrammar.Symbols.Where(x => x is GroupSymbol && x.Name == root.Name).First() as GroupSymbol;
      foreach (var subProduction in ruleGroupSymbol.SymbolsCollection) {
        treeGrammar.AddAllowedChildSymbol(treeGrammar.StartSymbol, subProduction, 0);
      }

      // assign subrules
      foreach (var allowedSymbol in treeGrammar.AllowedSymbols.Where(x => x is CFGProduction)) {
        var cfgProduction = allowedSymbol as CFGProduction;
        var rulesInProduction = productions[cfgProduction];
        if (rulesInProduction.Count == 0) continue;

        treeGrammar.SetSubtreeCount(cfgProduction, rulesInProduction.Count, rulesInProduction.Count);
        for (int i = 0; i < rulesInProduction.Count; i++) {
          ruleGroupSymbol = treeGrammar.Symbols.Where(x => x is GroupSymbol && x.Name.Substring("Rule: ".Length, x.Name.Length - "Rule: ".Length) == rulesInProduction[i]).First() as GroupSymbol;

          foreach (var subProduction in ruleGroupSymbol.SymbolsCollection) {
            treeGrammar.AddAllowedChildSymbol(cfgProduction, subProduction, i);
          }
        }
      }

      return treeGrammar;
    }