Пример #1
0
        /// <summary>
        /// Loads the syntactic rule in the given AST
        /// </summary>
        /// <param name="context">The current context</param>
        /// <param name="node">The AST node of a syntactic rule</param>
        private void LoadRule(LoaderContext context, ASTNode node)
        {
            string      name = node.Children[0].Value;
            Variable    var  = grammar.GetVariable(name);
            RuleBodySet defs = BuildDefinitions(context, node.Children[1]);

            foreach (RuleBody def in defs)
            {
                var.AddRule(new Rule(var, TreeAction.None, def, 0));
            }
        }
Пример #2
0
 /// <summary>
 /// Inherits the variables from the parent grammar
 /// </summary>
 /// <param name="parent">The parent's grammar</param>
 /// <param name="doClone">Clone the symbols</param>
 private void InheritVariables(Grammar parent, bool doClone)
 {
     foreach (Variable variable in parent.Variables)
     {
         if (doClone)
         {
             Variable clone = new Variable(variable.ID, variable.Name);
             variables.Add(clone.Name, clone);
         }
         else
         {
             AddVariable(variable.Name);
         }
     }
     foreach (Variable variable in parent.Variables)
     {
         Variable clone = variables[variable.Name];
         foreach (Rule rule in variable.Rules)
         {
             List <RuleBodyElement> parts = new List <RuleBodyElement>();
             for (int i = 0; i != rule.Body.Length; i++)
             {
                 RuleBodyElement part   = rule.Body[i];
                 Symbol          symbol = null;
                 if (part.Symbol is Variable)
                 {
                     symbol = variables[part.Symbol.Name];
                 }
                 else if (part.Symbol is Terminal)
                 {
                     symbol = terminalsByName[part.Symbol.Name];
                 }
                 else if (part.Symbol is Virtual)
                 {
                     symbol = virtuals[part.Symbol.Name];
                 }
                 else if (part.Symbol is Action)
                 {
                     symbol = actions[part.Symbol.Name];
                 }
                 parts.Add(new RuleBodyElement(symbol, part.Action));
             }
             clone.AddRule(new Rule(clone, rule.HeadAction, new RuleBody(parts), ResolveContext(parent.contexts[rule.Context])));
         }
     }
 }
Пример #3
0
        /// <summary>
        /// Compile this rule and generate the associated grammar rule
        /// </summary>
        /// <param name="context">The current context</param>
        public void Compile(LoaderContext context)
        {
            // Create a new context for recognizing the rule
            LoaderContext newContext = new LoaderContext(context);

            // Add the parameters as references in the new context
            for (int i = 0; i != parameters.Count; i++)
            {
                newContext.AddBinding(templateRule.Parameters[i], parameters[i]);
            }
            // Recognize the rule with the new context
            RuleBodySet set = newContext.Loader.BuildDefinitions(newContext, templateRule.DefinitionNode);

            // Add recognized rules to the variable
            foreach (RuleBody def in set)
            {
                variable.AddRule(new Rule(variable, TreeAction.None, def, 0));
            }
        }
Пример #4
0
        /// <summary>
        /// Adds the real axiom to this grammar
        /// </summary>
        /// <returns>An error message, if any</returns>
        private string AddRealAxiom()
        {
            // Search for Axiom option
            if (!options.ContainsKey(OPTION_AXIOM))
            {
                return("No axiom variable has been defined for grammar " + name);
            }
            // Search for the variable specified as the Axiom
            string axiomName = options[OPTION_AXIOM];

            if (!variables.ContainsKey(axiomName))
            {
                return("The specified axiom variable " + axiomName + " is undefined");
            }

            // Create the real axiom rule variable and rule
            Variable axiom = AddVariable(GENERATED_AXIOM);
            List <RuleBodyElement> parts = new List <RuleBodyElement>();

            parts.Add(new RuleBodyElement(variables[axiomName], TreeAction.Promote));
            parts.Add(new RuleBodyElement(Dollar.Instance, TreeAction.Drop));
            axiom.AddRule(new Rule(axiom, TreeAction.None, new RuleBody(parts), 0));
            return(null);
        }
Пример #5
0
 /// <summary>
 /// Builds the set of rule definitions that are represented by the given AST
 /// </summary>
 /// <param name="context">The current context</param>
 /// <param name="node">The AST node of a syntactic rule</param>
 /// <returns>The set of possible rule definitions</returns>
 public RuleBodySet BuildDefinitions(LoaderContext context, ASTNode node)
 {
     if (node.Symbol.ID == HimeGrammarParser.ID.VariableRuleDefContext)
     {
         int         contextID = grammar.ResolveContext(node.Children[0].Value);
         RuleBodySet setInner  = BuildDefinitions(context, node.Children[1]);
         Variable    subVar    = grammar.GenerateVariable();
         foreach (RuleBody def in setInner)
         {
             subVar.AddRule(new Rule(subVar, TreeAction.ReplaceByChildren, def, contextID));
         }
         RuleBodySet setVar = new RuleBodySet();
         setVar.Add(new RuleBody(subVar));
         return(setVar);
     }
     else if (node.Symbol.ID == HimeGrammarParser.ID.VariableRuleDefSub)
     {
         RuleBodySet setInner = BuildDefinitions(context, node.Children[0]);
         Variable    subVar   = grammar.GenerateVariable();
         foreach (RuleBody def in setInner)
         {
             subVar.AddRule(new Rule(subVar, TreeAction.ReplaceByEpsilon, def, 0));
         }
         RuleBodySet setVar = new RuleBodySet();
         setVar.Add(new RuleBody(subVar));
         return(setVar);
     }
     else if (node.Symbol.ID == HimeGrammarLexer.ID.TerminalOperatorOptional)
     {
         RuleBodySet setInner = BuildDefinitions(context, node.Children[0]);
         setInner.Insert(0, new RuleBody());
         return(setInner);
     }
     else if (node.Symbol.ID == HimeGrammarLexer.ID.TerminalOperatorZeromore)
     {
         RuleBodySet setInner = BuildDefinitions(context, node.Children[0]);
         Variable    subVar   = grammar.GenerateVariable();
         foreach (RuleBody def in setInner)
         {
             subVar.AddRule(new Rule(subVar, TreeAction.ReplaceByChildren, def, 0));
         }
         RuleBodySet setVar = new RuleBodySet();
         setVar.Add(new RuleBody(subVar));
         setVar = RuleBodySet.Multiply(setVar, setInner);
         foreach (RuleBody def in setVar)
         {
             subVar.AddRule(new Rule(subVar, TreeAction.ReplaceByChildren, def, 0));
         }
         setVar = new RuleBodySet();
         setVar.Add(new RuleBody());
         setVar.Add(new RuleBody(subVar));
         return(setVar);
     }
     else if (node.Symbol.ID == HimeGrammarLexer.ID.TerminalOperatorOnemore)
     {
         RuleBodySet setInner = BuildDefinitions(context, node.Children[0]);
         Variable    subVar   = grammar.GenerateVariable();
         foreach (RuleBody def in setInner)
         {
             subVar.AddRule(new Rule(subVar, TreeAction.ReplaceByChildren, def, 0));
         }
         RuleBodySet setVar = new RuleBodySet();
         setVar.Add(new RuleBody(subVar));
         setVar = RuleBodySet.Multiply(setVar, setInner);
         foreach (RuleBody def in setVar)
         {
             subVar.AddRule(new Rule(subVar, TreeAction.ReplaceByChildren, def, 0));
         }
         setVar = new RuleBodySet();
         setVar.Add(new RuleBody(subVar));
         return(setVar);
     }
     else if (node.Symbol.ID == HimeGrammarLexer.ID.TerminalOperatorUnion)
     {
         RuleBodySet setLeft  = BuildDefinitions(context, node.Children[0]);
         RuleBodySet setRight = BuildDefinitions(context, node.Children[1]);
         return(RuleBodySet.Union(setLeft, setRight));
     }
     else if (node.Symbol.ID == HimeGrammarLexer.ID.TerminalTreeActionPromote)
     {
         RuleBodySet setInner = BuildDefinitions(context, node.Children[0]);
         setInner.ApplyAction(TreeAction.Promote);
         return(setInner);
     }
     else if (node.Symbol.ID == HimeGrammarLexer.ID.TerminalTreeActionDrop)
     {
         RuleBodySet setInner = BuildDefinitions(context, node.Children[0]);
         setInner.ApplyAction(TreeAction.Drop);
         return(setInner);
     }
     else if (node.Symbol.Name == "concat")
     {
         RuleBodySet setLeft  = BuildDefinitions(context, node.Children[0]);
         RuleBodySet setRight = BuildDefinitions(context, node.Children[1]);
         return(RuleBodySet.Multiply(setLeft, setRight));
     }
     else if (node.Symbol.Name == "emptypart")
     {
         RuleBodySet set = new RuleBodySet();
         set.Add(new RuleBody());
         return(set);
     }
     return(BuildAtomicDefinition(context, node));
 }