protected EmptyParser(EmptyParser other, ParserCloneArgs args) : base(other, args) { }
void FixRecursiveGrammars() { var empty = new EmptyParser(); var alternates = Children.OfType <AlternativeParser>(); var first = new List <Parser>(); var second = new List <Parser>(); foreach (var alt in alternates.Distinct().ToList()) { first.Clear(); second.Clear(); Parser separator = null; for (int i = 0; i < alt.Items.Count; i++) { Parser item = alt.Items[i]; if (item != null && item.IsLeftRecursive(alt)) { var seqs = item.Scan(filter: p => { if (ReferenceEquals(p, alt)) { return(false); } if (p is SequenceParser seq && seq.Items.Count > 0 && seq.Items[0].IsLeftRecursive(alt)) { seq.Items[0] = empty; return(true); } return(false); }).OfType <SequenceParser>(); foreach (var seq in seqs) { separator = seq.Separator; seq.Items.RemoveAt(0); } if (!item.IsLeftRecursive(alt)) { second.Add(item); } else { Debug.WriteLine(string.Format("Warning: Item in alternate is still recursive {0}", item.DescriptiveName)); } } else { first.Add(item); } } if (second.Count > 0) { Debug.WriteLine(string.Format("Fixing recursion in alternate: {0}", alt.DescriptiveName)); alt.Items.Clear(); var secondParser = second.Count > 1 ? new AlternativeParser(second) : second[0]; if (first.Count > 0) { var firstParser = first.Count > 1 ? new AlternativeParser(first) : first[0]; var repeat = new RepeatParser(secondParser, 0) { Separator = separator }; if (first.Count == 1 && first[0] == null) { alt.Items.Add(repeat); } else { alt.Items.Add(new SequenceParser(firstParser, repeat) { Separator = separator }); } } else { alt.Items.Add(new RepeatParser(secondParser, 1) { Separator = separator }); } } } }
private bool Accept <TInput>(EmptyParser <TInput> p, BnfStringifyVisitor state) { state.Append("()"); return(true); }