Exemplo n.º 1
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));
 }