前1节我们介绍了 shardingsphere 分表分库的sql解析与重写:
shardingsphere分库分表项目实践4-sql解析&重写-CSDN博客
那么shardingsphere sql 解析底层究竟是怎么实现的呢,其实它直接用了著名的开源软件 antlr .
antlr 介绍:
ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于从语法描述中生成词法分析器、解析器、树分析器和代码生成器。它主要用于解析和处理编程语言、数据格式以及任何基于文本的输入。
-
跨平台支持:ANTLR 是用 Java 编写的,但它可以生成多种目标语言的解析器,例如 Java、C#、Python、JavaScript、Go、Swift、TypeScript 和 C++ 等。这使得它非常灵活,可以集成到各种编程项目中。
-
丰富的语法支持:ANTLR 支持 LL(*) 文法,这意味着它可以处理大量的上下文无关文法,包括一些复杂的语言特性。它提供了强大的语法定义能力,可以方便地定义词法和语法规则。
-
用户友好的语法定义:ANTLR 使用一种类似 EBNF的语法来定义语言规则,这使得语法定义直观且易于理解。
-
内置调试和测试工具:ANTLR 附带了一个可视化的语法调试工具,可以帮助用户调试和测试他们定义的语法,确保解析器的正确性。
-
强大的错误处理:ANTLR 提供了丰富的错误报告和恢复机制,能够在解析过程中提供详细的错误信息,并尝试从错误中恢复,继续解析剩余的输入。
antlr 在其他项目的应用:
antlr 非常成熟、稳定、强大,在其他大量项目中有使用:
Groovy
Jython
Hibernate
OpenJDK 编译器语法项目基于 ANTLR 语法编写的 javac 编译器的实验版本
Twitter 的搜索查询语言
Apache Cassandra
sqlparser 一个基于 ANTLR 的 SQL 解析器项目,用于解析和处理 SQL 语句
基于antlr 自己实现一个简单的sql解析器:
目标: 生成标准的 select 语句解析器,只需要支持单表查询, where 和 order by 就行了。
Lexer(词法分析器)
词法分析器 的主要任务是将输入的字符流转换成一系列的标记(tokens)。每个标记表示源代码中的基本元素,例如关键字、标识符、操作符和分隔符
输入:源代码的字符流。
输出:一系列的标记(tokens)。
lexer grammar SQLLexer;
@header {
package com.example.parser;
}
// Tokens
SELECT: [Ss][Ee][Ll][Ee][Cc][Tt];
FROM: [Ff][Rr][Oo][Mm];
WHERE: [Ww][Hh][Ee][Rr][Ee];
ORDER: [Oo][Rr][Dd][Ee][Rr];
BY: [Bb][Yy];
DESC: [Dd][Ee][Ss][Cc];
AND: [Aa][Nn][Dd];
OR: [Oo][Rr];
EQUAL: '=';
STAR: '*';
COMMA: ',';
SEMICOLON: ';';
QUOTE: '\'';
// Identifiers and literals
ID: [a-zA-Z_][a-zA-Z_0-9]*;
INT: [0-9]+;
STRING: QUOTE (~[\r\n'] | '\'\'' )* QUOTE;
// Whitespace and comments
WS: [ \t\r\n]+ -> skip;
Parser(语法分析器)
语法分析器 的任务是根据词法分析器生成的标记序列,按照特定的语法规则,将这些标记组织成一个语法树(parse tree)。语法树表示了代码的结构和语法关系。
输入:词法分析器生成的标记序列。
输出:语法树(parse tree)或抽象语法树(AST)。
parser grammar SQLParser;
@header {
package com.example.parser;
}
options { tokenVocab=SQLLexer; }
// Entry rule
sql: select_stmt SEMICOLON? ;
// Select statement rule
select_stmt: SELECT select_list FROM table_name where_clause? order_clause? ;
// Select list rule
select_list: STAR | column_list ;
// Column list rule
column_list: column_name (COMMA column_name)* ;
// Table name rule
table_name: ID ;
// Where clause rule
where_clause: WHERE condition (AND condition | OR condition)* ;
// Order clause rule
order_clause: ORDER BY order_element (COMMA order_element)* ;
// Order element rule
order_element: column_name (DESC)? ;
// Condition rule
condition: column_name EQUAL value ;
// Column name rule
column_name: ID ;
// Value rule
value: STRING | INT ;
生成parser 并代码验证:
1. 用maven 的compile ,会自动生成 com.example.parser 目录的 SQLParser 相关代码。
2. 写一个main函数测试一下生成的parser是否能正常工作。
antlr idea 插件:
安装antlr插件,词法、语法文件可以直接用插件辅助编辑和测试,提高效率。
直接打开SQLParser.g4 文件(已经完全写好了), ANTLR Preview 窗口可以输入sql验证语法:
正确的SQL :
select id,name from t_user werhe id=1 order by name desc , 右边会解析成一棵树(AST)
错误的SQL或者语法文件有错误,会显示解析错误 :
将 sql 里面的 select 错误地写成 sele ,则会报错。
本测试项目完整工程源码git库:
https://gitcode.com/zfj321/blog_tutorials/tree/main/antlr