我正在编写一个JAVA软件来解析SQL查询。为了做到这一点,我在presto.g4中使用了ANTLR。我目前使用的代码非常标准:
PrestoLexer lexer = new PrestoLexer(
new CaseChangingCharStream(CharStreams.fromString(query), true));
lexer.removeErrorListeners();
lexer.addErrorListener(errorListener);
CommonTokenStream tokens = new CommonTokenStream(lexer);
PrestoParser parser = new PrestoParser(tokens);我想知道是否有可能将一个参数传递给lexer,这样词汇就会有所不同,这取决于这个参数?
更新:我在下面使用了@Mike的建议,我的现在继承了内置的lexer,并添加了一个谓词函数。我现在的问题是纯粹的语法。
这是我的字符串定义:
STRING
: '\'' ( '\\' .
| '\\\\' . {HelperUtils.isNeedSpecialEscaping(this)}? // match \ followed by any char
| ~[\\'] // match anything other than \ and '
| '\'\'' // match ''
)*
'\''
;有时,我有一个带有奇怪转义的查询,其中谓词返回true。例如:
select
table1(replace(replace(some_col,'\\'',''),'\"' ,'')) as features
from table1当我试图解析它时,我得到的是:‘\’,''),
就像一根绳子。我怎么处理这件事?
发布于 2020-12-30 07:52:34
我不知道您需要这个参数做什么,但是您提到了SQL,所以让我介绍一个多年来我使用的解决方案:谓词。
在MySQL (我使用的方言)中,根据MySQL版本号的不同,语法也不同。因此,在我的语法中,我使用语义谓词来关闭属于特定版本的语言部分。方法很简单:
test:
{serverVersion < 80014}? ADMIN_SYMBOL
| ONLY_SYMBOL
;ADMIN关键字仅适用于版本< 8.0.14 (只是一个示例,在现实中不是这样),而惟一的关键字是任何版本中可能的替代词。
变量serverVersion是我从其中派生解析器的基类的成员。可通过以下方式指定:
options {
superClass = MySQLBaseRecognizer;
tokenVocab = MySQLLexer;
}lexer也是从该类派生出来的,因此在lexer和解析器中都有版本号(除了SQL模式等其他重要设置之外)。使用这种方法,您还可以为谓词实现更复杂的函数,这需要额外的处理。
您可以在MySQL工作台Github存储库上找到完整的代码+语法。
发布于 2020-12-29 12:17:55
我想知道是否有可能将一个参数传递给lexer,这样词汇就会有所不同,这取决于这个参数?
不,lexer独立于解析器工作。您不能在解析时直接使用lexer。
https://stackoverflow.com/questions/65491654
复制相似问题