【问题标题】:ANTLR4: Any difference between import and tokenVocab?ANTLR4:import 和 tokenVocab 有什么区别?
【发布时间】:2015-03-03 10:10:28
【问题描述】:
【问题讨论】:
标签:
parsing
import
grammar
antlr4
lexical-analysis
【解决方案1】:
首先,让我们谈谈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,就会出现错误:
error(160): G3.g4:3:21: 找不到令牌文件./G1.tokens
但是,如果我们先编译G1,就会有G1.tokens。现在编译 G3 就成功了。