2015-03-03 142 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会很成功。

相关问题