JSqlParser - Довольно печатать, где предложение

Я начал использовать JSqlParser, я могу разобрать предложение Where, но мне не удается идти дальше с ним.

JSqlParser github ссылка

Действительно, я пытался переопределить методы посещения, но не понимаю, как достичь своей цели.

Допустим, у меня есть: (a=1 AND (b=2 OR (c=3 AND d=4))) OR e=2 в качестве ввода, и я хотел бы в качестве вывода:

 -> a=1
 -> AND
 --> b=2 
 --> OR
 ---> c=3
 ---> AND
 ---> d=4
 -> OR
 -> e=5

Моей конечной целью является не красивая печать, а понимание того, как узнать текущую глубину печати в данном состоянии. Для того, чтобы копаться в дереве, как я хочу.

Я начал кусок кода, анализируя предложение where:

Expression expr = CCJSqlParserUtil.parseCondExpression("(a=1 AND (b=2 OR >(c=3 AND d=4))) OR e=2");
expr.accept(new ExpressionVisitorAdapter() {

    @Override
    public void visit(ExpressionClassToChoose expr) {
      some code here...
    }

});

Не могли бы вы показать мне способ начать такого рода вещи? Должен ли я работать с методами посещения или я не прав?

Спасибо!

1 ответ

Путь посетителя как всегда один путь. Если вы хотите получить глубину скобок, вы можете придерживаться:

public void visit(Parenthesis parenthesis)

Чтобы получить желаемый результат, немного сложнее. Я реализовал простой пример, принимая во внимание только AND и OR. Я не использую ExpressionVisitorAdapter, но ExpressionDeParser, который отвечает за печать Expression. Таким образом, вы можете изменить сгенерированный вывод в соответствии с вашими потребностями.

public static void main(String args[]) throws JSQLParserException {
    Expression expr = CCJSqlParserUtil.parseCondExpression("(a=1 AND (b=2 OR (c=3 AND d=4))) OR e=2");
    StringBuilder b = new StringBuilder();
    expr.accept(new ExpressionDeParser(null, b) {
        int depth = 0;

        @Override
        public void visit(Parenthesis parenthesis) {
            if (parenthesis.isNot()) {
                getBuffer().append("NOT");
            }

            depth++;
            parenthesis.getExpression().accept(this);
            depth--;
        }

        @Override
        public void visit(OrExpression orExpression) {
            visitBinaryExpr(orExpression, "OR");
        }

        @Override
        public void visit(AndExpression andExpression) {
            visitBinaryExpr(andExpression, "AND");
        }

        private void visitBinaryExpr(BinaryExpression expr, String operator) {
            if (expr.isNot()) {
                getBuffer().append("NOT");
            }
            if (!(expr.getLeftExpression() instanceof OrExpression) 
                    && !(expr.getLeftExpression() instanceof AndExpression) 
                    && !(expr.getLeftExpression() instanceof Parenthesis)) {
                getBuffer().append(StringUtils.repeat("-", depth)).append(">");
            }
            expr.getLeftExpression().accept(this);
            getBuffer().append("\n").append(StringUtils.repeat("-", depth)).append(">");
            getBuffer().append(operator).append("\n");
            if (!(expr.getRightExpression() instanceof OrExpression) 
                    && !(expr.getRightExpression() instanceof AndExpression) 
                    && !(expr.getRightExpression() instanceof Parenthesis)) {
                getBuffer().append(StringUtils.repeat("-", depth)).append(">");
            }
            expr.getRightExpression().accept(this);
        }
    });

    System.out.println(b);
}

Как видите, скобка посетителя меняет глубину. Трудная часть находится внутри visitBinaryExpression, Сложный экземпляр логики происходит от использования выражения And/OrExpression для вывода. Поскольку для одной текстовой строки несколько вызовов visitBinaryExpression может произойти, отступ должен быть сделан из самой внешней части.

Если вы хотите улучшить печать синтаксического анализа JSqlParser, ваши обновления следует отправлять в deparsers.

Другие вопросы по тегам