예제 #1
0
 public OrdinalityPatternMatcher(Ordinality ordinality, IEnumerable <PatternMatcher> patternMatchers, int maxMatches = Byte.MaxValue)
 {
     this.MaxMatches = maxMatches;
     this.Ordinality = ordinality;
     PatternMatchers.AddRange(patternMatchers.OrderBy(p => p.ContainsWildcard()));
 }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="pattern">pattern to parse</param>
        /// <returns></returns>
        public PatternMatcher Parse(string pattern, bool defaultFuzzyMatch = false, Ordinality ordinality = Ordinality.One, int maxMatches = 16)
        {
            OrdinalityPatternMatcher ordinalityPatternMatcher = new OrdinalityPatternMatcher(ordinality, maxMatches);
            SequencePatternMatcher   sequence = new SequencePatternMatcher();
            StringBuilder            sb       = new StringBuilder();
            var fuzzyMatch = defaultFuzzyMatch;
            var chars      = pattern.GetEnumerator();

            while (chars.MoveNext())
            {
                char ch = chars.Current;
                bool repeatChar;
                do
                {
                    repeatChar = false;

                    switch (ch)
                    {
                    case '(':
                        Ordinality modifierOrdinality = Ordinality.One;
                        AddTextToSequence(sequence, sb, fuzzyMatch);

                        var subText = GetPatternGroup(chars).Trim();

                        bool inModifiers = true;
                        while (inModifiers && chars.MoveNext())
                        {
                            ch = chars.Current;
                            switch (ch)
                            {
                            case '~':
                                fuzzyMatch = !defaultFuzzyMatch;
                                break;

                            case '?':
                                modifierOrdinality = Ordinality.ZeroOrOne;
                                break;

                            case '+':
                                modifierOrdinality = Ordinality.OneOrMore;
                                break;

                            case '*':
                                modifierOrdinality = Ordinality.ZeroOrMore;
                                break;

                            default:
                                if (byte.TryParse(ch.ToString(), out byte num))
                                {
                                    maxMatches = num;
                                }
                                else
                                {
                                    var patternMatcher = Parse(subText, fuzzyMatch, modifierOrdinality, maxMatches);
                                    sequence.PatternMatchers.Add(patternMatcher);

                                    // break out of modifier loop
                                    inModifiers = false;
                                    repeatChar  = true;
                                }
                                break;
                            }
                        }
                        if (inModifiers)
                        {
                            // paren was end of string.
                            var patternMatcher = Parse(subText, fuzzyMatch, modifierOrdinality, maxMatches);
                            sequence.PatternMatchers.Add(patternMatcher);
                        }
                        maxMatches = 16;
                        fuzzyMatch = defaultFuzzyMatch;
                        break;

                    case '|':
                    {
                        AddTextToSequence(sequence, sb, fuzzyMatch);
                        if (sequence.PatternMatchers.Count == 1)
                        {
                            ordinalityPatternMatcher.PatternMatchers.Add(sequence.PatternMatchers.Single());
                        }
                        else
                        {
                            ordinalityPatternMatcher.PatternMatchers.Add(sequence);
                        }
                        sequence = new SequencePatternMatcher();
                    }
                    break;

                    default:
                        sb.Append(ch);
                        break;
                    }
                } while (repeatChar);
            }

            AddTextToSequence(sequence, sb, fuzzyMatch);

            if (sequence.PatternMatchers.Any())
            {
                if (sequence.PatternMatchers.Count == 1)
                {
                    ordinalityPatternMatcher.PatternMatchers.Add(sequence.PatternMatchers.Single());
                }
                else
                {
                    ordinalityPatternMatcher.PatternMatchers.Add(sequence);
                }
            }

            // if this is a oneOf, maxMatches with a single pattern matcher, just the inner patternmatcher.
            PatternMatcher result = ordinalityPatternMatcher;

            if (ordinalityPatternMatcher.PatternMatchers.Count == 1 && ordinalityPatternMatcher.Ordinality == Ordinality.One)
            {
                result = ordinalityPatternMatcher.PatternMatchers.Single();
            }

            // if it is a sequence with only one patternMatcher, just the inner patternmatcher
            if (result is SequencePatternMatcher spm && spm.PatternMatchers.Count == 1)
            {
                result = spm.PatternMatchers.Single();
            }

            return(result);
        }
예제 #3
0
 public OrdinalityPatternMatcher(Ordinality ordinality, int maxMatches = Byte.MaxValue)
 {
     this.MaxMatches = maxMatches;
     this.Ordinality = ordinality;
 }