예제 #1
0
파일: Loader.cs 프로젝트: sebgod/hime
        /// <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>
        private RuleBodySet BuildAtomicDefinition(LoaderContext context, ASTNode node)
        {
            if (node.Symbol.ID == HimeGrammarParser.ID.VariableRuleSymAction)
            {
                return(BuildAtomicAction(node));
            }
            if (node.Symbol.ID == HimeGrammarParser.ID.VariableRuleSymVirtual)
            {
                return(BuildAtomicVirtual(node));
            }
            if (node.Symbol.ID == HimeGrammarParser.ID.VariableRuleSymRefSimple)
            {
                return(BuildAtomicSimpleReference(context, node));
            }
            if (node.Symbol.ID == HimeGrammarParser.ID.VariableRuleSymRefTemplate)
            {
                return(BuildAtomicTemplateReference(context, node));
            }
            if (node.Symbol.ID == HimeGrammarLexer.ID.TerminalLiteralText)
            {
                return(BuildAtomicInlineText(node));
            }
            // nothing found ...
            OnError(node.Position, "Failed to recognize syntactic rule");
            RuleBodySet set = new RuleBodySet();

            set.Add(new RuleBody());
            return(set);
        }
예제 #2
0
파일: Loader.cs 프로젝트: sebgod/hime
        /// <summary>
        /// Builds the set of rule definitions that represents a single reference to a template variable
        /// </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>
        private RuleBodySet BuildAtomicTemplateReference(LoaderContext context, ASTNode node)
        {
            RuleBodySet defs = new RuleBodySet();
            // Get the information
            string name       = node.Children[0].Value;
            int    paramCount = node.Children[1].Children.Count;

            // check for meta-rule existence
            if (!context.IsTemplateRule(name, paramCount))
            {
                OnError(node.Children[0].Position, "Unknown meta-rule {0}<{1}> in rule definition", name, paramCount);
                defs.Add(new RuleBody());
                return(defs);
            }
            // Recognize the parameters
            List <Symbol> parameters = new List <Symbol>();

            foreach (ASTNode symbolNode in node.Children[1].Children)
            {
                parameters.Add(BuildAtomicDefinition(context, symbolNode)[0][0].Symbol);
            }
            // Get the corresponding variable
            Variable variable = context.InstantiateMetaRule(name, parameters);

            // Create the definition
            defs.Add(new RuleBody(variable));
            return(defs);
        }
예제 #3
0
파일: RuleBodySet.cs 프로젝트: sebgod/hime
        /// <summary>
        /// Builds the union of the left and right set
        /// </summary>
        /// <param name="left">A set of rule bodies</param>
        /// <param name="right">A set of rule bodies</param>
        public static RuleBodySet Union(RuleBodySet left, RuleBodySet right)
        {
            RuleBodySet result = new RuleBodySet();

            result.AddRange(left);
            result.AddRange(right);
            return(result);
        }
예제 #4
0
파일: Loader.cs 프로젝트: sebgod/hime
        /// <summary>
        /// Builds the set of rule definitions that represents a single semantic action
        /// </summary>
        /// <param name="node">The AST node of a syntactic rule</param>
        /// <returns>The set of possible rule definitions</returns>
        private RuleBodySet BuildAtomicAction(ASTNode node)
        {
            RuleBodySet set    = new RuleBodySet();
            string      name   = node.Children[0].Value;
            Action      action = grammar.GetAction(name) ?? grammar.AddAction(name);

            set.Add(new RuleBody(action));
            return(set);
        }
예제 #5
0
파일: Loader.cs 프로젝트: sebgod/hime
        /// <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));
            }
        }
예제 #6
0
파일: Loader.cs 프로젝트: sebgod/hime
        /// <summary>
        /// Builds the set of rule definitions that represents a single virtual symbol
        /// </summary>
        /// <param name="node">The AST node of a syntactic rule</param>
        /// <returns>The set of possible rule definitions</returns>
        private RuleBodySet BuildAtomicVirtual(ASTNode node)
        {
            RuleBodySet set  = new RuleBodySet();
            string      name = node.Children[0].Value;

            name = ReplaceEscapees(name.Substring(1, name.Length - 2));
            Virtual vir = grammar.GetVirtual(name) ?? grammar.AddVirtual(name);

            set.Add(new RuleBody(vir));
            return(set);
        }
예제 #7
0
파일: RuleBodySet.cs 프로젝트: sebgod/hime
        /// <summary>
        /// Builds the product of the left and right set
        /// </summary>
        /// <param name="left">A set of rule bodies</param>
        /// <param name="right">A set of rule bodies</param>
        public static RuleBodySet Multiply(RuleBodySet left, RuleBodySet right)
        {
            RuleBodySet result = new RuleBodySet();

            foreach (RuleBody defLeft in left)
            {
                foreach (RuleBody defRight in right)
                {
                    result.Add(RuleBody.Concatenate(defLeft, defRight));
                }
            }
            return(result);
        }
예제 #8
0
파일: Loader.cs 프로젝트: sebgod/hime
        /// <summary>
        /// Builds the set of rule definitions that represents a single reference to a simple variable
        /// </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>
        private RuleBodySet BuildAtomicSimpleReference(LoaderContext context, ASTNode node)
        {
            RuleBodySet defs   = new RuleBodySet();
            Symbol      symbol = ResolveSymbol(node.Children[0].Value, context);

            if (symbol == null)
            {
                OnError(node.Children[0].Position, "Unknown symbol {0} in rule definition", node.Children[0].Value);
                defs.Add(new RuleBody());
            }
            else
            {
                defs.Add(new RuleBody(symbol));
            }
            return(defs);
        }
예제 #9
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));
            }
        }
예제 #10
0
파일: Loader.cs 프로젝트: sebgod/hime
        /// <summary>
        /// Builds the set of rule definitions that represents a single inline piece of text
        /// </summary>
        /// <param name="node">The AST node of a syntactic rule</param>
        /// <returns>The set of possible rule definitions</returns>
        private RuleBodySet BuildAtomicInlineText(ASTNode node)
        {
            // Construct the terminal name
            string value = node.Value;

            value = value.Substring(1, value.Length - 2);
            value = ReplaceEscapees(value);
            // Check for previous instance in the grammar
            Terminal terminal = grammar.GetTerminalByValue(value);

            if (terminal == null)
            {
                // Create the terminal
                NFA nfa = BuildNFAFromText(node);
                terminal = grammar.AddTerminalAnon(value, nfa);
                nfa.StateExit.AddItem(terminal);
            }
            // Create the definition set
            RuleBodySet set = new RuleBodySet();

            set.Add(new RuleBody(terminal));
            return(set);
        }
예제 #11
0
파일: Loader.cs 프로젝트: sebgod/hime
 /// <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));
 }