private Parser <char, string> createParser(BasePattern pattern) { if (pattern == null) { throw new ArgumentNullException("pattern.", "Pattern is null when creating match parser."); } switch (pattern.Type) { case PatternType.Group: return(from vs in CharParsers.Sequence(((GroupPattern)pattern).Patterns .Select(p => createParser(p))) select vs.JoinStrings()); case PatternType.Quantifier: QuantifierPattern quant = (QuantifierPattern)pattern; return(from vs in CharParsers.Count(quant.MinOccurrences, quant.MaxOccurrences, createParser(quant.ChildPattern)) select vs.JoinStrings()); case PatternType.Alternation: return(CharParsers.Choice(((AlternationPattern)pattern).Alternatives .Select(p => createParser(p)) .ToArray())); case PatternType.String: return(CharParsers.String(((StringPattern)pattern).Value)); case PatternType.Char: return(from c in CharParsers.Satisfy(((CharPattern)pattern).IsMatch) select new string(c, 1)); default: throw new ApplicationException( string.Format("ExplicitDFAMatcher: unrecognized pattern type ({0}).", pattern.GetType().Name)); } }
protected override Result <char, Match2> Parse(ArrayConsList <char> consList, int afterLastMatchIndex) { BacktrackPoint lastBacktrackPoint = null; StackFrame callStack = new GroupStackFrame(null, Pattern); var partialResult = new Result <char, int>(0, consList); while (callStack != null) { if (callStack is QuantifierStackFrame) { QuantifierStackFrame quantStackFrame = (QuantifierStackFrame)callStack; if (quantStackFrame.IsPositionChanged(partialResult.Tree)) { lastBacktrackPoint = new BacktrackPoint(lastBacktrackPoint, quantStackFrame.SecondAlternative(partialResult.Tree), partialResult); callStack = quantStackFrame.FirstAlternative(partialResult.Tree); } else { callStack = quantStackFrame.Parent; } } else { BasePattern currentPattern = callStack.RemainingChildren.Head; if (currentPattern.MinCharLength > partialResult.Rest.Length) { partialResult = null; } else { callStack = ((GroupStackFrame)callStack).MoveToNextChild(); switch (currentPattern.Type) { case PatternType.Group: callStack = new GroupStackFrame(callStack, ((GroupPattern)currentPattern).Patterns); break; case PatternType.Quantifier: var quant = (QuantifierPattern)currentPattern; quant.AssertCanonicalForm(); if (quant.MinOccurrences == quant.MaxOccurrences) { callStack = new GroupStackFrame(callStack, new RepeaterConsList <BasePattern>(quant.ChildPattern, quant.MinOccurrences)); } else { callStack = new QuantifierStackFrame(callStack, quant); } break; case PatternType.Alternation: var alternatives = ((AlternationPattern)currentPattern).Alternatives; foreach (var alt in alternatives.Skip(1).Reverse()) { lastBacktrackPoint = new BacktrackPoint(lastBacktrackPoint, new GroupStackFrame(callStack, alt), partialResult); } callStack = new GroupStackFrame(callStack, alternatives.First()); break; case PatternType.Anchor: if (!doesAnchorMatch(((AnchorPattern)currentPattern).AnchorType, (ArrayConsList <char>)partialResult.Rest, afterLastMatchIndex)) { partialResult = null; } break; case PatternType.Char: partialResult = parseChar(partialResult, ((CharPattern)currentPattern).IsMatch); break; default: throw new ApplicationException( string.Format("BacktrackingMatcher: unrecognized pattern type ({0}).", currentPattern.GetType().Name)); } } if (partialResult == null) { if (lastBacktrackPoint != null) { callStack = lastBacktrackPoint.CallStack; partialResult = lastBacktrackPoint.PartialResult; lastBacktrackPoint = lastBacktrackPoint.Previous; } else { return(new Result <char, Match2>(Match2.Empty, consList)); } } } callStack = unwindEmptyFrames(callStack); } return(new Result <char, Match2>( new Match2(consList.ArrayIndex, partialResult.Tree, consList.AsEnumerable().Take(partialResult.Tree).AsString()), partialResult.Rest)); }