private List <string> GetValidReplacements(ProductionRule productionRule)
        {
            List <string> vr = new List <string>(productionRule.Replacements.Count);

            for (int i = 0; i < productionRule.Replacements.Count; ++i)
            {
                string replacement = (productionRule.Replacements[i] ?? String.Empty).Trim();

                for (int cc = 0; cc < replacement.Length; ++cc)
                {
                    cc = replacement.IndexOf('{', cc);
                    if (cc == -1)
                    {
                        break;
                    }
                    int          bcc = cc;
                    TextWildcard w   = TextWildcard.XtractWildcard(replacement, ref cc);
                    if (w.Name != "void")
                    {
                        continue;
                    }
                    replacement = replacement.Remove(bcc) + replacement.Substring(cc);
                    cc          = bcc;
                }

                if (String.IsNullOrEmpty(replacement))
                {
                    continue;
                }

                vr.Add(replacement);
            }
            return(vr);
        }
        private void SRGSWriteProductionRule(ProductionRule productionRule)
        {
            List <string> validReplacements = GetValidReplacements(productionRule);

            writer.WriteStartElement("rule");
            writer.WriteAttributeString("id", SRGSNonTerminalToRuleName(productionRule.NonTerminal));
            writer.WriteAttributeString("scope", "private");

            SRGSWriteReplacements(validReplacements);

            writer.WriteEndElement();
        }
示例#3
0
 /// <summary>
 /// Adds all the replacements in a homonime production rule to this instance
 /// </summary>
 /// <param name="pr">The production rule whose replacements will be added</param>
 public void AddReplacements(ProductionRule pr)
 {
     if (pr.NonTerminal != this.NonTerminal)
     {
         return;
     }
     foreach (string replacement in pr.replacements)
     {
         if (this.replacements.Contains(replacement))
         {
             continue;
         }
         this.replacements.Add(replacement);
     }
 }
示例#4
0
        /// <summary>
        /// Creates a ProductionRule object from a string
        /// </summary>
        /// <returns>A ProductionRule object.</returns>
        /// <param name="s">the string to analyze</param>
        public static ProductionRule FromString(string s)
        {
            Match m = rxRuleParser.Match(s);

            if (!m.Success)
            {
                return(null);
            }
            string         name = m.Result("${name}");
            string         prod = m.Result("${prod}");
            ProductionRule pr   = new ProductionRule(name);

            SplitProductions(prod, pr.replacements);
            return(pr);
        }
示例#5
0
            /// <summary>
            /// Expands the addressed production rule in a set of production rules.
            /// Expansion consists in spliting all parentheses and OR operators in a
            /// replacement into new production rules
            /// </summary>
            /// <param name="ix">The index of the rule to expand in the lsit of rules</param>
            /// <param name="ruleList">The set of production rules of the grammar with
            /// elements accessible by index in O(1).</param>
            /// <param name="ruleDicc">The set of production rules of the grammar with
            /// elements accessible by non-terminal symbol in O(1).</param>
            private static void ExpandRule(int ix, List <ProductionRule> ruleList, Dictionary <string, ProductionRule> ruleDicc)
            {
                if (ix >= ruleList.Count)
                {
                    return;
                }

                string         replacement;
                string         nonTerminal;
                int            nonTerminalBaseIndex = 0;
                ProductionRule pr = ruleList [ix];

                for (int i = 0; i < pr.Replacements.Count; ++i)
                {
                    replacement = pr.Replacements [i];
                    // Find open parenthesis within replacement
                    for (int cc = 0; cc < replacement.Length; ++cc)
                    {
                        if (replacement [cc] != '(')
                        {
                            continue;
                        }
                        // Open parenthesis was found!
                        // Increase reading header to the char at the right of the left par
                        int bcc = ++cc;
                        // and find the closing parenthesis
                        if (!ProductionRule.FindClosePar(replacement, ref cc))
                        {
                            break;
                        }
                        // Get the replacement (subchunk)
                        string subchunk = replacement.Substring(bcc, cc - bcc);
                        // Generate a Non-Terminal symbol (name) for the replacement
                        nonTerminal = GenerateNonTerminal(pr.NonTerminal, ref nonTerminalBaseIndex, ruleDicc);
                        // Create and add the production rule
                        ProductionRule cpr = ProductionRule.FromString(nonTerminal + " = " + subchunk);
                        ruleList.Add(cpr);
                        ruleDicc.Add(cpr.NonTerminal, cpr);
                        // Replace the subchunk with the Non-Terminal symbol
                        replacement         = replacement.Substring(0, bcc - 1) + nonTerminal + replacement.Substring(cc + 1);
                        pr.Replacements [i] = replacement;
                        cc = bcc + nonTerminal.Length - 2;
                    }
                }
            }
        private void SRGSWriteMainRule()
        {
            ProductionRule main = grammar.ProductionRules["$Main"];

            writer.WriteStartElement("rule");
            writer.WriteAttributeString("id", "main");
            writer.WriteAttributeString("scope", "public");

            writer.WriteStartElement("one-of");
            foreach (string replacement in main.Replacements)
            {
                SRGSWriteReplacement(replacement);
            }
            writer.WriteStartElement("item");
            SRGSWriteRuleRef("#_questions");
            writer.WriteEndElement();
            writer.WriteEndElement();

            writer.WriteEndElement();
        }
示例#7
0
            /// <summary>
            /// Parses a set of strings containing each a production rule, converting them into
            /// a non-terminal symbol addressable set of expanded production rules.
            /// </summary>
            private void ParseProductionRules()
            {
                ProductionRule pr;
                Dictionary <string, ProductionRule> prsd = grammar.productionRules;

                // prsd = new Dictionary<string, ProductionRule> ();
                foreach (string line in lines)
                {
                    pr = ProductionRule.FromString(line);
                    if ((pr == null) || (pr.Replacements.Count < 1))
                    {
                        continue;
                    }
                    if (prsd.ContainsKey(pr.NonTerminal))
                    {
                        prsd[pr.NonTerminal].AddReplacements(pr);
                    }
                    else
                    {
                        prsd.Add(pr.NonTerminal, pr);
                    }
                }
                ExpandRules(prsd);
            }
示例#8
0
            /// <summary>
            /// Imports production tules from another grammar file into a non-terminal
            /// </summary>
            /// <param name="directive">Specifies the import method used</param>
            /// <param name="nonTerminal">The non-terminal in which the grammar file will be imported</param>
            /// <param name="path">Path to the grammar file to be imported</param>
            /// be dumped</param>
            private void ImportSubGrammarIntoNT(string directive, string path, string nonTerminal)
            {
                if (String.IsNullOrEmpty(nonTerminal))
                {
                    ImportSubGrammar(directive, path, nonTerminal);
                    return;
                }
                if (directive != "import")
                {
                    return;
                }

                ProductionRule pr     = null;
                string         errMsg = "#ERROR! {void meta:{0}}";

                if (!File.Exists(path))
                {
                    errMsg = String.Format(errMsg, String.Format("File {0} not found", path));
                    pr     = new ProductionRule(nonTerminal, new String[] { errMsg });
                    if (grammar.productionRules.ContainsKey(nonTerminal))
                    {
                        grammar.productionRules[nonTerminal].AddReplacements(pr);
                    }
                    else
                    {
                        grammar.productionRules.Add(nonTerminal, pr);
                    }
                    return;
                }

                Grammar subGrammar = new GrammarLoader().FromFile(path, true);

                if (subGrammar == null)
                {
                    errMsg = String.Format(errMsg, String.Format("Cannot load grammar file {0}", path));
                    pr     = new ProductionRule(nonTerminal, new String[] { errMsg });
                    if (grammar.productionRules.ContainsKey(nonTerminal))
                    {
                        grammar.productionRules[nonTerminal].AddReplacements(pr);
                    }
                    else
                    {
                        grammar.productionRules.Add(nonTerminal, pr);
                    }
                    return;
                }

                errMsg = String.Format(errMsg, "Not implemented. Sorry =(");
                pr     = new ProductionRule(nonTerminal, new String[] { errMsg });
                if (grammar.productionRules.ContainsKey(nonTerminal))
                {
                    grammar.productionRules[nonTerminal].AddReplacements(pr);
                }
                else
                {
                    grammar.productionRules.Add(nonTerminal, pr);
                }

                // var main = subGrammar.productionRules["$Main"];
                // subGrammar.productionRules.Remove("$Main");
                // foreach(var item in subGrammar.productionRules){
                //  if(grammar.productionRules.ContainsKey(item.Key))
                //      grammar.productionRules[item.Key].AddReplacements(item.Value);
                //  else
                //      grammar.productionRules.Add(item.Key, item.Value);
                // }
            }