示例#1
0
        // this method must be invoked in any subclass immediatly after constructor completion
        protected void CompleteInitialization()
        {
            lock (this)
            {
                if (_isReadOnly)
                {
                    return;
                }
                _isReadOnly = true;
            }

            if (typeof(ISyntaxExtender).IsAssignableFrom(typeof(TExtender)))
            {
                var api = new TExtender().CastTo <ISyntaxExtender>();
                api.ExtendSyntax(this);
            }

            NonBreakingIdentifierChars = NonBreakingIdentifierChars.CastTo <List <char> >().AsReadOnly();
            SyntaxChars         = SyntaxChars.CastTo <Dictionary <int, TokenType> >().AsReadOnly();
            Constants           = Constants.CastTo <Dictionary <string, object> >().AsReadOnly();
            Symbols             = Symbols.CastTo <Dictionary <string, TokenType> >().AsReadOnly();
            Functions           = Functions.CastTo <List <FunctionMap> >().AsReadOnly();
            KnownTypes          = KnownTypes.CastTo <Dictionary <string, TypeParser> >().AsReadOnly();
            ImplementsVariables = Symbols.Values.Any(v => v == TokenType.Declaration) || SyntaxChars.Values.Any(v => v == TokenType.Declaration);
            IdentifierDelimiter = (char)SyntaxChars.Where(kv => kv.Value == TokenType.IdentifierDelimiter).Select(kv => kv.Key).FirstOrDefault();
        }
示例#2
0
        protected ScriptSyntax() : base(false)
        {
            LineComment = '#';

            NonBreakingIdentifierChars.Add('$');

            SyntaxChars.Add(new Dictionary <int, TokenType>
            {
                { '-', TokenType.Negate },
                { '(', TokenType.LParen },
                { ')', TokenType.RParen },
                { '[', TokenType.LArrayBracket },
                { ']', TokenType.RArrayBracket },
                { ',', TokenType.Delimiter },
                { ';', TokenType.LogicalAnd }, // statement seperarator
                { '|', TokenType.BitwiseOr },
                { '&', TokenType.BitwiseAnd },
                { '^', TokenType.BitwiseXOr },
                { '!', TokenType.LogicalNot },
                { '<', TokenType.LessThan },
                { '>', TokenType.GreaterThan },
                { '~', TokenType.BitwiseNot },
                { '/', TokenType.Div },
                { '*', TokenType.Mul },
                { '+', TokenType.Add },
                { '.', TokenType.IdentifierDelimiter },
                { '=', TokenType.Assignment },
                { '@', TokenType.SyntaxEscape }
            });


            Constants.Add(new Dictionary <string, object>
            {
                { "PI", Math.PI },
                { "E", Math.E },
                { "null", null },
                { "true", true },
                { "false", false },
                { "NaN", double.NaN },
                { "INF", double.PositiveInfinity }
            });


            Symbols.Add(new Dictionary <string, TokenType>
            {
                { "-", TokenType.Sub },
                { "==", TokenType.Equal },
                { "!=", TokenType.NotEqual },
                { "||", TokenType.LogicalOr },
                { "&&", TokenType.LogicalAnd },
                { ">>", TokenType.RightShift },
                { "<<", TokenType.LeftShift },
                { "var", TokenType.Declaration }
            });


            Functions.Add(new List <FunctionMap>
            {
                new FunctionMap("if", new IffBuilder()),
                new FunctionMap("else", new ElseBuilder()),
                new FunctionMap("format", new FormatBuilder()),
                new FunctionMap("cast", new CastBuilder()),
                new FunctionMap("contains", MemberTokens.String.Contains),
                new FunctionMap("startswith", MemberTokens.String.StartsWith),
                new FunctionMap("endswith", MemberTokens.String.EndsWith),
                new FunctionMap("concat", MemberTokens.String.Concat),
                new FunctionMap("indexof", MemberTokens.String.IndexOf),
                new FunctionMap("length", MemberTokens.String.Length),
                new FunctionMap("substring", MemberTokens.String.Substring1),
                new FunctionMap("substring", MemberTokens.String.Substring2), // overload
                new FunctionMap("toupper", MemberTokens.String.ToUpper),
                new FunctionMap("tolower", MemberTokens.String.ToLower),
                new FunctionMap("trim", MemberTokens.String.Trim),

                new FunctionMap("year", MemberTokens.DateTime.Year),
                new FunctionMap("year", MemberTokens.DateTimeOffset.Year),

                new FunctionMap("month", MemberTokens.DateTime.Month),
                new FunctionMap("month", MemberTokens.DateTimeOffset.Month),

                new FunctionMap("day", MemberTokens.DateTime.Day),
                new FunctionMap("day", MemberTokens.DateTimeOffset.Day),
                new FunctionMap("day", MemberTokens.TimeSpan.Days),

                new FunctionMap("hour", MemberTokens.DateTime.Hour),
                new FunctionMap("hour", MemberTokens.DateTimeOffset.Hour),
                new FunctionMap("hour", MemberTokens.TimeSpan.Hours),

                new FunctionMap("minute", MemberTokens.DateTime.Minute),
                new FunctionMap("minute", MemberTokens.DateTimeOffset.Minute),
                new FunctionMap("minute", MemberTokens.TimeSpan.Minutes),

                new FunctionMap("second", MemberTokens.DateTime.Second),
                new FunctionMap("second", MemberTokens.DateTimeOffset.Second),
                new FunctionMap("second", MemberTokens.TimeSpan.Seconds),

                new FunctionMap("fractionalseconds", MemberTokens.DateTime.Millisecond),
                new FunctionMap("fractionalseconds", MemberTokens.DateTimeOffset.Millisecond),
                new FunctionMap("fractionalseconds", MemberTokens.TimeSpan.Milliseconds),

                new FunctionMap("totalfractionalseconds", MemberTokens.TimeSpan.TotalMilliseconds),
                new FunctionMap("totalseconds", MemberTokens.TimeSpan.TotalSeconds),
                new FunctionMap("totalminutes", MemberTokens.TimeSpan.TotalMinutes),
                new FunctionMap("totalhours", MemberTokens.TimeSpan.TotalHours),
                new FunctionMap("totaldays", MemberTokens.TimeSpan.TotalDays),

                new FunctionMap("date", MemberTokens.DateTimeOffset.Date),
                new FunctionMap("time", MemberTokens.DateTimeOffset.TimeOfDay),
                new FunctionMap("time", MemberTokens.DateTime.TimeOfDay),
                new FunctionMap("now", MemberTokens.DateTimeOffset.Now),
                new FunctionMap("utcnow", MemberTokens.DateTimeOffset.UtcNow),

                new FunctionMap("dow", MemberTokens.DateTimeOffset.DayOfWeek),
                new FunctionMap("dow", MemberTokens.DateTime.DayOfWeek),
            });


            foreach (var m in typeof(TExtender).GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(m => Attribute.IsDefined(m, typeof(ScriptMethodAttribute))))
            {
                Functions.Add(new FunctionMap(m.GetCustomAttribute <ScriptMethodAttribute>().Name, m));
            }

            this.AddMathFunctions();

            KnownTypes.Add(new Dictionary <string, TypeParser>
            {
                { "X", new TypeParser(typeof(byte[]), lex => lex.ParseBinary()) },
                { "string", new TypeParser(typeof(string), lex => lex) },
                { "bool", new TypeParser(typeof(bool), lex => bool.Parse(lex)) },
                { "byte", new TypeParser(typeof(byte), lex => byte.Parse(lex)) },
                { "dt", new TypeParser(typeof(DateTime), lex => XmlConvert.ToDateTime(lex, XmlDateTimeSerializationMode.Local)) },
                { "datetime", new TypeParser(typeof(DateTime), lex => XmlConvert.ToDateTime(lex, XmlDateTimeSerializationMode.Local)) },
                { "decimal", new TypeParser(typeof(decimal), lex => decimal.Parse(lex)) },
                { "double", new TypeParser(typeof(double), lex => double.Parse(lex)) },
                { "float", new TypeParser(typeof(float), lex => float.Parse(lex)) },
                { "guid", new TypeParser(typeof(Guid), lex => Guid.Parse(lex)) },
                { "int16", new TypeParser(typeof(Int16), lex => Int16.Parse(lex)) },
                { "int32", new TypeParser(typeof(Int32), lex => int.Parse(lex)) },
                { "int64", new TypeParser(typeof(Int64), lex => long.Parse(lex)) },
                { "sbyte", new TypeParser(typeof(sbyte), lex => sbyte.Parse(lex)) },
                { "ts", new TypeParser(typeof(TimeSpan), lex => XmlConvert.ToTimeSpan(lex)) },
                { "timespan", new TypeParser(typeof(TimeSpan), lex => XmlConvert.ToTimeSpan(lex)) },
                { "dto", new TypeParser(typeof(DateTimeOffset), lex => XmlConvert.ToDateTimeOffset(lex)) },
                { "datetimeoffset", new TypeParser(typeof(DateTimeOffset), lex => XmlConvert.ToDateTimeOffset(lex)) }
            });

            CompleteInitialization();
        }
示例#3
0
        protected ODataSyntax() : base(true)
        {
            NonBreakingIdentifierChars.Add('.');

            SyntaxChars.Add(new Dictionary <int, TokenType>
            {
                { '-', TokenType.Negate },
                { '(', TokenType.LParen },
                { ')', TokenType.RParen },
                { ',', TokenType.Delimiter },
                { '/', TokenType.IdentifierDelimiter }
            });

            Symbols.Add(new Dictionary <string, TokenType>
            {
                { "and", TokenType.LogicalAnd },
                { "or", TokenType.LogicalOr },

                { "not", TokenType.LogicalNot },

                { "mod", TokenType.Mod },
                { "div", TokenType.Div },
                { "add", TokenType.Add },
                { "mul", TokenType.Mul },
                { "sub", TokenType.Sub },

                { "has", TokenType.Has },

                { "eq", TokenType.Equal },
                { "ne", TokenType.NotEqual },
                { "lt", TokenType.LessThan },
                { "gt", TokenType.GreaterThan },
                { "le", TokenType.LessThanOrEqual },
                { "ge", TokenType.GreaterThanOrEqual }
            });

            Functions.Add(new List <FunctionMap>
            {
                new FunctionMap("cast", new CastBuilder()),
                new FunctionMap("isof", new IsofBuilder()),

                new FunctionMap("contains", MemberTokens.String.Contains),
                new FunctionMap("startswith", MemberTokens.String.StartsWith),
                new FunctionMap("endswith", MemberTokens.String.EndsWith),
                new FunctionMap("concat", MemberTokens.String.Concat),
                new FunctionMap("indexof", MemberTokens.String.IndexOf),
                new FunctionMap("length", MemberTokens.String.Length),
                new FunctionMap("substring", MemberTokens.String.Substring1),
                new FunctionMap("substring", MemberTokens.String.Substring2), // overload
                new FunctionMap("toupper", MemberTokens.String.ToUpper),
                new FunctionMap("tolower", MemberTokens.String.ToLower),
                new FunctionMap("trim", MemberTokens.String.Trim),

                new FunctionMap("floor", MemberTokens.Math.FloorDecimal),
                new FunctionMap("floor", MemberTokens.Math.FloorDouble),
                new FunctionMap("round", MemberTokens.Math.RoundDecimalZeroDigits),
                new FunctionMap("round", MemberTokens.Math.RoundDoubleZeroDigits),
                new FunctionMap("ceiling", MemberTokens.Math.CeilingDecimal),
                new FunctionMap("ceiling", MemberTokens.Math.CeilingDouble),

                new FunctionMap("year", MemberTokens.DateTime.Year),
                new FunctionMap("year", MemberTokens.DateTimeOffset.Year),

                new FunctionMap("month", MemberTokens.DateTime.Month),
                new FunctionMap("month", MemberTokens.DateTimeOffset.Month),

                new FunctionMap("day", MemberTokens.DateTime.Day),
                new FunctionMap("day", MemberTokens.DateTimeOffset.Day),
                new FunctionMap("day", MemberTokens.TimeSpan.Days),

                new FunctionMap("hour", MemberTokens.DateTime.Hour),
                new FunctionMap("hour", MemberTokens.DateTimeOffset.Hour),
                new FunctionMap("hour", MemberTokens.TimeSpan.Hours),

                new FunctionMap("minute", MemberTokens.DateTime.Minute),
                new FunctionMap("minute", MemberTokens.DateTimeOffset.Minute),
                new FunctionMap("minute", MemberTokens.TimeSpan.Minutes),

                new FunctionMap("second", MemberTokens.DateTime.Second),
                new FunctionMap("second", MemberTokens.DateTimeOffset.Second),
                new FunctionMap("second", MemberTokens.TimeSpan.Seconds),

                new FunctionMap("fractionalseconds", MemberTokens.DateTime.Millisecond),
                new FunctionMap("fractionalseconds", MemberTokens.DateTimeOffset.Millisecond),
                new FunctionMap("fractionalseconds", MemberTokens.TimeSpan.Milliseconds),

                new FunctionMap("totalfractionalseconds", MemberTokens.TimeSpan.TotalMilliseconds),
                new FunctionMap("totalseconds", MemberTokens.TimeSpan.TotalSeconds),
                new FunctionMap("totalminutes", MemberTokens.TimeSpan.TotalMinutes),
                new FunctionMap("totalhours", MemberTokens.TimeSpan.TotalHours),
                new FunctionMap("totaldays", MemberTokens.TimeSpan.TotalDays),
                new FunctionMap("totaloffsetminutes", new TotalOffsetMinutesBuilder()),

                new FunctionMap("date", MemberTokens.DateTimeOffset.Date),
                new FunctionMap("time", MemberTokens.DateTimeOffset.TimeOfDay),
                new FunctionMap("time", MemberTokens.DateTime.TimeOfDay),
                new FunctionMap("now", MemberTokens.DateTimeOffset.Now),
                new FunctionMap("utcnow", MemberTokens.DateTimeOffset.UtcNow), // not OData specified

                new FunctionMap("mindatetime", MemberTokens.DateTimeOffset.MinValue),
                new FunctionMap("maxdatetime", MemberTokens.DateTimeOffset.MaxValue),


                new FunctionMap("dow", MemberTokens.DateTimeOffset.DayOfWeek), // not OData specified
                new FunctionMap("dow", MemberTokens.DateTime.DayOfWeek),
            });

            this.TryAddSqlServerSpatialTypes();


            Constants.Add(new Dictionary <string, object>
            {
                { "null", null },
                { "true", true },
                { "false", false },
                { "NaN", double.NaN },
                { "INF", double.PositiveInfinity }
            });

            KnownTypes.Add(new Dictionary <string, TypeParser>
            {
                { "X", new TypeParser(typeof(byte[]), lex => lex.ParseBinary()) },
                { "binary", new TypeParser(typeof(byte[]), lex => lex.ParseBinary()) },
                { "string", new TypeParser(typeof(string), lex => lex) },
                { "boolean", new TypeParser(typeof(bool), lex => bool.Parse(lex)) },
                { "byte", new TypeParser(typeof(byte), lex => byte.Parse(lex)) },
                { "datetime", new TypeParser(typeof(DateTime), lex => XmlConvert.ToDateTime(lex, XmlDateTimeSerializationMode.Local)) },
                { "decimal", new TypeParser(typeof(decimal), lex => decimal.Parse(lex)) },
                { "double", new TypeParser(typeof(double), lex => double.Parse(lex)) },
                { "single", new TypeParser(typeof(float), lex => float.Parse(lex)) },
                { "float", new TypeParser(typeof(float), lex => float.Parse(lex)) },
                { "guid", new TypeParser(typeof(Guid), lex => Guid.Parse(lex)) },
                { "int16", new TypeParser(typeof(Int16), lex => Int16.Parse(lex)) },
                { "int32", new TypeParser(typeof(Int32), lex => int.Parse(lex)) },
                { "int64", new TypeParser(typeof(Int64), lex => long.Parse(lex)) },
                { "sbyte", new TypeParser(typeof(sbyte), lex => sbyte.Parse(lex)) },
                { "time", new TypeParser(typeof(TimeSpan), lex => XmlConvert.ToTimeSpan(lex)) },
                { "duration", new TypeParser(typeof(TimeSpan), lex => XmlConvert.ToTimeSpan(lex)) },
                { "datetimeoffset", new TypeParser(typeof(DateTimeOffset), lex => XmlConvert.ToDateTimeOffset(lex)) },

                { "Edm.Binary", new TypeParser(typeof(byte[]), lex => lex.ParseBinary()) },
                { "Edm.String", new TypeParser(typeof(string), lex => lex) },
                { "Edm.Boolean", new TypeParser(typeof(bool), lex => bool.Parse(lex)) },
                { "Edm.Byte", new TypeParser(typeof(byte), lex => byte.Parse(lex)) },
                { "Edm.DateTime", new TypeParser(typeof(DateTime), lex => XmlConvert.ToDateTime(lex, XmlDateTimeSerializationMode.Local)) },
                { "Edm.Decimal", new TypeParser(typeof(decimal), lex => decimal.Parse(lex)) },
                { "Edm.Double", new TypeParser(typeof(double), lex => double.Parse(lex)) },
                { "Edm.Single", new TypeParser(typeof(float), lex => float.Parse(lex)) },
                { "Edm.Float", new TypeParser(typeof(float), lex => float.Parse(lex)) },
                { "Edm.Guid", new TypeParser(typeof(Guid), lex => Guid.Parse(lex)) },
                { "Edm.Int16", new TypeParser(typeof(Int16), lex => Int16.Parse(lex)) },
                { "Edm.Int32", new TypeParser(typeof(Int32), lex => int.Parse(lex)) },
                { "Edm.Int64", new TypeParser(typeof(Int64), lex => long.Parse(lex)) },
                { "Edm.SBbyte", new TypeParser(typeof(sbyte), lex => sbyte.Parse(lex)) },
                { "Edm.Time", new TypeParser(typeof(TimeSpan), lex => XmlConvert.ToTimeSpan(lex)) },
                { "Edm.Duration", new TypeParser(typeof(TimeSpan), lex => XmlConvert.ToTimeSpan(lex)) },
                { "Edm.DateTimeOffset", new TypeParser(typeof(DateTimeOffset), lex => XmlConvert.ToDateTimeOffset(lex)) }
            });

            CompleteInitialization();
        }