/// <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)); }