public static bool TryMatchExpr(ParserString parserString, out RegexTerm expr, out ParserString newParserString) { level++; expr = null; newParserString = null; char c; bool doneMatching; while (parserString.HasNext()) { doneMatching = false; c = parserString.Head; if (Char.IsWhiteSpace(c)) { parserString = parserString.Advance(1); continue; } // Match nested expr. if (c == '(') // Match expr nested in (). { if (!parserString.NextContains(')')) { return(false); } parserString = parserString.Advance(1); RegexTermGroup innerTerms = new RegexTermGroup(); while (TryMatchExpr(parserString, out RegexTerm innerTerm, out ParserString afterInnerTermString)) // Hopefully this consumes everything up to ')'. { innerTerms.Terms.Add(innerTerm); parserString = afterInnerTermString; } // Empty () is valid. It just won't do anything. while (parserString.HasNext()) // Loop over whitespace. { c = parserString.Head; if (Char.IsWhiteSpace(c)) // Skip whitespace. { parserString = parserString.Advance(1); continue; } if (c == ')') { // Might need to check for whitespace before quantifier. parserString = parserString.Advance(1); if (TryMatchQuantifier(parserString, out Quantifier quantifier, out ParserString afterQuantifierString)) { quantifier.SetTerm(innerTerms); expr = quantifier; parserString = afterQuantifierString; } else { expr = innerTerms; parserString = parserString.Advance(1); // Consume ')'. } doneMatching = true; } else // No matching ')' after a token or token and a quantifier. { return(false); } } if (!doneMatching) { return(false); } }
public Or(RegexTerm option1, RegexTerm option2) { Option1 = option1; Option2 = option2; }
public override void SetTerm(RegexTerm term) { RegexTerm = term; }
public CardinalQuantifier(Cardinality range, RegexTerm regexTerm) { Range = range; RegexTerm = regexTerm; }
public CharQuantifier(char m, RegexTerm term) { M = m; RegexTerm = term; }
public abstract void SetTerm(RegexTerm term);