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)); }) { }
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); }
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) ) { }
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; } }) { }
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" ); }
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; } )); }