searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

一种SQL解析实现分析

2023-06-14 06:31:43
8
0

一种SQL解析实现分析

1、概述

本文主要是介绍中间件SQL 解析的实现

2、介绍

基本原理

 

antlr 入门

一个用antlr 实现的简单的计算器

语法

 

grammar Expr;
s : e ;
e : e op=MULT e    // MULT is '*'
  | e op=ADD e     // ADD is '+'
  | INT
  ;

MULT: '*' ;
ADD : '+' ;
INT : [0-9]+ ;
WS : [ \t\n]+ -> skip ;



生成的代码

使用antlr 生成的词法和语法解析代码

 

实现visitor及遍历语法树

public class TestEvalVisitor {
    // a4 -visitor LExpr.g4
    /** Visitor "calculator" */
    public static class EvalVisitor extends ExprBaseVisitor<Integer> {
        public Integer visitE(ExprParser.EContext ctx) {
            if ( ctx.getChildCount()==3 ) { // operations have 3 children
                if ( ctx.op.getType()==ExprParser.MULT ) {
                    return visit(ctx.e(0)) * visit(ctx.e(1));
                }
                else {
                    return visit(ctx.e(0)) + visit(ctx.e(1)); // must be add
                }
            }
            return visitChildren(ctx);   // must be e above INT
        }

        @Override
        public Integer visitTerminal(TerminalNode node) {
            if ( node.getSymbol().getType()==ExprParser.INT ) {
                return Integer.valueOf(node.getText());
            }
            return 0;
        }
    }

    public static void main(String[] args) throws Exception {
        String inputFile = null;
        if ( args.length>0 ) inputFile = args[0];
        InputStream is = System.in;
        if ( inputFile!=null ) {
            is = new FileInputStream(inputFile);
        }
        ANTLRInputStream input = new ANTLRInputStream(is);
        ExprLexer lexer = new ExprLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        ExprParser parser = new ExprParser(tokens);
        parser.setBuildParseTree(true);      // tell ANTLR to build a parse tree
        ParseTree tree = parser.s(); // parse
        // show tree in text form
        System.out.println(tree.toStringTree(parser));

        EvalVisitor evalVisitor = new EvalVisitor();
        int result = evalVisitor.visit(tree);
        System.out.println("visitor result = "+result);
    }
}



执行效果

3、中间件用antlr实现的SQL解析

以DML语句作为介绍,其它类型语句处理模式相同

SQL 语法

以DML为例,编写sql 文法

生成语法解析代码

代码结构类似入门章节里介绍的计算器

实现visitor及遍历语法树

MySQLDMLStatementSQLVisitor 是上面antlr 生成代码BaseVistor的子类

 

遍历后生成的结果对象MySQLSelectStatement,描述了select 语句解析结果

 

4、总结

总体流程  词法、文法->语法树->visitor 访问->自定义对象

 

0条评论
0 / 1000
卢****雨
5文章数
0粉丝数
卢****雨
5 文章 | 0 粉丝
原创

一种SQL解析实现分析

2023-06-14 06:31:43
8
0

一种SQL解析实现分析

1、概述

本文主要是介绍中间件SQL 解析的实现

2、介绍

基本原理

 

antlr 入门

一个用antlr 实现的简单的计算器

语法

 

grammar Expr;
s : e ;
e : e op=MULT e    // MULT is '*'
  | e op=ADD e     // ADD is '+'
  | INT
  ;

MULT: '*' ;
ADD : '+' ;
INT : [0-9]+ ;
WS : [ \t\n]+ -> skip ;



生成的代码

使用antlr 生成的词法和语法解析代码

 

实现visitor及遍历语法树

public class TestEvalVisitor {
    // a4 -visitor LExpr.g4
    /** Visitor "calculator" */
    public static class EvalVisitor extends ExprBaseVisitor<Integer> {
        public Integer visitE(ExprParser.EContext ctx) {
            if ( ctx.getChildCount()==3 ) { // operations have 3 children
                if ( ctx.op.getType()==ExprParser.MULT ) {
                    return visit(ctx.e(0)) * visit(ctx.e(1));
                }
                else {
                    return visit(ctx.e(0)) + visit(ctx.e(1)); // must be add
                }
            }
            return visitChildren(ctx);   // must be e above INT
        }

        @Override
        public Integer visitTerminal(TerminalNode node) {
            if ( node.getSymbol().getType()==ExprParser.INT ) {
                return Integer.valueOf(node.getText());
            }
            return 0;
        }
    }

    public static void main(String[] args) throws Exception {
        String inputFile = null;
        if ( args.length>0 ) inputFile = args[0];
        InputStream is = System.in;
        if ( inputFile!=null ) {
            is = new FileInputStream(inputFile);
        }
        ANTLRInputStream input = new ANTLRInputStream(is);
        ExprLexer lexer = new ExprLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        ExprParser parser = new ExprParser(tokens);
        parser.setBuildParseTree(true);      // tell ANTLR to build a parse tree
        ParseTree tree = parser.s(); // parse
        // show tree in text form
        System.out.println(tree.toStringTree(parser));

        EvalVisitor evalVisitor = new EvalVisitor();
        int result = evalVisitor.visit(tree);
        System.out.println("visitor result = "+result);
    }
}



执行效果

3、中间件用antlr实现的SQL解析

以DML语句作为介绍,其它类型语句处理模式相同

SQL 语法

以DML为例,编写sql 文法

生成语法解析代码

代码结构类似入门章节里介绍的计算器

实现visitor及遍历语法树

MySQLDMLStatementSQLVisitor 是上面antlr 生成代码BaseVistor的子类

 

遍历后生成的结果对象MySQLSelectStatement,描述了select 语句解析结果

 

4、总结

总体流程  词法、文法->语法树->visitor 访问->自定义对象

 

文章来自个人专栏
sql解析
1 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0