Ejemplo n.º 1
0
        public ExprOp ParseOrExpr(QueryLexerTokenKind tokContext)
        {
            ExprOp node = ParseAndExpr(tokContext);

            if (node != null)
            {
                while (true)
                {
                    QueryLexerToken tok = Lexer.NextToken(tokContext);
                    if (tok.Kind == QueryLexerTokenKind.TOK_OR)
                    {
                        ExprOp prev = node;
                        node       = new ExprOp(OpKindEnum.O_OR);
                        node.Left  = prev;
                        node.Right = ParseAndExpr(tokContext);
                        if (node.Right == null)
                        {
                            throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol()));
                        }
                    }
                    else
                    {
                        Lexer.PushToken(tok);
                        break;
                    }
                }
                return(node);
            }
            return(null); // new ExprOp();
        }
Ejemplo n.º 2
0
        public ExprOp ParseQueryTerm(QueryLexerTokenKind tokContext)
        {
            ExprOp node = null;

            QueryLexerToken tok = Lexer.NextToken(tokContext);

            switch (tok.Kind)
            {
            case QueryLexerTokenKind.TOK_SHOW:
            case QueryLexerTokenKind.TOK_ONLY:
            case QueryLexerTokenKind.TOK_BOLD:
            case QueryLexerTokenKind.TOK_FOR:
            case QueryLexerTokenKind.TOK_SINCE:
            case QueryLexerTokenKind.TOK_UNTIL:
            case QueryLexerTokenKind.END_REACHED:
                Lexer.PushToken(tok);
                break;

            case QueryLexerTokenKind.TOK_CODE:
            case QueryLexerTokenKind.TOK_PAYEE:
            case QueryLexerTokenKind.TOK_NOTE:
            case QueryLexerTokenKind.TOK_ACCOUNT:
            case QueryLexerTokenKind.TOK_META:
            case QueryLexerTokenKind.TOK_EXPR:
                node = ParseQueryTerm(tok.Kind);
                if (node == null)
                {
                    throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol()));
                }
                break;

            case QueryLexerTokenKind.TERM:
                if (String.IsNullOrEmpty(tok.Value))
                {
                    throw new InvalidOperationException("term");
                }

                switch (tokContext)
                {
                case QueryLexerTokenKind.TOK_EXPR:
                    node = new Expr(tok.Value).Op;
                    break;

                case QueryLexerTokenKind.TOK_META:
                {
                    node = new ExprOp(OpKindEnum.O_CALL);

                    ExprOp ident = new ExprOp(OpKindEnum.IDENT);
                    ident.AsIdent = "has_tag";
                    node.Left     = ident;

                    ExprOp arg1 = new ExprOp(OpKindEnum.VALUE);
                    arg1.AsValue = Value.Get(new Mask(tok.Value));

                    tok = Lexer.PeekToken(tokContext);
                    if (tok.Kind == QueryLexerTokenKind.TOK_EQ)
                    {
                        tok = Lexer.NextToken(tokContext);
                        tok = Lexer.NextToken(tokContext);
                        if (tok.Kind != QueryLexerTokenKind.TERM)
                        {
                            throw new ParseError(ParseError.ParseError_MetadataEqualityOperatorNotFollowedByTerm);
                        }

                        ExprOp arg2 = new ExprOp(OpKindEnum.VALUE);
                        if (String.IsNullOrEmpty(tok.Value))
                        {
                            throw new InvalidOperationException();
                        }
                        arg2.AsValue = Value.Get(new Mask(tok.Value));

                        node.Right = ExprOp.NewNode(OpKindEnum.O_SEQ, ExprOp.NewNode(OpKindEnum.O_CONS, arg1, arg2));
                    }
                    else
                    {
                        node.Right = arg1;
                    }
                    break;
                }

                default:
                {
                    node = new ExprOp(OpKindEnum.O_MATCH);

                    ExprOp ident = new ExprOp(OpKindEnum.IDENT);
                    switch (tokContext)
                    {
                    case QueryLexerTokenKind.TOK_ACCOUNT:
                        ident.AsIdent = "account"; break;

                    case QueryLexerTokenKind.TOK_PAYEE:
                        ident.AsIdent = "payee"; break;

                    case QueryLexerTokenKind.TOK_CODE:
                        ident.AsIdent = "code"; break;

                    case QueryLexerTokenKind.TOK_NOTE:
                        ident.AsIdent = "note"; break;

                    default:
                        throw new InvalidOperationException();
                    }

                    ExprOp mask = new ExprOp(OpKindEnum.VALUE);
                    mask.AsValue = Value.Get(new Mask(tok.Value));

                    node.Left  = ident;
                    node.Right = mask;

                    break;
                }
                }
                break;

            case QueryLexerTokenKind.LPAREN:
                node = ParseQueryExpr(tokContext, true);
                tok  = Lexer.NextToken(tokContext);
                if (tok.Kind != QueryLexerTokenKind.RPAREN)
                {
                    tok.Expected(')');
                }
                break;

            default:
                Lexer.PushToken(tok);
                break;
            }

            return(node);
        }
Ejemplo n.º 3
0
        public ExprOp ParseUnaryExpr(QueryLexerTokenKind tokContext)
        {
            ExprOp node = null;

            QueryLexerToken tok = Lexer.NextToken(tokContext);

            switch (tok.Kind)
            {
            case QueryLexerTokenKind.TOK_NOT:
            {
                ExprOp term = ParseQueryTerm(tokContext);
                if (term == null)
                {
                    throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol()));
                }

                node      = new ExprOp(OpKindEnum.O_NOT);
                node.Left = term;
                break;
            }

            default:
                Lexer.PushToken(tok);
                node = ParseQueryTerm(tokContext);
                break;
            }

            return(node);
        }