一种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 访问->自定义对象