public void LexerTest() { Parser <Term> exprlazy = null; Parser <Term> expr = Prim.Lazy <Term>(() => exprlazy); Func <Parser <Term>, Parser <Term> > contents; Func <Parser <Term>, Parser <ImmutableList <Term> > > many = Prim.Many; Func <Parser <Term>, Parser <Term> > @try = Prim.Try; var def = new Lang(); var lexer = Tok.MakeTokenParser <Term>(def); var binops = BuildOperatorsTable <Term>(lexer); // Lexer var intlex = lexer.Integer; var floatlex = lexer.Float; var parens = lexer.Parens; var commaSep = lexer.CommaSep; var semiSep = lexer.SemiSep; var identifier = lexer.Identifier; var reserved = lexer.Reserved; var reservedOp = lexer.ReservedOp; var whiteSpace = lexer.WhiteSpace; // Parser var integer = from n in intlex select new Integer(n) as Term; var variable = from v in identifier select new Var(v) as Term; var manyargs = parens(from ts in many(variable) select new Arguments(ts) as Term); var commaSepExpr = parens(from cs in commaSep(expr) select new Exprs(cs) as Term); var function = from _ in reserved("def") from name in identifier from args in manyargs from body in expr select new Function(name, args, body) as Term; var externFn = from _ in reserved("extern") from name in identifier from args in manyargs select new Extern(name, args) as Term; var call = from name in identifier from args in commaSepExpr select new Call(name, args as Exprs) as Term; var subexpr = (from p in parens(expr) select new Expression(p) as Term); var factor = from f in @try(integer) | @try(externFn) | @try(function) | @try(call) | @try(variable) | subexpr select f; var defn = from f in @try(externFn) | @try(function) | @try(expr) select f; contents = p => from ws in whiteSpace from r in p select r; var toplevel = from ts in many( from fn in defn from semi in reservedOp(";") select fn ) select ts; exprlazy = Ex.BuildExpressionParser <Term>(binops, factor); var watch = Stopwatch.StartNew(); var result = toplevel.Parse(TestData4); watch.Stop(); var time = watch.ElapsedMilliseconds; if (result.IsFaulted) { string errs = System.String.Join("\n", result.Errors.Select(e => e.Message + "Expected " + e.Expected + " at " + e.Location + " - " + e.Input.AsString().Substring(0, Math.Min(30, e.Input.AsString().Length)) + "...") ); Console.WriteLine(errs); } var resu = result.Value.First().Item1; var left = result.Value.First().Item2.AsString(); Assert.True(left.Length == 0); Assert.True(!result.IsFaulted); }
public void BuildScrapeQLParser() { var def = new ScrapeQLDef(); var lexer = Tok.MakeTokenParser <Term>(def); var reserved = lexer.Reserved; var identifier = lexer.Identifier; var strings = lexer.StringLiteral; var ParserComma = from _ in Prim.WhiteSpace() from c in Prim.Character(',') from __ in Prim.WhiteSpace() select c; var ParserRegularExpression = (from b in Prim.Character('\\') from r in Prim.Character('r') from re in strings select new RegularExpression(re.Value.AsString())) .Fail("Regex"); var ParserListLiteralStringToken = (from strs in Prim.SepBy( strings, ParserComma ) select strs); var ParserListIdentifierToken = (from strs in Prim.SepBy( identifier, ParserComma ) select strs); /*ParserKeyPair = (from left in ParserString * from c in Prim.Character(':') * from right in ParserString * select Tuple.Create(left, right)) * .Fail("tuple"); * * ParserDictionary = (from ps in Prim.SepBy1(ParserKeyPair, Prim.Character(',')) * select ps) * .Fail("dictionary");*/ var ParserLoadQuery = from _ in reserved("LOAD") from sources in ParserListLiteralStringToken from __ in reserved("AS") from aliases in ParserListIdentifierToken select new LoadQuery(aliases, sources, _.Location) as Query; var ParserWriteQuery = from _ in reserved("WRITE") from alias in identifier from __ in reserved("TO") from src in strings select new WriteQuery(alias, src, _.Location) as Query; var ParserStringSelector = from s in strings select new SelectorString(s, s.Location) as Selector; var ParserAttributeSelector = from src in identifier from xpath in Prim.Between(Prim.Character('['), Prim.Character(']'), strings) select new AttributeSelector(src, xpath, src.Location) as Selector; var Conditional = from sq in reserved("TO") select sq; //TODO: Conditions var ParserWhereExpression = from _ in reserved("WHERE") from clauses in Prim.Many1(Conditional) select new WhereExpression() as Term; //TODO: Return enumarable conditions var ParserSelectQuery = from _ in reserved("SELECT") from selector in Prim.Choice(ParserStringSelector, ParserAttributeSelector) from __ in reserved("AS") from alias in identifier from ___ in reserved("FROM") from src in identifier from whereClasuses in Prim.Try(ParserWhereExpression) select new SelectQuery(selector, alias, src, _.Location) as Query; TopLevel = Prim.Choice(ParserLoadQuery, ParserSelectQuery, ParserWriteQuery); TopLevelMany = from ts in Prim.Many1( from lq in TopLevel select lq ) select ts; }