首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获取ANTLR lexer对象的参数?

如何获取ANTLR lexer对象的参数?
EN

Stack Overflow用户
提问于 2020-12-29 11:48:29
回答 2查看 228关注 0票数 0

我正在编写一个JAVA软件来解析SQL查询。为了做到这一点,我在presto.g4中使用了ANTLR。我目前使用的代码非常标准:

代码语言:javascript
复制
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,并添加了一个谓词函数。我现在的问题是纯粹的语法。

这是我的字符串定义:

代码语言:javascript
复制
STRING
    : '\'' ( '\\' .
           | '\\\\'  .  {HelperUtils.isNeedSpecialEscaping(this)}?       // match \ followed by any char
           | ~[\\']       // match anything other than \ and '
           | '\'\''       // match ''
           )*
      '\''
    ;

有时,我有一个带有奇怪转义的查询,其中谓词返回true。例如:

代码语言:javascript
复制
select 
table1(replace(replace(some_col,'\\'',''),'\"' ,'')) as features 
from table1

当我试图解析它时,我得到的是:‘\’,''),

就像一根绳子。我怎么处理这件事?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-30 07:52:34

我不知道您需要这个参数做什么,但是您提到了SQL,所以让我介绍一个多年来我使用的解决方案:谓词。

在MySQL (我使用的方言)中,根据MySQL版本号的不同,语法也不同。因此,在我的语法中,我使用语义谓词来关闭属于特定版本的语言部分。方法很简单:

代码语言:javascript
复制
test:
    {serverVersion < 80014}? ADMIN_SYMBOL
    | ONLY_SYMBOL
;

ADMIN关键字仅适用于版本< 8.0.14 (只是一个示例,在现实中不是这样),而惟一的关键字是任何版本中可能的替代词。

变量serverVersion是我从其中派生解析器的基类的成员。可通过以下方式指定:

代码语言:javascript
复制
options {
    superClass = MySQLBaseRecognizer;
    tokenVocab = MySQLLexer;
}

lexer也是从该类派生出来的,因此在lexer和解析器中都有版本号(除了SQL模式等其他重要设置之外)。使用这种方法,您还可以为谓词实现更复杂的函数,这需要额外的处理。

您可以在MySQL工作台Github存储库上找到完整的代码+语法。

票数 1
EN

Stack Overflow用户

发布于 2020-12-29 12:17:55

我想知道是否有可能将一个参数传递给lexer,这样词汇就会有所不同,这取决于这个参数?

不,lexer独立于解析器工作。您不能在解析时直接使用lexer。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65491654

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档