ANTLR4:import和tokenVocab之间有什么区别?

8
import语句或tokenVocab选项可用于解析器语法中,以重用词法分析器语法。
Sam Harwell 建议始终使用tokenVocab而不是import [1]。
importtokenVocab之间有什么区别吗?如果没有区别(而Sam建议使用tokenVocab),那么为什么需要import语句?
引用:
[1] 我实际上建议完全避免在ANTLR中使用import语句。改用tokenVocab特性。[Sam Harwell]
请参阅:ANTLR4:在词法分析器命令中无法识别常量值
1个回答

21
首先,让我们谈一下importimport与C/C++语言中的#include类似,即将src复制到dst。如果有冲突,ANTLR4会尝试合并两个语法。
使用import有点令人沮丧,因为有很多限制:
1.并非所有类型的语法都可以导入其他类型的语法。 - Lexer语法可以导入Lexer语法。 - Parser语法可以导入Parser语法。 - Combined语法可以导入Lexer或Parser语法。
2.导入时,语法中的选项将被忽略。
3.导入时,在Lexer语法中不允许使用mode。
因此,您实际上不能在解析器语法中导入词法分析器语法,因为它们不属于同一种类型。但是您可以在组合语法中导入Lexer语法。
这些限制已经缩小了import的用途范围。我认为使用import的最佳情况是将大型词法或解析器语法分解为几个部分,以便更易于管理。
现在,还记得我们不能使用import在解析器语法中导入词法分析器语法吗?这就是为什么我们需要tokenVocab,它是设计用于在解析器或组合语法中使用单独的词法分析器。
总之,以上结论为:
- 在Lexer语法中,您只能使用import。 - 在解析器语法中,您只能使用import导入另一个解析器语法。您只能使用tokenVocab来使用另一个词法分析器语法。 - 在组合语法中,您可以同时使用importtokenVocab
对于第三个,现在有什么区别?
区别在于使用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,那么就没有问题。但是如果我们尝试编译G3,则会出现错误:
错误(160):G3.g4:3:21:找不到./G1.tokens令牌文件。
然而,如果我们先编译G1,就会生成G1.tokens文件。现在编译G3将会成功。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接