[英]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.