コード例 #1
0
        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));
            }
        }
コード例 #2
0
        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));
        }