sql - 有没有人成功使用 Antlr v4 为 Hive 生成 javascript
问题描述
我的目标是用 javascript 解析 SQL(特别是 Hive)语句,最好是 Nodejs。我从看起来很有希望的 node-sql-parser 开始。但是,我发现很多情况下,解析器无法识别有效的 SQL,例如 select 子句中列上的多个嵌套函数,以及 SQL 中具有大量连接、联合等的多个 AND 子句。(我已记录为问题但需要一些时间)。
我决定看看 Antlr v4。我按照 Hive SQL 语法的入门步骤进行操作。(https://github.com/apache/hive/blob/master/hplsql/src/main/antlr4/org/apache/hive/hplsql/Hplsql.g4);我使用 Antlr 为 JavaSCript 生成的解析器词法分析器和侦听器 - 到目前为止一切都很好。然后我尝试了一个简单的测试,如下所示:
const HplsqlLexer = require('./HplsqlLexer');
const HplsqlParser = require('./HplsqlParser');
const input = "select * from table_a"
var chars = new antlr4.InputStream(input);
var lexer = new HplsqlLexer.HplsqlLexer(chars);
var tokens = new antlr4.CommonTokenStream(lexer);
var parser = new HplsqlParser.HplsqlParser(tokens);
parser.buildParseTrees = true;
const tree = parser.program();
我相信“program()”是解析器的入口点,但我可能是错的。这在 parser.program() 行给了我“ReferenceError:_input 未定义”。我质疑 Hplsql.g4 是否可能缺少某些东西,但排除了这一点。然后我查看了 HplsqlParser.js 中生成的代码 - 我在顶部添加了 var _input = "" 并重新运行;然后它抱怨说没有定义LT。感觉像兔子洞。
接下来的步骤包括运行 Antlr 解析器的 Java 版本,然后是 Calcite。(hplsql.org 不是我要找的)。
节点--版本:v15.2.1。任何建议或指示都会有所帮助。
解决方案
正如 kaby76 在评论中提到的:语法包含目标特定(Java)代码。您需要用 TypeScipt 代码替换所有 Java{
代码}?
。
例如,这个 Java 代码:
{!_input.LT(2).getText().equalsIgnoreCase("TRANSACTION")}?
可以改写成这样:
{this._input.LT(2).text.toUpperCase() !== 'TRANSACTION'}?
(未经测试!)
编辑
我迅速进行了全局搜索并_input\.LT\((\d+)\).getText\(\)\.equalsIgnoreCase\("(\w+)"\)
用替换字符串替换了模式(this._input.LT(\1).text.toUpperCase() === '\2')
,这导致了以下语法:https ://gist.github.com/bkiers/bb68b25ed03cf6c8ffae2709606d27a5
编辑 2
我很惊讶 Antlr 甚至有一个用于解析器生成的 -Dlanguage=JavaScript 标志。如果它本质上仍然是 Java,那又有什么意义呢?
确保在-Dlanguage=JavaScript
JavaScript 中生成词法分析器和解析器类。它不做的是重写语义谓词,它们只是“按原样”复制。请注意,始终建议不要使用语义谓词,而是将此类目标特定代码移动到访问者或侦听器类中。
推荐阅读
- c - 如何在 Atollic TrueStudio 中包含 CMSIS-DSP 标头
- enums - 如何在 Clojure 的 Java 类中引用枚举
- javascript - 每次我们创建字符串文字时,javascript是否都会创建一个新实例?
- python - 如何从字典创建 2Darray?
- java - 未知主机异常仅在 ONEPLUS 6T 和其他 Pie 手机中运行良好
- redis - 无法从应用引擎 flex SSH 连接 redis (Memorystore)
- java - 使用多个 if 语句进行 Junit 测试
- android - 连接到具有 BLE Android 的设备
- javascript - 如何拼接嵌套 JSON 的每个第 0 个索引特定键“逻辑”和值?
- android - RxKotlin 中的区块链并继续