public void setExpression(final String expression) throws IllegalExpressionException {
        MQELexer lexer = new MQELexer(CharStreams.fromString(expression));
        lexer.addErrorListener(new ParseErrorListener());
        MQEParser parser = new MQEParser(new CommonTokenStream(lexer));
        parser.addErrorListener(new ParseErrorListener());
        ParseTree tree;
        try {
            tree = parser.expression();
        } catch (ParseCancellationException e) {
            throw new IllegalExpressionException("Expression: " + expression + " error: " + e.getMessage());
        }
        try {
            TRACE_CONTEXT.set(new DebuggingTraceContext(expression, false, false));
            AlarmMQEVerifyVisitor visitor = new AlarmMQEVerifyVisitor();
            ExpressionResult parseResult = visitor.visit(tree);
            if (StringUtil.isNotBlank(parseResult.getError())) {
                throw new IllegalExpressionException("Expression: " + expression + " error: " + parseResult.getError());
            }
            if (!parseResult.isBoolResult()) {
                throw new IllegalExpressionException(
                    "Expression: " + expression + " root operation is not a Compare Operation.");
            }
            if (ExpressionResultType.SINGLE_VALUE != parseResult.getType()) {
                throw new IllegalExpressionException(
                    "Expression: " + expression + " is not a SINGLE_VALUE result expression.");
            }

            verifyIncludeMetrics(visitor.getIncludeMetrics(), expression);
            this.expression = expression;
            this.includeMetrics = visitor.getIncludeMetrics();
            this.maxTrendRange = visitor.getMaxTrendRange();
        } finally {
            TRACE_CONTEXT.remove();
        }
    }
@Test
    public void testExpressionVerify() throws IllegalExpressionException {
        AlarmRule rule = new AlarmRule();
        //normal common metric
        rule.setExpression("sum(service_percent < 85) >= 3");
        //normal labeled metric
        //4xx + 5xx > 10
        rule.setExpression("sum(aggregate_labels(meter_status_code{_='4xx,5xx'},sum) > 10) > 3");
        rule.setExpression("sum(aggregate_labels(meter_status_code,sum) > 10) > 3");
        //4xx or 5xx > 10
        rule.setExpression("sum(meter_status_code{_='4xx,5xx'} > 10) >= 3");
        rule.setExpression("sum(meter_status_code > 10) >= 3");
        //illegal expression
        Assertions.assertThrows(IllegalExpressionException.class, () -> {
            rule.setExpression("what? sum(service_percent < 85) >= 3");
        });

        //not exist metric
        Assertions.assertEquals(
            "Expression: sum(service_percent111 < 85) >= 3 error: Metric: [service_percent111] dose not exist.",
            Assertions.assertThrows(IllegalExpressionException.class, () -> {
                rule.setExpression("sum(service_percent111 < 85) >= 3");
            }).getMessage()
        );

        //root operation is not a Compare Operation
        Assertions.assertEquals(
            "Expression: sum(service_percent < 85) + 3 root operation is not a Compare Operation.",
            Assertions.assertThrows(IllegalExpressionException.class, () -> {
                rule.setExpression("sum(service_percent < 85) + 3");
            }).getMessage()
        );

        //not a SINGLE_VALUE result expression
        Assertions.assertEquals(
            "Expression: service_percent < 85 is not a SINGLE_VALUE result expression.",
            Assertions.assertThrows(IllegalExpressionException.class, () -> {
                rule.setExpression("service_percent < 85");
            }).getMessage()
        );

        //not a common or labeled metric
        Assertions.assertEquals(
            "Expression: sum(record < 85) > 1 error: Metric dose not supported in alarm, metric: [record] is not a common or labeled metric.",
            Assertions.assertThrows(IllegalExpressionException.class, () -> {
                rule.setExpression("sum(record < 85) > 1");
            }).getMessage()
        );

        //metrics in expression must have the same scope level
        Assertions.assertTrue(Assertions.assertThrows(IllegalExpressionException.class, () -> {
            rule.setExpression("sum(service_percent > endpoint_percent) >= 1");
        }).getMessage().contains("The metrics in expression: sum(service_percent > endpoint_percent) >= 1 must have the same scope level, but got:"));

        //trend expression
        rule.setExpression("sum((increase(service_percent,5) + increase(service_percent,2)) > 0) >= 1");
        Assertions.assertEquals(5, rule.getMaxTrendRange());
    }