如何获取 ANTLR 词法分析器对象的参数?
How to get a parameter to the ANTLR lexer object?
我正在编写 JAVA 软件来解析 SQL 查询。为此,我将 ANTLR 与 presto.g4 一起使用。
我目前使用的代码非常标准:
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);
我想知道是否可以将一个参数传递给词法分析器,这样词法分析就会因该参数而异?
更新:
我在下面使用了@Mike 的建议,我的词法分析器现在继承自内置词法分析器并添加了谓词函数。我现在的问题是纯粹的语法问题。
这是我的字符串定义:
STRING
: '\'' ( '\' .
| '\\' . {HelperUtils.isNeedSpecialEscaping(this)}? // match \ followed by any char
| ~[\'] // match anything other than \ and '
| '\'\'' // match ''
)*
'\''
;
我有时有一个奇怪的转义查询,谓词 returns 为真。例如:
select
table1(replace(replace(some_col,'\'',''),'\"' ,'')) as features
from table1
当我尝试解析它时,我得到:
'\'',''),'
作为单个字符串。
我该如何处理?
I wonder whether it's possible to pass a parameter to the lexer so the lexing will be different depends on that parameter?
不,词法分析器独立于解析器工作。解析时不能引导词法分析器。
我不知道你需要参数做什么,但你提到了 SQL,所以让我介绍一个我多年来使用的解决方案:谓词。
在 MySQL(这是我使用的方言)中,语法因 MySQL 版本号而异。所以在我的语法中,我使用语义谓词来关闭和打开属于特定版本的语言部分。方法很简单:
test:
{serverVersion < 80014}? ADMIN_SYMBOL
| ONLY_SYMBOL
;
ADMIN 关键字仅适用于 < 8.0.14 的版本(仅作为示例,实际情况并非如此),而 ONLY 关键字在任何版本中都是可能的选择。
变量 serverVersion
是我派生解析器的基础 class 的成员。可以通过以下方式指定:
options {
superClass = MySQLBaseRecognizer;
tokenVocab = MySQLLexer;
}
词法分析器也派生自 class,因此版本号在词法分析器和解析器中都可用(除了其他重要设置,如 SQL 模式)。使用这种方法,您还可以为谓词实现更复杂的功能,这需要额外的处理。
找到完整的代码和语法
我正在编写 JAVA 软件来解析 SQL 查询。为此,我将 ANTLR 与 presto.g4 一起使用。 我目前使用的代码非常标准:
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);
我想知道是否可以将一个参数传递给词法分析器,这样词法分析就会因该参数而异?
更新: 我在下面使用了@Mike 的建议,我的词法分析器现在继承自内置词法分析器并添加了谓词函数。我现在的问题是纯粹的语法问题。
这是我的字符串定义:
STRING
: '\'' ( '\' .
| '\\' . {HelperUtils.isNeedSpecialEscaping(this)}? // match \ followed by any char
| ~[\'] // match anything other than \ and '
| '\'\'' // match ''
)*
'\''
;
我有时有一个奇怪的转义查询,谓词 returns 为真。例如:
select
table1(replace(replace(some_col,'\'',''),'\"' ,'')) as features
from table1
当我尝试解析它时,我得到: '\'',''),'
作为单个字符串。 我该如何处理?
I wonder whether it's possible to pass a parameter to the lexer so the lexing will be different depends on that parameter?
不,词法分析器独立于解析器工作。解析时不能引导词法分析器。
我不知道你需要参数做什么,但你提到了 SQL,所以让我介绍一个我多年来使用的解决方案:谓词。
在 MySQL(这是我使用的方言)中,语法因 MySQL 版本号而异。所以在我的语法中,我使用语义谓词来关闭和打开属于特定版本的语言部分。方法很简单:
test:
{serverVersion < 80014}? ADMIN_SYMBOL
| ONLY_SYMBOL
;
ADMIN 关键字仅适用于 < 8.0.14 的版本(仅作为示例,实际情况并非如此),而 ONLY 关键字在任何版本中都是可能的选择。
变量 serverVersion
是我派生解析器的基础 class 的成员。可以通过以下方式指定:
options {
superClass = MySQLBaseRecognizer;
tokenVocab = MySQLLexer;
}
词法分析器也派生自 class,因此版本号在词法分析器和解析器中都可用(除了其他重要设置,如 SQL 模式)。使用这种方法,您还可以为谓词实现更复杂的功能,这需要额外的处理。
找到完整的代码和语法