Beispiel #1
0
        public IEnumerable <Match2> GetMatches(string inputText)
        {
            ArrayConsList <char> consList = new ArrayConsList <char>(inputText);

            int index = 0, afterLastMatchIndex = 0;

            while (index <= inputText.Length)
            {
                Result <char, Match2> result = Parse(consList, afterLastMatchIndex);

                if (result.Tree.Success)
                {
                    yield return(result.Tree);

                    if (result.Tree.Length > 0)
                    {
                        consList            = (ArrayConsList <char>)result.Rest;
                        index              += result.Tree.Length;
                        afterLastMatchIndex = index;
                        continue;
                    }
                }

                if (!consList.IsEmpty)
                {
                    consList = (ArrayConsList <char>)consList.Tail;
                }

                index++;
            }
        }
Beispiel #2
0
        public IEnumerable<Match2> GetMatches(string inputText)
        {
            ArrayConsList<char> consList = new ArrayConsList<char>(inputText);

            int index = 0, afterLastMatchIndex = 0;

            while (index <= inputText.Length)
            {
                Result<char, Match2> result = Parse(consList, afterLastMatchIndex);

                if (result.Tree.Success)
                {
                    yield return result.Tree;

                    if (result.Tree.Length > 0)
                    {
                        consList = (ArrayConsList<char>)result.Rest;
                        index += result.Tree.Length;
                        afterLastMatchIndex = index;
                        continue;
                    }
                }

                if (!consList.IsEmpty)
                    consList = (ArrayConsList<char>)consList.Tail;

                index++;
            }
        }
        public static void CharParserTest <TTree>(Parser <char, TTree> parser, int times, int maxItemCount, string inputText)
        {
            IConsList <char> consList = new ArrayConsList <char>(inputText);

            DateTime start = DateTime.Now;

            IConsList <char> rest = null;

            for (int i = 0; i < times; i++)
            {
                Result <char, TTree> result = parser(consList);

                while (result != null)
                {
                    rest   = result.Rest;
                    result = parser(result.Rest);
                }
            }

            if (rest != null && !rest.IsEmpty)
            {
                Console.WriteLine("The remaining list is NOT empty.\n");
            }

            TimeSpan time         = DateTime.Now - start;
            TimeSpan timePerCycle = new TimeSpan(0, 0, 0, 0, (int)(time.TotalMilliseconds / times));

            Console.WriteLine(time);
            Console.WriteLine();
            //Console.WriteLine("{0}  per cycle", timePerCycle);
            //Console.WriteLine();
        }
        protected override Result<char, Match2> Parse(ArrayConsList<char> consList, int afterLastMatchIndex)
        {
            Result<char, string> result = Parser(consList);

            if (result != null)
                return new Result<char, Match2>(
                                new Match2(consList.ArrayIndex, result.Tree.Length, result.Tree),
                                result.Rest);
            else
                return new Result<char, Match2>(Match2.Empty, consList);
        }
        protected override Result <char, Match2> Parse(ArrayConsList <char> consList, int afterLastMatchIndex)
        {
            Result <char, string> result = Parser(consList);

            if (result != null)
            {
                return(new Result <char, Match2>(
                           new Match2(consList.ArrayIndex, result.Tree.Length, result.Tree),
                           result.Rest));
            }
            else
            {
                return(new Result <char, Match2>(Match2.Empty, consList));
            }
        }
Beispiel #6
0
        private bool doesAnchorMatch(AnchorType anchorType, ArrayConsList <char> currentPos, int afterLastMatchIndex)
        {
            switch (anchorType)
            {
            case AnchorType.StartOfString:
                return(currentPos.IsStartOfArray);

            case AnchorType.StartOfLine:
                return(currentPos.IsStartOfArray || currentPos.Prev == '\n');


            case AnchorType.EndOfString:
                return(currentPos.IsEmpty);

            case AnchorType.EndOfLine:
                return(currentPos.IsEmpty || currentPos.Head == '\n');

            case AnchorType.EndOfStringOrBeforeEndingNewline:
                return(currentPos.DropWhile(c => c == '\n').IsEmpty);


            case AnchorType.ContiguousMatch:
                return(currentPos.ArrayIndex == afterLastMatchIndex);

            case AnchorType.WordBoundary:
                return(isWordBoundary(currentPos));

            case AnchorType.NonWordBoundary:
                return(!isWordBoundary(currentPos));


            default:
                throw new ApplicationException(
                          string.Format("BacktrackingMatcher: illegal anchor type ({0}).",
                                        anchorType.ToString()));
            }
        }
Beispiel #7
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));
        }
Beispiel #8
0
 private bool isWordBoundary(ArrayConsList <char> currentPos)
 {
     return((!currentPos.IsStartOfArray && CharGroupPattern.WordChar.IsMatch(currentPos.Prev)) ^
            (!currentPos.IsEmpty && CharGroupPattern.WordChar.IsMatch(currentPos.Head)));
 }
Beispiel #9
0
 protected abstract Result<char, Match2> Parse(ArrayConsList<char> consList, int afterLastMatchIndex);
        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);
        }
 private bool isWordBoundary(ArrayConsList<char> currentPos)
 {
     return (!currentPos.IsStartOfArray && CharGroupPattern.WordChar.IsMatch(currentPos.Prev)) ^
            (!currentPos.IsEmpty && CharGroupPattern.WordChar.IsMatch(currentPos.Head));
 }
        private bool doesAnchorMatch(AnchorType anchorType, ArrayConsList<char> currentPos, int afterLastMatchIndex)
        {
            switch (anchorType)
            {
                case AnchorType.StartOfString:
                    return currentPos.IsStartOfArray;

                case AnchorType.StartOfLine:
                    return currentPos.IsStartOfArray || currentPos.Prev == '\n';

                case AnchorType.EndOfString:
                    return currentPos.IsEmpty;

                case AnchorType.EndOfLine:
                    return currentPos.IsEmpty || currentPos.Head == '\n';

                case AnchorType.EndOfStringOrBeforeEndingNewline:
                    return currentPos.DropWhile(c => c == '\n').IsEmpty;

                case AnchorType.ContiguousMatch:
                    return currentPos.ArrayIndex == afterLastMatchIndex;

                case AnchorType.WordBoundary:
                    return isWordBoundary(currentPos);

                case AnchorType.NonWordBoundary:
                    return !isWordBoundary(currentPos);

                default:
                    throw new ApplicationException(
                        string.Format("BacktrackingMatcher: illegal anchor type ({0}).",
                                      anchorType.ToString()));
            }
        }
Beispiel #13
0
 protected abstract Result <char, Match2> Parse(ArrayConsList <char> consList, int afterLastMatchIndex);
 protected override Result <char, Match2> Parse(ArrayConsList <char> consList, int afterLastMatchIndex)
 {
     return(new Result <char, Match2>(Match2.Empty, consList));
 }
 protected override Result<char, Match2> Parse(ArrayConsList<char> consList, int afterLastMatchIndex)
 {
     return new Result<char, Match2>(Match2.Empty, consList);
 }