sql—有人成功使用antlr v4为hive生成javascript吗

3vpjnl9f  于 2021-06-24  发布在  Hive
关注(0)|答案(1)|浏览(977)

我的目标是用javascript解析sql(特别是hive)语句,最好是nodejs。我从node-sql解析器开始,它看起来很有前途。但是,我发现有很多情况下解析器无法识别有效的sql,比如select子句中一列上的几个嵌套函数,以及sql中有许多连接、联合等的多个and子句(我记录为issue,但这需要一些时间)。
我决定看看antlrv4。我遵循了hivesql语法的入门步骤(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:\u input is not defined”。我怀疑hplsql.g4是否遗漏了什么,但排除了这种可能性。然后我查看了hplsqlparser.js中生成的代码-我在顶部添加了var\u input=“”并重新运行;但它没有定义。感觉像个兔子洞。
接下来的步骤包括运行antlr解析器的java版本,然后运行calcite(我要找的不是hplsql.org)。
节点——版本:v15.2.1。任何建议或建议都会有帮助。

ldfqzlk8

ldfqzlk81#

正如kaby76在注解中提到的:语法包含特定于目标(java)的代码。您需要替换 { 以及 }? 使用typescipt代码。
例如,以下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中生成lexer和parser类。它没有做的是重写语义 predicate ,而语义 predicate 只是“按原样”复制。请注意,通常建议不要使用语义 predicate ,而是将此类特定于目标的代码移到visitor或listener类中。

相关问题