Пример #1
0
 public static Parser <char, T> Next <T>(Parser <char, T> parser)
 {
     return
         (SkipWhitespaces
          .Then(Try(CommentParser.SkipBlockComment(String("/*"), String("*/"))
                    .Or(CommentParser.SkipLineComment(String("//")))).Optional()
                .Then(SkipWhitespaces))
          .Then(parser));
 }
Пример #2
0
        public static string ParseTomlComment(string input)
        {
            // Build parser
            Parser <char, char>   hash    = Char('#');
            Parser <char, string> comment = hash
                                            .Then(SkipWhitespaces.Then(AnyCharExcept('\r', '\n').ManyString()));

            // Parse
            var output = comment.ParseOrThrow(input);

            return(output);
        }
Пример #3
0
        private void InitScripts()
        {
            Input =
                from t in Path.Before(Whitespace.AtLeastOnce())
                from n in Name
                select new StringInput()
            {
                Type = t, Name = n
            };

            Script =
                from v in OneOf(Try(Public.ThenReturn(true)), Try(Private.ThenReturn(false))).Before(Whitespace.AtLeastOnce()).Optional()
                from t in Path.Before(Whitespace.AtLeastOnce())
                from n in Name.Before(SkipWhitespaces)
                from i in Input.Separated(Comma.Between(SkipWhitespaces)).Between(OpenParenthesis, CloseParenthesis)
                from cs in Block(SkipWhitespaces.Then(Lines))
                select new StringScript()
            {
                IsPublic = v.GetValueOrDefault(false), ReturnType = t, Name = n, Inputs = i, Commands = cs
            } as StringChild;
        }
Пример #4
0
        /// <summary>
        /// Creates and initializes a new <see cref="CommandCompiler"/>.
        /// </summary>
        public CommandCompiler()
        {
            CommentHead      = String("//");
            LiteralMarker    = Char('#');
            CharMarker       = Char('\'');
            StringMarker     = Char('\"');
            AddressMarker    = Char('$');
            DirectiveMarker  = Char('.');
            ReferenceMarker  = Char('?');
            AnyCommandMarker = OneOf(LiteralMarker, AddressMarker, ReferenceMarker);
            EnumStart        = Char('{');
            EnumEnd          = Char('}');
            ExceptEndLine    = AnyCharExcept('\r', '\n');

            TrueString  = String("true");
            FalseString = String("false");
            NullString  = String("null");

            ReservedCommandNames = new string[]
            {
                "Define",
                "Var",
                "Constant"
            };

            NumLiteral =
                from l in CurrentPos
                from n in LiteralMarker.Then(Digit.Or(Char('.')).Or(Char('-')).ManyString())
                select new ValueToken()
            {
                Value = n, Type = ValueType.Immediate, Position = l
            };

            CharLiteral =
                from l in CurrentPos
                from c in Any.Between(CharMarker)
                select new ValueToken()
            {
                Value = c.ToString(), Type = ValueType.Immediate, Position = l
            };

            StringLiteral =
                from l in CurrentPos
                from c in AnyCharExcept('\"').ManyString().Between(StringMarker)
                select new ValueToken()
            {
                Value = c.ToString(), Type = ValueType.Immediate, Position = l
            };

            BoolLiteral =
                from l in CurrentPos
                from b in OneOf(Try(TrueString), FalseString)
                select new ValueToken()
            {
                Value = b, Type = ValueType.Immediate, Position = l
            };

            EnumLiteral =
                from l in CurrentPos
                from e in LetterOrDigit.ManyString().Between(EnumStart, EnumEnd)
                select new ValueToken()
            {
                Value = e, Type = ValueType.Immediate, Position = l
            };

            NullLiteral =
                from l in CurrentPos
                from n in NullString
                select new ValueToken()
            {
                Value = string.Empty, Type = ValueType.Immediate, Position = l
            };

            Address =
                from l in CurrentPos
                from a in AddressMarker
                from n in Num
                select new ValueToken()
            {
                Value = n.ToString(), Type = ValueType.Address, Position = l
            };

            Directive =
                from l in CurrentPos
                from d in DirectiveMarker
                from n in LetterOrDigit.Or(DirectiveMarker).ManyString()
                select new ValueToken()
            {
                Value = n, Type = ValueType.Directive, Position = l
            };

            Reference =
                from l in CurrentPos
                from r in ReferenceMarker
                from n in LetterOrDigit.Or(DirectiveMarker).ManyString()
                select new ValueToken()
            {
                Value = n, Type = ValueType.Reference, Position = l
            };

            Value = OneOf(
                NumLiteral.Labelled("number"),
                CharLiteral.Labelled("char"),
                StringLiteral.Labelled("string"),
                EnumLiteral.Labelled("enum"),
                Try(BoolLiteral).Labelled("bool"),
                Try(NullLiteral).Labelled("null"),
                Address.Labelled("address"),
                Directive.Labelled("directive"),
                Reference.Labelled("reference"));

            CompilerCommand =
                from l in CurrentPos
                from c in LetterOrDigit.AtLeastOnceString().Where(n => ReservedCommandNames.Contains(n)).Labelled("reserved command")
                from v in Try(SkipWhitespaces.Then(Value)).Many()
                select new CommandCall()
            {
                Name     = c,
                Inputs   = v.ToArray(),
                Type     = CallType.Compiler,
                Position = l
            };

            CallCommand =
                from l in CurrentPos
                from c in LetterOrDigit.Or(AnyCommandMarker).AtLeastOnceString().Where(n => KnownCommandNames.Contains(n)).Labelled("known command")
                from v in Try(SkipWhitespaces.Then(Value)).Many()
                select new CommandCall()
            {
                Name     = c,
                Inputs   = v.ToArray(),
                Type     = CallType.Command,
                Position = l
            };

            Command = OneOf(Try(CompilerCommand).Labelled("compiler call"), CallCommand.Labelled("command call"));
            Code    = OneOf(
                Try(CommentHead.Then(ExceptEndLine.SkipMany())).ThenReturn <CommandCall?>(null).Labelled("comment"),
                Command.Select <CommandCall?>(c => c))
                      .SeparatedAndOptionallyTerminatedAtLeastOnce(SkipWhitespaces);
        }
Пример #5
0
        private static Tuple <Parser <char, Expr>, Stack <bool>, Stack <bool> > BuildExprParser()
        {
            Parser <char, Expr> exprParser = null;

            var listParser = Rec(() => exprParser).Separated(Comma.Before(SkipWhitespaces));
            var funcHead   = Id.Or(If).Between(SkipWhitespaces).Before(LParen.Between(SkipWhitespaces));
            var funcParser = Try(Lookahead(funcHead)).Then(Map((id, prms) => (Expr) new Function(id, prms), funcHead,
                                                               listParser.Before(RParen))).Labelled("func");
            var termParser = funcParser
                             .Or(Try(Bool.Select <Expr>(x => new BoolLit(x)))
                                 .Or(Num.Select <Expr>(x => new NumLit(x)))
                                 .Or(Str.Select <Expr>(x => new StringLit(x)))
                                 .Or(Chr.Select <Expr>(x => new CharLit(x)))
                                 .Or(Id.Select <Expr>(x => new Identifier(x)))
                                 .Or(Rec(() => listParser)
                                     .Between(LBrace.Then(SkipWhitespaces), SkipWhitespaces.Then(RBrace))
                                     .Select <Expr>(x => new Membership(x)))
                                 .Or(Rec(() => exprParser)
                                     .Between(LParen.Then(SkipWhitespaces), SkipWhitespaces.Then(RParen))
                                     .Select <Expr>(x => new Nested(x)))
                                 ).Labelled("term")
                             .Between(SkipWhitespaces.Or(End()));
            var cTerStack  = new Stack <bool>();
            var pyTerStack = new Stack <bool>();

            exprParser = ExpressionParser.Build(termParser, new[]
            {
                // arithmatic
                new[] {
                    Operator.Prefix(Char('+').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr> >(x => new Positive(x)))),
                    Operator.Prefix(Char('-').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr> >(x => new Negative(x)))),
                },
                new[] {
                    Operator.InfixR(Char('^').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Power(x, y)))),
                },
                new[] {
                    Operator.InfixL(Char('*').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Mult(x, y)))),
                    Operator.InfixL(Char('/').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Div(x, y)))),
                },
                new[] {
                    Operator.InfixL(Char('%').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Mod(x, y)))),
                },
                new[] {
                    Operator.InfixL(Char('+').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Plus(x, y)))),
                    Operator.InfixL(Char('-').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Minus(x, y)))),
                },
                new[] { // VB string cat
                    Operator.InfixL(Try(Lookahead(Not(Char('&').Before(Char('&'))))).Then(Char('&').Between(SkipWhitespaces)).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Cat(x, y)))),
                },
                new[] {
                    Operator.InfixL(Try(Lookahead(String("??"))).Then(String("??").Between(SkipWhitespaces)).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new NullCoalesce(x, y)))),
                },
                // comparision. TODO: check how to separate arithmatic, comparison and logical ops
                new[] {
                    Operator.InfixL(Try(String(">=").Between(SkipWhitespaces)).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Ge(x, y)))),
                    Operator.InfixL(Try(String("<=").Between(SkipWhitespaces)).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Le(x, y)))),
                    Operator.InfixL(Try(String("<>").Between(SkipWhitespaces)).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Ne("<>", x, y)))),
                    Operator.InfixL(String("!=").Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Ne(x, y)))),
                    Operator.InfixL(String(">").Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Gt(x, y)))),
                    Operator.InfixL(String("<").Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Lt(x, y)))),
                    Operator.InfixL(Try(String("==")).Or(String("=")).Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Eq(x, y)))),
                    Operator.InfixL(Try(String("in").Between(SkipWhitespaces).Before(Lookahead(LBrace))).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new In(x, y)))),
                },
                // logical. TODO: check how to separate arithmatic, comparison and logical ops
                new[] {
                    Operator.Prefix(Char('!').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr> >(x => new Not(x)))),
                },
                new[] {
                    Operator.InfixL(String("&&").Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new And(x, y)))),
                },
                new[] {
                    Operator.InfixL(String("||").Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Or(x, y)))),
                },
                new[] {
                    Operator.InfixR(If.Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) =>
                    {
                        if (pyTerStack.Count == 0)
                        {
                            throw new InvalidOperationException("Unbalanced Python-style Ternary Operators, fewer 'else' parts than 'then' parts");
                        }
                        pyTerStack.Pop();
                        return(TerUtils.FormPyTerExpr(x, y));
                    }))),
                    Operator.InfixR(Else.Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) =>
                    {
                        pyTerStack.Push(true);
                        return(new PyTerExprElse(x, y));
                    }))),
                    Operator.InfixR(Try(Lookahead(Not(Char('?').Before(Char('?'))))).Then(Char('?').Between(SkipWhitespaces)).Then(Return <Func <Expr, Expr, Expr> >((x, y) =>
                    {
                        if (cTerStack.Count == 0)
                        {
                            throw new InvalidOperationException("Unbalanced C-style Ternary Operators, fewer 'else' parts than 'then' parts");
                        }
                        cTerStack.Pop();
                        return(TerUtils.FormCTerExpr(x, y));
                    }))),
                    Operator.InfixR(Char(':').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) =>
                    {
                        cTerStack.Push(true);
                        return(new CTerElseExpr(x, y));
                    }))),
                },
            });
            return(Tuple.Create(exprParser, cTerStack, pyTerStack));
        }
 private static Parser <char, T> Trim <T>(Parser <char, T> parser)
 {
     return(SkipWhitespaces.Then(parser));
 }