簡體   English   中英

如何獲取 ANTLR 詞法分析器 object 的參數?

[英]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 的建議,我的詞法分析器現在繼承自內置詞法分析器並添加了一個謂詞 function。 我的問題現在是純語法。

這是我的字符串定義:


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

我有時會有一個奇怪的 escaping 查詢,謂詞返回 true。 例如:


select 
table1(replace(replace(some_col,'\\'',''),'\"' ,'')) as features 
from table1

當我嘗試解析它時,我得到:'\'',''),'

作為單個字符串。 我該如何處理這個?

我不知道你需要這個參數做什么,但你提到了 SQL,所以讓我介紹一個我多年來使用的解決方案:謂詞。

在 MySQL(這是我使用的方言)中,語法因 MySQL 版本號而異。 所以在我的語法中,我使用語義謂詞來關閉和打開屬於特定版本的語言部分。 方法很簡單:

test:
    {serverVersion < 80014}? ADMIN_SYMBOL
    | ONLY_SYMBOL
;

ADMIN 關鍵字僅適用於 < 8.0.14 的版本(只是一個示例,實際上並非如此),而 ONLY 關鍵字是任何版本的可能替代方案。

變量serverVersion是基礎 class 的成員,我從中派生出解析器。 可以通過以下方式指定:

options {
    superClass = MySQLBaseRecognizer;
    tokenVocab = MySQLLexer;
}

詞法分析器也派生自 class,因此版本號在詞法分析器和解析器中都可用(除了其他重要設置,如 SQL 模式)。 使用這種方法,您還可以為需要額外處理的謂詞實現更復雜的函數。

您可以在MySQL Workbench Github 存儲庫中找到完整的代碼 + 語法。

我想知道是否可以將參數傳遞給詞法分析器,因此詞法分析會有所不同取決於該參數?

不,詞法分析器獨立於解析器工作。 解析時不能指導詞法分析器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM