예제 #1
0
        public void TestRead()
        {
            SeekableStringReader s = new SeekableStringReader("hello");

            Assert.AreEqual('h', s.Read());
            Assert.AreEqual('e', s.Read());
            Assert.AreEqual("l", s.Read(1));
            Assert.AreEqual("lo", s.Read(2));
            Assert.Throws <IndexOutOfRangeException>(() => s.Read());
        }
예제 #2
0
        public void TestBookmark()
        {
            SeekableStringReader s = new SeekableStringReader("hello");

            s.Read(2);
            int bookmark = s.Bookmark();

            Assert.AreEqual("ll", s.Read(2));
            s.FlipBack(bookmark);
            Assert.AreEqual("ll", s.Read(2));
            Assert.AreEqual("o", s.Read(999));
        }
예제 #3
0
        public void TestRanges()
        {
            SeekableStringReader s = new SeekableStringReader("hello");

            Assert.Throws <ParseException>(() => s.Read(-1));
            Assert.AreEqual("hello", s.Read(999));
            Assert.Throws <ParseException>(() => s.Read(1));
            s.Rewind(int.MaxValue);
            Assert.IsTrue(s.HasMore());
            Assert.AreEqual("hello", s.Peek(999));
            Assert.IsTrue(s.HasMore());
        }
예제 #4
0
        public void TestNesting()
        {
            SeekableStringReader outer = new SeekableStringReader("hello!");

            outer.Read(1);
            SeekableStringReader inner1 = new SeekableStringReader(outer);
            SeekableStringReader inner2 = new SeekableStringReader(outer);

            Assert.AreEqual("ell", inner1.Read(3));
            Assert.AreEqual("el", inner2.Read(2));
            Assert.AreEqual("o", inner1.Read(1));
            Assert.AreEqual("l", inner2.Read(1));
            Assert.AreEqual("e", outer.Read(1));
            Assert.AreEqual("o", inner2.Read(1));
            Assert.AreEqual("l", outer.Read(1));
            outer.Sync(inner2);
            Assert.AreEqual("!", outer.Read(1));
        }
예제 #5
0
        public void TestContext()
        {
            SeekableStringReader s = new SeekableStringReader("abcdefghijklmnopqrstuvwxyz");

            s.Read(10);
            string left, right;

            s.Context(-1, 5, out left, out right);
            Assert.AreEqual("fghij", left);
            Assert.AreEqual("klmno", right);
            s.Context(-1, 12, out left, out right);
            Assert.AreEqual("abcdefghij", left);
            Assert.AreEqual("klmnopqrstuv", right);
            s.Read(13);
            s.Context(-1, 6, out left, out right);
            Assert.AreEqual("rstuvw", left);
            Assert.AreEqual("xyz", right);

            s.Context(5, 4, out left, out right);
            Assert.AreEqual("bcde", left);
            Assert.AreEqual("fghi", right);
        }
예제 #6
0
        public void TestStuff()
        {
            using (SeekableStringReader s = new SeekableStringReader("hello"))
            {
                Assert.AreEqual('h', s.Peek());
                Assert.AreEqual("hel", s.Peek(3));
                Assert.AreEqual('h', s.Read());
                Assert.AreEqual("ell", s.Read(3));
                Assert.AreEqual("o", s.Peek(999));
                Assert.AreEqual("o", s.Read(999));
            }

            using (SeekableStringReader s2 = new SeekableStringReader("    skip.\t\n\rwhitespace.  "))
            {
                s2.SkipWhitespace();
                Assert.AreEqual("skip", s2.ReadUntil('.'));
                s2.SkipWhitespace();
                Assert.AreEqual("whitespace", s2.ReadUntil('.'));
                s2.SkipWhitespace();
                Assert.IsFalse(s2.HasMore());
                Assert.Throws <IndexOutOfRangeException>(() => s2.Peek());
            }
        }
예제 #7
0
        public void TestReadUntil()
        {
            SeekableStringReader s = new SeekableStringReader("hello there");

            s.Read();
            Assert.AreEqual("ello", s.ReadUntil(' '));
            Assert.AreEqual('t', s.Peek());
            Assert.Throws <ParseException>(() => s.ReadUntil('x'));

            Assert.AreEqual("there", s.Rest());
            Assert.Throws <ParseException>(() => s.Rest());

            s.Rewind(int.MaxValue);
            Assert.AreEqual("hell", s.ReadUntil('x', 'y', 'z', ' ', 'o'));
            Assert.Throws <ParseException>(() => s.ReadUntil('x', 'y', '@'));
        }
예제 #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="rest"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        /// <exception cref="">InvalidSystemException</exception>
        public static string Parse(string rest, OutputFormat format)
        {
            SeekableReader reader  = new SeekableStringReader(rest);
            bool           success = System.Parse(reader, out System system);

            if (!success)
            {
                throw new InvalidSystemException("Could not parse as a system");
            }

            if (reader.Peek() != -1)
            {
                throw new InvalidSystemException($"Saw unexpected character: {(char)reader.Read()}");
            }

            return(system.ToString(format));
        }
예제 #9
0
            private VariableNode?ReadVariableNode(SeekableStringReader reader)
            {
                int start = reader.NextPosition;
                int c, len = 0;

                while ((c = reader.Peek()) > -1 && IsValidVariableChar(c, isFirstChar: len == 0))
                {
                    reader.Read();
                    len++;
                }

                if (len == 0)
                {
                    errorsSink.AddError(
                        "There is a variable with an empty or invalid name. The valid characters are 'a-zA-Z0-9_' and the first character cannot be a number.",
                        start);

                    return(null);
                }

                return(new VariableNode(pattern.Substring(start, len)));
            }
예제 #10
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);
            }