Exemple #1
0
        /// <summary>
        /// The last Rule is often a 'fallback' rule with an empty condition. If this is the case,
        /// we can sometimes perform an optimisation that reduces the overall code size.
        /// </summary>
        /// <returns>Root of the generated tree.</returns>
        private Node?BuildFallbackSequence()
        {
            // sanity check
            if (ruleSet.NumRules <= 1)
            {
                return(null);
            }

            // check that there is a fallback rule
            RuleSetEntry lastRule = ruleSet[ruleSet.NumRules - 1];

            if (!lastRule.EffectiveCondition.IsEmpty)
            {
                return(null);
            }

            // check that sequence nodes are permitted
            if (!spec.Config.AllowSequence)
            {
                return(null);
            }

            if (spec.Config.Verbose)
            {
                Console.WriteLine("Performing fallback sequence optimisation.");
            }

            // remove the fallback rule and build the tree
            RuleSet rSet    = ruleSet.DeriveExcludingLast();
            var     builder = new TreeBuilder(spec, rSet, this);
            Node    node    = builder.Build();

            // ensure that there is a sequence node including the root
            // of the tree
            SequenceNode seq;

            if (node is SequenceNode)
            {
                seq = (SequenceNode)node;
            }
            else
            {
                seq = new SequenceNode(spec);
                seq.Append(node);
            }

            // now paste the fallback rule onto the end of the sequence
            seq.Append(lastRule.Rule);
            return(seq);
        }
Exemple #2
0
        /// <summary>
        /// Generate an if-else node for a Rule.
        /// </summary>
        private Node CreateIfElseNode(RuleSetEntry entry, Node elseBranch)
        {
            // generate a child node for the rule
            if (entry.EffectiveCondition.IsEmpty)
            {
                if (spec.Config.Verbose && !(elseBranch is EmptyNode))
                {
                    Console.WriteLine("Discarding non-empty else branch; condition is empty.");
                }

                return(entry.Rule);
            }
            else
            {
                if (spec.Config.NoOptimiseIfConditionNodes)
                {
                    return(new IfElseNode(spec, entry.Rule.Condition, entry.Rule, elseBranch));
                }
                else
                {
                    return(new IfElseNode(spec, entry.EffectiveCondition, entry.Rule, elseBranch));
                }
            }
        }