如何获取ANTLR lexer对象的参数?
我正在编写一个JAVA软件来解析SQL查询。为了做到这一点,我将ANTLR与presto.g4一起使用。 我目前使用的代码非常标准:如何获取ANTLR lexer对象的参数?,antlr,sql-parser,Antlr,Sql Parser,我正在编写一个JAVA软件来解析SQL查询。为了做到这一点,我将ANTLR与presto.g4一起使用。 我目前使用的代码非常标准: PrestoLexer lexer = new PrestoLexer( new CaseChangingCharStream(CharStreams.fromString(query), true)); lexer.removeErrorListeners(); lexer.addErrorListener(
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,以便lexing根据该参数而有所不同
更新:
我在下面使用了@Mike的建议,我的lexer现在继承了内置的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
当我试图解析它时,我得到:
“\”,“),”
作为一个单一的字符串。
我怎么处理这个
我想知道是否有可能将一个参数传递给lexer,以便lexing根据该参数而有所不同
不,lexer独立于解析器工作。解析时不能直接使用lexer。我不知道您需要该参数做什么,但您提到了SQL,所以让我介绍一个多年来使用的解决方案:谓词 在MySQL(我使用的方言)中,语法根据MySQL版本号的不同而不同。因此,在我的语法中,我使用语义谓词来关闭和打开属于特定版本的语言部分。方法很简单:
test:
{serverVersion < 80014}? ADMIN_SYMBOL
| ONLY_SYMBOL
;
lexer也是从该类派生的,因此lexer和parser中都有版本号(除了其他重要的设置,如SQL模式)。通过这种方法,您还可以为需要额外处理的谓词实现更复杂的函数
您可以在上找到完整的代码+语法。我明白了。谢谢你的回答!不客气@nir99谢谢@Mike!这实际上非常有用。我现在对解析还有其他问题。我将在原始帖子中详细说明。@Nir99最好为SO的语法部分打开一个新问题,这将允许其他人插话寻求解决方案。已经打开了一个-
options {
superClass = MySQLBaseRecognizer;
tokenVocab = MySQLLexer;
}