Пример #1
0
        public InCommentMulti(LanguageDef def)
            :
            base(
                inp =>
        {
            int depth = 1;
            while (depth > 0)
            {
                var res = Prim.String(def.CommentEnd).Parse(inp);
                if (!res.IsFaulted)
                {
                    depth--;
                    inp = res.Value.Head().Item2;
                    continue;
                }

                res = Prim.String(def.CommentStart).Parse(inp);
                if (!res.IsFaulted)
                {
                    depth++;
                    inp = res.Value.Head().Item2;
                    continue;
                }

                var resU = Prim.SkipMany(Prim.NoneOf(def.CommentStartEndDistinctChars.Value)).Parse(inp);
                if (resU.Value.Head().Item2.IsEmpty)
                {
                    return(Prim.Failure <Unit>(ParserError.Create("end of comment", inp)).Parse(inp));
                }
                inp = resU.Value.Head().Item2;
            }
            return(Prim.Return <Unit>(Unit.Default).Parse(inp));
        })
        {
        }
Пример #2
0
        public void TestFailure()
        {
            var inp = "abc".ToParserChar();

            var parser = Prim.Failure <bool>(ParserError.Create("failed because...", inp));

            var result = parser.Parse(inp);

            Assert.True(result.Value.IsEmpty);
        }
Пример #3
0
 public StringEscape()
     :
     base(
         inp =>
         Prim.Character('\\')
         .And(
             new EscapeGap().And(Prim.Failure <ParserChar>(ParserError.Create("", inp)))
             .Or(new EscapeEmpty().And(Prim.Failure <ParserChar>(ParserError.Create("", inp))))
             .Or(Tok.Chars.EscapeCode())
             )
         .Parse(inp)
         )
 {
 }
Пример #4
0
        public InCommentSingle(LanguageDef def)
            :
            base(
                inp =>
        {
            while (true)
            {
                var res = Prim.String(def.CommentEnd).Parse(inp);
                if (!res.IsFaulted)
                {
                    return(Prim.Return <Unit>(Unit.Default).Parse(res.Value.Head().Item2));
                }

                var resU = Prim.SkipMany(Prim.NoneOf(def.CommentStartEndDistinctChars.Value)).Parse(inp);
                if (resU.Value.Head().Item2.IsEmpty)
                {
                    return(Prim.Failure <Unit>(ParserError.Create("end of comment", inp)).Parse(inp));
                }
                inp = resU.Value.Head().Item2;
            }
        })
        {
        }
Пример #5
0
        public void TestChoice()
        {
            var r = Prim.Choice(Prim.Item(), Prim.Return(Prim.ParserChar('d'))).Parse("abc").Value.Single();

            Assert.True(
                r.Item1.Value == 'a' &&
                r.Item2.AsString() == "bc"
                );

            var inp = "abc".ToParserChar();

            var parser = Prim.Choice(
                Prim.Failure <ParserChar>(ParserError.Create("failed because...", inp)),
                Prim.Return(Prim.ParserChar('d'))
                )
                         .Parse(inp);

            r = parser.Value.Single();

            Assert.True(
                r.Item1.Value == 'd' &&
                r.Item2.AsString() == "abc"
                );
        }
Пример #6
0
        private static Parser <A> MakeParser <A>(IEnumerable <Operator <A> > ops, Parser <A> term)
        {
            var empty2 = ImmutableList.Empty <Parser <Func <A, A> > >();
            var empty3 = ImmutableList.Empty <Parser <Func <A, A, A> > >();

            return(ops.Foldr(
                       SplitOp,
                       Tuple.Create(empty3, empty3, empty3, empty2, empty2)
                       )
                   .Apply((rassoc, lassoc, nassoc, prefix, postfix) =>
            {
                var rassocOp = Prim.Choice(rassoc);
                var lassocOp = Prim.Choice(lassoc);
                var nassocOp = Prim.Choice(nassoc);
                var prefixOp = Prim.Choice(prefix).Fail("");
                var postfixOp = Prim.Choice(postfix).Fail("");

                Func <string, Choice <Func <A, A, A> >, Parser <A> > ambiguous = (string assoc, Choice <Func <A, A, A> > op) =>
                                                                                 Prim.Try <A>(
                    (from o in op
                     from fail in
                     Prim.Failure <A>(
                         ParserError.Create("ambiguous use of a " + assoc + " associative operator",
                                            new ParserChar(' ').Cons()
                                            ))
                     select fail)
                    );


                var ambiguousRight = ambiguous("right", rassocOp);
                var ambiguousLeft = ambiguous("left", lassocOp);
                var ambiguousNon = ambiguous("non", nassocOp);

                var postfixP = postfixOp | Prim.Return <Func <A, A> >(a => a);
                var prefixP = prefixOp | Prim.Return <Func <A, A> >(a => a);

                Parser <A> termP = from pre in prefixP
                                   from x in term
                                   from post in postfixP
                                   select(post(pre(x)));

                Func <A, Parser <A> > rassocP1 = null;

                Func <A, Parser <A> > rassocP = x => (from f in rassocOp
                                                      from y in
                                                      (from z in termP
                                                       from rz in rassocP1(z)
                                                       select rz)
                                                      select f(x, y))
                                                | ambiguousLeft
                                                | ambiguousNon;

                rassocP1 = x => rassocP(x) | Prim.Return(x);

                Func <A, Parser <A> > lassocP1 = null;

                Func <A, Parser <A> > lassocP = x => (from f in lassocOp
                                                      from y in termP
                                                      from l in lassocP1(f(x, y))
                                                      select l)
                                                | ambiguousRight;

                lassocP1 = x => (from l in lassocP(x)
                                 select l)
                           | Prim.Return(x);

                Func <A, Parser <A> > nassocP = x => (from f in nassocOp
                                                      from y in termP
                                                      from r in ambiguousRight
                                                      | ambiguousLeft
                                                      | ambiguousNon
                                                      | Prim.Return(f(x, y))
                                                      select r);

                return from x in termP
                from r in (rassocP(x) | lassocP(x) | nassocP(x) | Prim.Return(x)).Fail("operator")
                select r;
            }
                          ));
        }