2015-03-03 143 views
3

import語句或tokenVocab選項可以放在解析器語法中以重用詞法分析器語法。ANTLR4:import和tokenVocab有什麼不同?

Sam Harwell建議始終使用tokenVocab而不是import [1]。

importtokenVocab之間有什麼區別嗎?如果沒有區別(Sam說使用tokenVocab),那麼爲什麼要有import聲明?

[1] I actually recommend avoiding the import statement altogether in ANTLR. Use the tokenVocab feature instead. [Sam Harwell]

ANTLR4: Unrecognized constant value in a lexer command

回答

6

首先,讓我們來談談import

import所做的與C/C++語言中的#include類似,它將src複製到dst。如果存在衝突,ANTLR4將嘗試合併兩個語法。

使用import是一種令人沮喪,因爲有這麼多的限制:

  1. 並不是每一種語法可以導入所有其他類型的語法的。

    • Lexer語法可以導入詞法分析器語法。
    • 解析器語法可以導入解析器語法。
    • 組合語法可以導入詞法分析器或語法分析器語法。
  2. 導入時,文法中的options將被忽略。

  3. 當導入時,mode在詞法分析器語法中是不允許的。

因此,實際上不能在解析器語法中導入詞法分析器語法,因爲它們不是同一種類型。但是,您可以在組合語法中導入詞法分析器。

這些限制縮小了import的使用範圍。我認爲使用import的最佳情況是將大的詞法分析器或語法分析器分成幾個部分,以便於管理。

現在,請記住,我們無法使用import將語法分析器語法導入語法分析器語法中?這就是爲什麼我們需要tokenVocab,這是爲了在解析器或組合語法中使用單獨的詞法分析器而設計的。

的上面的結論將是:

  • 在詞法語法,你只能使用import
  • 在語法分析器中,您只能使用import導入另一個語法分析器。您只能使用tokenVocab來使用另一個詞法分析器語法。
  • 在組合的語法,你可以同時使用importtokenVocab

對於第三個,現在有什麼區別?

區別在於使用tokenVocab需要先編譯詞法分析器,因爲tokenVocab只是一個聲明需要另一個語法的選項。雖然使用import並不需要,因爲它會將src複製到當前語法。

grammar G1; 
r: B; 

G2.g4

grammar G2; 
import G1 

G3.g4

grammar G3; 
options { tokenVocab=G2; } 
t: A; 

如果我們直接

G1.g4:

例如,有三個語法文件編譯G2,它會好的。但是,如果我們試圖編譯G3,總會有錯誤:

error(160): G3.g4:3:21: cannot find tokens file ./G1.tokens

但是,如果我們先編譯G1,會有G1.tokens。現在編譯G3會很成功。

相關問題