首先,让我们来谈谈import
。
import
所做的与C/C++语言中的#include
类似,它将src复制到dst。如果存在冲突,ANTLR4将尝试合并两个语法。
使用import
是一种令人沮丧,因为有这么多的限制:
并不是每一种语法可以导入所有其他类型的语法的。
- Lexer语法可以导入词法分析器语法。
- 解析器语法可以导入解析器语法。
- 组合语法可以导入词法分析器或语法分析器语法。
导入时,文法中的options
将被忽略。
- 当导入时,
mode
在词法分析器语法中是不允许的。
因此,实际上不能在解析器语法中导入词法分析器语法,因为它们不是同一种类型。但是,您可以在组合语法中导入词法分析器。
这些限制缩小了import
的使用范围。我认为使用import
的最佳情况是将大的词法分析器或语法分析器分成几个部分,以便于管理。
现在,请记住,我们无法使用import
将语法分析器语法导入语法分析器语法中?这就是为什么我们需要tokenVocab
,这是为了在解析器或组合语法中使用单独的词法分析器而设计的。
的上面的结论将是:
- 在词法语法,你只能使用
import
。
- 在语法分析器中,您只能使用
import
导入另一个语法分析器。您只能使用tokenVocab
来使用另一个词法分析器语法。
- 在组合的语法,你可以同时使用
import
和tokenVocab
对于第三个,现在有什么区别?
区别在于使用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会很成功。