可以将import
语句或tokenVocab
选项放入解析器语法中以重用词法分析器语法。
Sam Harwell建议始终使用tokenVocab
而不是import
[1]。
import
和tokenVocab
之间有什么区别吗?如果没有区别(Sam说要使用tokenVocab
),为什么要有import
语句?
[1]我实际上建议完全避免使用import语句 ANTLR。请改用tokenVocab功能。 [Sam Harwell]
答案 0 :(得分:10)
首先,我们来谈谈import
。
import
的作用类似于C / C ++语言中的#include
,它将src复制到dst。如果存在冲突,ANTLR4将尝试合并两个语法。
使用import
有点令人沮丧,因为有很多限制因素:
并非每种语法都可以导入其他类型的语法。
导入时,语法中的options
将被忽略。
mode
。因此,您实际上无法在解析器语法中导入词法分析器语法,因为它们不是同一类型。但是你可以用组合语法导入词法分析器。
这些限制缩小了import
的使用范围。我认为使用import
的最佳情况是将一个大词法分析器或解析器语法分成几个部分,以便更容易管理。
现在,请记住我们不能使用import
在解析器语法中导入词法分析器语法?这就是为什么我们需要tokenVocab
,它被设计为在解析器或组合语法中使用单独的词法分析器。
上述结论将是:
import
。 import
导入另一个解析器语法。您只能使用tokenVocab
来使用其他词法分析器语法。import
和tokenVocab
对于第三个,现在有什么不同?
不同之处在于使用tokenVocab
需要首先编译词法分析器,因为tokenVocab
只是一个声明需要另一个语法的选项。使用import
时不需要,因为它会将src复制到当前语法。
例如,有三个语法文件:
G1.g4
grammar G1;
r: B;
G2.g4
grammar G2;
import G1
G3.g4
grammar G3;
options { tokenVocab=G2; }
t: A;
如果我们直接编译G2,那就OK了。但是如果我们尝试编译G3,就会出现错误:
错误(160):G3.g4:3:21:找不到令牌文件./G1.tokens
但是,如果我们先编译G1,那么就会有G1.tokens。现在编译G3会很成功。