示例#1
0
        public void AndOrTests()
        {
            TagExpression onlyAnd = Parser.ParseExpression(NewState("1==2 and 2==2 AND 3==2 and 4==2 and 5==2"));

            Assert.That(onlyAnd.ToString(), Is.EqualTo("(((((1 == 2) AND (2 == 2)) AND (3 == 2)) AND (4 == 2)) AND (5 == 2))"));

            TagExpression onlyOr = Parser.ParseExpression(NewState("1==2 or 2==2 OR 3==2 or 4==2 or 5==2"));

            Assert.That(onlyOr.ToString(), Is.EqualTo("(((((1 == 2) OR (2 == 2)) OR (3 == 2)) OR (4 == 2)) OR (5 == 2))"));

            Exception e = null;

            try
            {
                TagExpression errorAndException = Parser.ParseExpression(NewState("1==2 and 2==2 OR 3==2"));
            }
            catch (ExpressionException ee)
            { e = ee; }
            Assert.That(e, Is.TypeOf(typeof(PriorityException)));

            TagExpression andException = Parser.ParseExpression(NewState("1==2 and 2==2 OR 3==2", true));

            Assert.That(andException.ToString(), Is.EqualTo("(((1 == 2) AND (2 == 2)) OR (3 == 2))"));

            andException = Parser.ParseExpression(NewState("1==2 or 2==2 and 3==2", true));
            Assert.That(andException.ToString(), Is.EqualTo("((1 == 2) OR ((2 == 2) AND (3 == 2)))"));
        }
示例#2
0
        private static List <TagExpression> ArgList(ParserState state)
        {
            List <TagExpression> args = new List <TagExpression>();

            while (state.PeekTokenType() != TagTokenType.AtEof)
            {
                TagExpression expr = ArgValue(state);

                if (expr == null)
                {
                    throw new ParserException(string.Format("Expected argument value instead of '{0}'", state.PeekToken()), state);
                }

                args.Add(expr);

                if (state.PeekTokenType() != TagTokenType.Comma)
                {
                    break;
                }

                state.NextToken();
            }

            return(args);
        }
示例#3
0
        static TagExpression BooleanExpression(ParserState state)
        {
            TagExpression baseExpression = Part(state);

            if (baseExpression == null)
            {
                return(null);                // Should not happen
            }
            TagToken token;

            switch (state.PeekTokenType())
            {
            case TagTokenType.IsEqual:
            case TagTokenType.IsNot:
            case TagTokenType.IsLte:
            case TagTokenType.IsLessThan:
            case TagTokenType.IsGreaterThan:
            case TagTokenType.IsGte:
                token = state.NextToken();

                return(new CompareExpression(token, baseExpression, Part(state)));

            default:
                return(baseExpression);
            }
        }
示例#4
0
 public UnaryExpression(TagToken token, TagExpression inner)
     : base(token)
 {
     if (inner == null)
     {
         throw new ArgumentNullException("inner");
     }
     _inner = inner;
 }
示例#5
0
        public void ParseExceptions()
        {
            Exception e = null;

            try
            {
                TagExpression expr = Parser.ParseExpression(NewState(" '$(Configuration)' == '' == 24"));
            }
            catch (ExpressionException ee)
            { e = ee; }
            Assert.That(e, Is.TypeOf(typeof(ParserException)));

            e = null;
            try
            {
                TagExpression expr = Parser.ParseExpression(NewState(" '$(Configuration)' == '' |"));
            }
            catch (ExpressionException ee)
            { e = ee; }
            Assert.That(e, Is.TypeOf(typeof(LexerException)));

            e = null;
            try
            {
                TagExpression expr = Parser.ParseExpression(NewState(" '$(Configuration)' == '' 12"));
            }
            catch (ExpressionException ee)
            { e = ee; }
            Assert.That(e, Is.TypeOf(typeof(ParserException)));

            e = null;
            try
            {
                TagExpression expr = Parser.ParseExpression(NewState("('$(Configuration)' == ''"));
            }
            catch (ExpressionException ee)
            { e = ee; }
            Assert.That(e, Is.TypeOf(typeof(ParserException)));

            e = null;
            try
            {
                TagExpression expr = Parser.ParseExpression(NewState(")'$(Configuration)' == ''"));
            }
            catch (ExpressionException ee)
            { e = ee; }
            Assert.That(e, Is.TypeOf(typeof(ParserException)));

            e = null;
            try
            {
                TagExpression expr = Parser.ParseExpression(NewState("'$(Configuration)' == '',"));
            }
            catch (ExpressionException ee)
            { e = ee; }
            Assert.That(e, Is.TypeOf(typeof(ParserException)));
        }
示例#6
0
        internal override void PrePrepare(TagBatchDefinition batchDefinition)
        {
            base.PrePrepare(batchDefinition);

            if (_expression == null)
            {
                _expression = QQn.TurtleUtils.Tags.ExpressionParser.Parser.Parse(Definition, ConditionArgs);
            }
        }
示例#7
0
        /// <summary>
        /// Parses the expression.
        /// </summary>
        /// <param name="state">The state.</param>
        /// <returns></returns>
        internal static TagExpression ParseExpression(ParserState state)
        {
            TagExpression expr = CompleteExpression(state);

            if (expr != null)
            {
                ResolveAndOrConflicts(expr, state);
            }

            return(expr);
        }
示例#8
0
        public void ParseSome()
        {
            TagExpression expr = Parser.ParseExpression(NewState(" '$(Configuration)' == '' "));

            Assert.That(expr, Is.Not.Null);
            Assert.That(expr.ToString(), Is.EqualTo("('$(Configuration)' == '')"));

            expr = Parser.ParseExpression(NewState("( '$(ProjectOutput)' <= '@(Configuration)' AnD 12 < 24.0 ) Or 12==24"));
            Assert.That(expr, Is.Not.Null);
            Assert.That(expr.ToString(), Is.EqualTo("((('$(ProjectOutput)' <= '@(Configuration)') AND (12 < 24.0)) OR (12 == 24))"));
        }
示例#9
0
        protected BinaryExpression(TagToken token, TagExpression lhs, TagExpression rhs)
            : base(token)
        {
            if (lhs == null)
            {
                throw new ArgumentNullException("lhs");
            }
            else if (rhs == null)
            {
                throw new ArgumentNullException("rhs");
            }

            _lhs = lhs;
            _rhs = rhs;
        }
示例#10
0
        static void AddAndOr(TagExpression tagExpression, List <TagToken> tokens, List <TagExpression> exprs)
        {
            AndOrExpression andOr = tagExpression as AndOrExpression;

            if (andOr != null)
            {
                AddAndOr(andOr.LeftHand, tokens, exprs);
                tokens.Add(andOr.Token);
                AddAndOr(andOr.RightHand, tokens, exprs);
            }
            else
            {
                exprs.Add(tagExpression);
            }
        }
示例#11
0
        private static TagExpression Expr(ParserState state)
        {
            TagExpression expr = BooleanExpression(state);

            switch (state.PeekTokenType())
            {
            case TagTokenType.Or:
                return(new AndOrExpression(state.NextToken(), expr, BooleanExpression(state)));

            case TagTokenType.And:
                return(new AndOrExpression(state.NextToken(), expr, BooleanExpression(state)));

            default:
                return(expr);
            }
        }
        /// <summary>
        /// 表达式查询
        /// </summary>
        /// <exception cref="InvalidExpressionException">查询表达式非法</exception>
        public async Task <List <FileItem> > QueryAsync(string expression)
        {
#if DISPOSE_CONTEXT_IMMEDIATELY
            using (var context = Context)
            {
#endif
            var files  = new List <FileItem>();
            var idList = TagExpression.Query(context.Relations, expression);
            foreach (int fileItemId in idList)
            {
                files.Add(await GetFileItemAsync(fileItemId));
            }
            return(files);

#if DISPOSE_CONTEXT_IMMEDIATELY
        }
#endif
        }
示例#13
0
        internal void ForceExpression(TagToken token, TagExpression lhs, TagExpression rhs)
        {
            switch (token.TokenType)
            {
            case TagTokenType.And:
                _isAnd = true;
                break;

            case TagTokenType.Or:
                break;

            default:
                throw new ArgumentException("Only AND and OR are allowed");
            }
            _token = token;
            SetEditable(true);
            LeftHand  = lhs;
            RightHand = rhs;
            SetEditable(false);
        }
示例#14
0
        internal static TagExpression CompleteExpression(ParserState state)
        {
            TagExpression expr = Expr(state);

            while (state.PeekTokenType() != TagTokenType.AtEof)
            {
                TagToken tk = state.NextToken();
                switch (tk.TokenType)
                {
                case TagTokenType.Or:
                    expr = new AndOrExpression(tk, expr, BooleanExpression(state));
                    break;

                case TagTokenType.And:
                    expr = new AndOrExpression(tk, expr, BooleanExpression(state));
                    break;

                default:
                    throw new ParserException(string.Format("Unexpected token {0}", tk), tk, state);
                }
            }

            return(expr);
        }
示例#15
0
 public AndOrExpression(TagToken token, TagExpression lhs, TagExpression rhs)
     : base(token, lhs, rhs)
 {
     ForceExpression(token, lhs, rhs);
 }
示例#16
0
 public CompareExpression(TagToken token, TagExpression lhs, TagExpression rhs)
     : base(token, lhs, rhs)
 {
 }
示例#17
0
 public NotExpression(TagToken token, TagExpression inner)
     : base(token, inner)
 {
 }
示例#18
0
        internal static void ResolveAndOrConflicts(TagExpression expr, ParserState state)
        {
            if (expr == null)
            {
                throw new ArgumentNullException("expr");
            }

            AndOrExpression andOr = expr as AndOrExpression;

            if (andOr != null && (andOr.LeftHand is AndOrExpression || andOr.RightHand is AndOrExpression))
            {
                List <TagToken>      tokens = new List <TagToken>();
                List <TagExpression> exprs  = new List <TagExpression>();

                AddAndOr(andOr, tokens, exprs);                 // Create a list of tokens and separating expressions

                if (exprs.Count != tokens.Count + 1)
                {
                    throw new InvalidOperationException();                     // Not a valid token chain
                }
                TagTokenType tt = tokens[0].TokenType;

                bool hasConflict = false;
                for (int i = 1; i < tokens.Count; i++)
                {
                    if (tokens[i].TokenType != tt)
                    {
                        if (!state.Args.ApplyAndOrPriority)
                        {
                            throw new PriorityException("And or conflict; please resolve using parens", tokens[i], state);
                        }
                        else
                        {
                            hasConflict = true;
                        }
                    }
                }

                if (hasConflict)
                {
                    // We re-orden the children to prioritize 'and' above 'or'

                    // We assume: we have at least one 'and' at least one 'or'

                    int i;

                    // Re-create all groups of and-s, from the back
                    while (0 <= (i = LastToken(tokens, TagTokenType.And)))
                    {
                        exprs[i] = new AndOrExpression(tokens[i], exprs[i], exprs[i + 1]);
                        tokens.RemoveAt(i);
                        exprs.RemoveAt(i + 1);
                    }

                    // Re-create all groups of or-s, from the back
                    while (1 <= (i = LastToken(tokens, TagTokenType.Or)))
                    {
                        exprs[i] = new AndOrExpression(tokens[i], exprs[i], exprs[i + 1]);
                        tokens.RemoveAt(i);
                        exprs.RemoveAt(i + 1);
                    }

                    if (exprs.Count != 2 && tokens.Count != 1)
                    {
                        throw new InvalidOperationException();
                    }

                    andOr.ForceExpression(tokens[0], exprs[0], exprs[1]);
                }
            }

            foreach (TagExpression ee in expr.SubExpressions)
            {
                ResolveAndOrConflicts(ee, state);
            }
        }
示例#19
0
 public ParenExpression(TagToken token, TagExpression inner)
     : base(token, inner)
 {
 }
示例#20
0
        public MessageReceivedEventArgs(String Message)
        {
            //Console.WriteLine(Message);
            this.Tags       = new Dictionary <string, string>();
            this.RawMessage = Message;
            this.Type       = MessageType.UNDEFINED;
            this.Permission = Permission.Everybody;

            if (String.IsNullOrEmpty(Message))
            {
                return;
            }

            if (Message.StartsWith(@"PING"))
            {
                this.Type = MessageType.Ping;
                //return;
            }
            else if (Message.StartsWith(@":tmi.twitch.tv"))
            {
                this.Type = MessageType.Server;
                return;
            }
            else
            {
                String[] SpaceSplit = Message.Split(' ');
                if (SpaceSplit.Length < ((UsesTags) ? 3 : 2))
                {
                    this.Type = MessageType.Server;
                    return;
                }
                this.Channel = SpaceSplit[(UsesTags) ? 3 : 2].Substring(1);

                // Tags
                if (UsesTags)
                {
                    String[] TagSplit = SpaceSplit[0].Substring(1).Split(';');
                    foreach (String TagExpression in TagSplit)
                    {
                        String[] TagExpressionSplit = TagExpression.Split('=');
                        Tags.Add(TagExpressionSplit[0], TagExpressionSplit[1]);
                    }
                }
                String t_;
                Tags.TryGetValue("display-name", out t_);
                if (!Tags.ContainsKey("display-name") || String.IsNullOrWhiteSpace(t_))
                {
                    if (SpaceSplit[0].Contains(":[email protected]"))
                    {
                        IsSubMessage         = true;
                        Tags["display-name"] = SpaceSplit[3].Substring(1);
                    }
                    else
                    {
                        String RegexMatch = new Regex(@":([A-Za-z0-9_-]+)!\1@\1.tmi.twitch.tv").Match(this.RawMessage).Value;
                        if (!String.IsNullOrEmpty(RegexMatch))
                        {
                            Tags["display-name"] = RegexMatch.Substring(1).Split('!').FirstOrDefault();
                        }
                        else
                        {
                            Tags["display-name"] = "**NO_NAME**";
                        }
                    }
                }
                if (SpaceSplit[(UsesTags) ? 2 : 1] == @"PRIVMSG")
                {
                    this.Type = MessageType.Chat;

                    String m = String.Empty;
                    for (int i = ((UsesTags) ? 4 : 3); i < SpaceSplit.Length; i++)
                    {
                        m += SpaceSplit[i];
                        if (i < SpaceSplit.Length - 1)
                        {
                            m += " ";
                        }
                    }

                    this.Message = m.Substring(1);


                    if (this.Message[0] == '\u0001')
                    {
                        //Console.WriteLine("Yay?");
                        IsAction     = true;
                        this.Message = this.Message.Substring(8);
                        this.Message = this.Message.Substring(0, this.Message.Length - 1);
                    }
                    // Setup Permission

                    //Console.WriteLine(this.Nick + " | " + this.Channel);
                    if (IsSubscriber)
                    {
                        this.Permission = Permission.Subscriber;
                    }

                    if (IsModerator)
                    {
                        this.Permission = Permission.Moderator;
                    }

                    if (this.Nick.ToLower() == this.Channel)
                    {
                        this.Permission = Permission.Broadcaster;
                    }

                    if (this.Nick.ToLower() == @"imthe666st")
                    {
                        this.Permission  = Permission.Developer;
                        this.IsDeveloper = true;
                    }
                }
                else if (SpaceSplit[(UsesTags) ? 2 : 1] == @"USERSTATE")
                {
                    this.Type = MessageType.Userstate;
                }
                else if (SpaceSplit[(UsesTags) ? 2 : 1] == @"ROOMSTATE")
                {
                    this.Type = MessageType.Roomstate;
                }
                else if (SpaceSplit[(UsesTags) ? 2 : 1] == @"USERNOTICE")
                {
                    this.Type = MessageType.Usernotice;
                    //Console.WriteLine(RawMessage);
                }
                else if (SpaceSplit[(UsesTags) ? 2 : 1] == @"CLEARCHAT")
                {
                    this.Type = MessageType.Clearchat;
                    //Console.WriteLine(RawMessage);
                }
                else if (SpaceSplit[(UsesTags) ? 2 : 1] == @"JOIN")
                {
                    this.Type = MessageType.Join;
                    //Console.WriteLine(RawMessage);
                }
                else if (SpaceSplit[(UsesTags) ? 2 : 1] == @"PART")
                {
                    this.Type = MessageType.Part;
                    //Console.WriteLine(RawMessage);
                }
                else if (SpaceSplit[(UsesTags) ? 2 : 1] == @"WHISPER")
                {
                    this.Type = MessageType.Whisper;

                    String m = String.Empty;
                    for (int i = 4; i < SpaceSplit.Length; i++)
                    {
                        m += SpaceSplit[i];
                        if (i < SpaceSplit.Length - 1)
                        {
                            m += " ";
                        }
                    }

                    this.Message = m.Substring(1);
                }
                else
                {
                    this.Type = MessageType.Server;
                    //Console.WriteLine(this.RawMessage);
                    //Console.WriteLine("asdf {0}", SpaceSplit[(UsesTags) ? 2 : 1]);
                }
            }
        }
示例#21
0
        internal static TagExpression Part(ParserState state)
        {
            TagExpression expression = ArgValue(state);

            if (expression != null)
            {
                return(expression);
            }

            TagToken tk = state.NextToken();
            TagToken next;

            if (tk == null)
            {
                return(null);
            }

            switch (tk.TokenType)
            {
            case TagTokenType.Function:
                next = state.NextToken();
                if (next == null)
                {
                    throw new ParserException("Expected '('", tk, state);
                }
                else if (next.TokenType != TagTokenType.ParenOpen)
                {
                    throw new ParserException(string.Format("Expected '(' instead of '{0}')", next), state);
                }

                List <TagExpression> functionArgs = ArgList(state);

                next = state.NextToken();

                if (next == null)
                {
                    throw new ParserException(string.Format("Expected ')' before end of expression", state.PeekToken()), state);
                }
                else if (next.TokenType != TagTokenType.ParenClose)
                {
                    throw new ParserException(string.Format("Expected ')' instead of '{0}'", next), state);
                }

                expression = new FunctionExpression(tk, functionArgs.AsReadOnly());
                break;

            case TagTokenType.ParenOpen:
                expression = new ParenExpression(tk, Expr(state));

                next = state.NextToken();
                if (next == null)
                {
                    throw new ParserException(string.Format("Expected ')' before end of expression", state.PeekToken()), state);
                }
                else if (next.TokenType != TagTokenType.ParenClose)
                {
                    throw new ParserException(string.Format("Expected ')' instead of '{0}'", next), state);
                }

                break;

            case TagTokenType.Not:
                expression = new NotExpression(tk, Expr(state));
                break;

            default:
                throw new ParserException(string.Format("Unexpected token '{0}'", tk), state);
            }

            return(expression);
        }