作者:秦乐0_707 | 来源:互联网 | 2023-05-19 17:06
该import
语句或tokenVocab
选项可以放在一个解析器语法重用词法语法.
Sam Harwell建议总是使用tokenVocab
而不是import
[1].
有什么区别import
和tokenVocab
?如果没有区别(Sam说要使用tokenVocab
),为什么要import
声明呢?
[1]我实际上建议在ANTLR中完全避免使用import语句.请改用tokenVocab功能.[山姆哈威尔]
请参阅lexer命令中的ANTLR4:无法识别的常量值
1> skyline75489..:
首先,我们来谈谈import
.
import
与#include
C/C++语言类似的是什么,它将src复制到dst.如果存在冲突,ANTLR4将尝试合并两个语法.
使用import
有点令人沮丧,因为有很多限制:
并非每种语法都可以导入其他类型的语法.
Lexer语法可以导入词法分析器.
解析器语法可以导入解析器语法.
组合语法可以导入词法分析器或解析器语法.
导入时,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会很成功.