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