Esempio n. 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);
        }