
介绍
calcite是使用javcc+FreeMarker集成的,借助FreeMarker支持用户自定义自己的语义、语法分析及处理,扩展性极强。
calcite基于javacc扩展的解析SQL的实现在core包中:

前置知识学习:03、编译原理实践 - JavaCC解析表达式并生成抽象语法树、自定义Calcite的SQL语法后再来尝试阅读源码
关于Parser.jj中的${xxx}来源
变量参数均来自:

例如:${parser.class}指的就是自定义类名

入口是什么?
我们在使用calcite解析的时候是如下代码操作的:
public static void main(String[] args) throws SqlParseException {
// 解析配置 - mysql设置
SqlParser.Config mysqlConfig = SqlParser.configBuilder()
// 定义解析工厂
.setParserFactory(SqlParserImpl.FACTORY)
.setLex(Lex.MYSQL)
.build();
// 创建解析器
SqlParser parser = SqlParser.create("", mysqlConfig);
// Sql语句
String sql = "xxx";
// 解析sql
SqlNode sqlNode = parser.parseQuery(sql);
System.out.println(sqlNode.toSqlString(OracleSqlDialect.DEFAULT));
}
核心代码:parseQuery(sql)方法
public SqlNode parseQuery(String sql) throws SqlParseException {
this.parser.ReInit(new StringReader(sql));
//1
return this.parseQuery();
}
public SqlNode parseQuery() throws SqlParseException {
try {
//2、自定义parseSqlStmtEof
return this.parser.parseSqlStmtEof();
} catch (Throwable var2) {
Throwable ex = var2;
throw this.handleException(ex);
}
}
这个parseSqlStmtEof()从何而来?Parser.jj中定义好的


看下下面解析实现:可以看到优先匹配的是我们自定义部分

parser.statementParserMethods
对应的就是config.fmpp中配置的:

自定义模板替换

模板替换:

评论区请在客户端页面查看