private void ParseBNFEntry(string s, ref int x) { BNFEntry ret = new BNFEntry(); ParseBNFWhitespace(s, ref x); BNFEntryReference name = ParseBNFToken(s, ref x); ret.Name = name.Value; if (ret.Name.EndsWith(":")) { ret.Name = ret.Name.TrimEnd(':'); } else { ParseBNFWhitespace(s, ref x); if (!BNFMatch(s, ref x, ":")) { throw new Exception(); } } ParseBNFWhitespace(s, ref x); bool cont = true; List <BNFEntryReference> entries = new List <BNFEntryReference>(); while (cont) { BNFEntryReference entry = ParseBNFToken(s, ref x); entries.Add(entry); ParseBNFWhitespace(s, ref x); if (BNFMatch(s, ref x, ";")) { ret.Children.Add(entries.ToArray()); cont = false; ParseBNFWhitespace(s, ref x); } else if (BNFMatch(s, ref x, "|")) { ret.Children.Add(entries.ToArray()); entries = new List <BNFEntryReference>(); ParseBNFWhitespace(s, ref x); } } bnf_entries.Add(ret.Name, ret); }
private int ParseToken(IList <Preprocessor.token> tokens, int x, string bnf) { BNFEntry bne = bnf_entries[bnf]; System.Diagnostics.Debug.WriteLine("Testing position " + x.ToString() + " against " + bnf); int max_x = x; foreach (BNFEntryReference[] bnr in bne.Children) { int new_x = ParseToken(tokens, x, bnr); if (new_x > max_x) { max_x = new_x; } } if (max_x != x) { System.Diagnostics.Debug.WriteLine("Matched position " + x.ToString() + " against " + bnf); } return(max_x); }
private void RemoveImmediateLeftRecursion(BNFEntry e, Dictionary <string, BNFEntry> new_rules) { // First group the entries into those which begin with the current entry and those which do not List <BNFEntryReference[]> bce = new List <BNFEntryReference[]>(); List <BNFEntryReference[]> nbce = new List <BNFEntryReference[]>(); foreach (BNFEntryReference[] child in e.Children) { if ((child.Length > 0) && (child[0].Type == BNFEntryReference.type.EntryReference) && (child[0].Value == e.Name)) { bce.Add(child); } else { nbce.Add(child); } } // If none begin with the current entry then this entry is not left-recursive, therefore return if (bce.Count == 0) { new_rules.Add(e.Name, e); return; } // Create two new rules A and A_ BNFEntry A = new BNFEntry { Name = e.Name }; BNFEntry A_ = new BNFEntry { Name = e.Name + "_" }; // Set A-> nbce[0]A_ | nbce[1]A_ | nbce[2]A_ ... foreach (BNFEntryReference[] nbce_i in nbce) { List <BNFEntryReference> new_nbce_i = new List <BNFEntryReference>(nbce_i); new_nbce_i.Add(new BNFEntryReference { Type = BNFEntryReference.type.EntryReference, Value = A_.Name }); A.Children.Add(new_nbce_i.ToArray()); } // Set A_-> empty | bce[0]A_ | bce[1]A_ ... A_.Children.Add(new BNFEntryReference[] { new BNFEntryReference { Type = BNFEntryReference.type.Empty } }); foreach (BNFEntryReference[] bce_i in bce) { List <BNFEntryReference> new_bce_i = new List <BNFEntryReference>(bce_i); // Trim the 'current entry' from the start of the current list new_bce_i.RemoveAt(0); new_bce_i.Add(new BNFEntryReference { Type = BNFEntryReference.type.EntryReference, Value = A_.Name }); A_.Children.Add(new_bce_i.ToArray()); } new_rules.Add(A.Name, A); new_rules.Add(A_.Name, A_); }