druid.sql中 lexer 类源码分析

lexer 类的部分成员:

public final String text;       //执行的sql语句原文字符串
protected int pos;              //分词所在位置,分词是一个字符一个字符进行的,当前所在字符的位置,select 中 s位置是0,t位置是5
protected char ch;     //分词所在位置的字符值,分词是一个字符一个字符进行的,当前所在字符的位置,select 中 s位置是s,t位置是t           
protected Keywords keywords = Keywords.DEFAULT_KEYWORDS; //分词使用的关键字列表
protected int line = 0; //记录sql所在行数
示例: while (ch == '\u200B' || ch == '\n') { //\u200B 是空格
if (ch == '\n') {
line++;
}
ch = charAt(++pos); //返回pos所在位置的字符
}



类的方法:
public final void nextToken() { };

这个函数就是实现分词最主要的函数。
对于查询 select a,b,c from test;
刚开始程序
pos=0 ch="s" token=null stringVal=null
然后调用nextToken();
pos=6 ch="" token=select stringVal=null
pos指针前进了6位,在nextToken()里会识别关键字SELECT,找到关键字指针会前进
然后调用nextToken();
pos=8 ch="," token=IDENTIFIER stringVal="a"
pos指针前进了2位,在nextToken()里会识别标识符a,找到标识符a指针会多前进
然后调用nextToken();
pos=9 ch="b" token=COMMA stringVal="a"
pos指针前进了1位,在nextToken()里会识别逗号,,找到逗号,指针会多前进
然后调用nextToken();
pos=10 ch="," token=IDENTIFIER stringVal="b"
pos指针前进了1位,在nextToken()里会识别标识符b,找到标识符b指针会多前进
然后调用nextToken();
pos=11 ch="c" token=COMMA stringVal="b"
pos指针前进了1位,在nextToken()里会识别逗号,,找到逗号,指针会多前进
然后调用nextToken();
pos=12 ch="" token=IDENTIFIER stringVal="c"
pos指针前进了1位,在nextToken()里会识别标识符c,找到标识符c指针会多前进
然后调用nextToken();
pos=17 ch="" token=FROM stringVal=null
pos指针前进了5位,在nextToken()里会识别关键字FROM,找到关键字FROM指针会多前进
然后调用nextToken();
pos=22 ch=";" token=IDENTIFIER stringVal="test"
pos指针前进了5位,在nextToken()里会识别标识符test,找到标识符test指针会多前进
然后调用nextToken();
pos=23 ch="\u001A" token=SEMI stringVal="test" //semicolon(分号的英文) 在unicode编码里结束符:\u001A
pos指针前进了1位,在nextToken()里会识别关键字; ,找到关键字semicolon(SEMI)指针会多前进


示例程序:
String sql = "select a,b,c from test;";
String dbType = "hive";
System.out.println("原始SQL 为 : " + sql);
Lexer Lexer =new Lexer(sql); 分词
SQLExprParser sqlExprParser=new SQLExprParser(Lexer); 生成语法树
sqlExprParser.getLexer().nextToken();
sqlExprParser.getLexer().nextToken();
sqlExprParser.getLexer().nextToken();
sqlExprParser.getLexer().nextToken();
sqlExprParser.getLexer().nextToken();
sqlExprParser.getLexer().nextToken();
sqlExprParser.getLexer().nextToken();
sqlExprParser.getLexer().nextToken();
sqlExprParser.getLexer().nextToken();

posted @ 2022-07-01 11:01  whyisthatyou  阅读(240)  评论(0编辑  收藏  举报