예제 #1
0
        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);
        }
예제 #2
0
        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;
        }