コード例 #1
0
            private PatternNode?ReadNode(SeekableStringReader reader, char?stopChar = null)
            {
                PatternNode?node = null;
                int         c, len, start;

                Reset();

                void Reset()
                {
                    len   = 0;
                    start = reader.NextPosition;
                }

                PatternNode?AppendMatch(string pattern)
                {
                    if (len > 0)
                    {
                        node += new MatchNode(pattern.Substring(start, len));
                    }

                    return(node);
                }

                while ((c = reader.Read()) > -1)
                {
                    if (c == stopChar)
                    {
                        return(AppendMatch(pattern));
                    }

                    PatternNode?next;
                    switch (c)
                    {
                    case Constants.Slash:
                        next = SegmentStartNode.Instance;
                        break;

                    case Constants.Wildcard:
                        next = WildcardNode.Instance;
                        break;

                    case Constants.VariableStart:
                        next = ReadVariableNode(reader);
                        break;

                    case Constants.OptionalStart:
                        next = ReadOptionalNode(reader);
                        break;

                    case Constants.OptionalEnd:
                        errorsSink.AddError($"There is an unexpected '{(char)c}'.", reader.NextPosition - 1);
                        return(null);

                    case Constants.EscapeSequenceStart:
                        if (!ShouldEscape(reader))
                        {
                            len++;
                            continue;
                        }

                        AppendMatch(pattern);
                        reader.NextPosition += Constants.EscapeSequence.Length;
                        start = reader.NextPosition - 1;
                        len   = 1;
                        continue;

                    default:
                        len++;
                        continue;
                    }

                    // failed to parse!
                    if (next is null)
                    {
                        return(null);
                    }

                    if (len > 0)
                    {
                        node += new MatchNode(pattern.Substring(start, len));
                    }

                    node += next;
                    Reset();
                }

                // expected an end char but didn't find it
                if (stopChar.HasValue)
                {
                    errorsSink.AddError($"There is a missing '{stopChar}'.");
                    return(null);
                }

                node += len == 0
                    ? MatchNode.Empty
                    : new MatchNode(pattern.Substring(reader.NextPosition - len, len));

                return(node);
            }
コード例 #2
0
 internal PatternNode?Parse()
 {
     using (var reader = new SeekableStringReader(pattern))
         return(ReadNode(reader));
 }