假设我有这个语法来解析ip地址,其中每个八位位组可以是十进制或十六进制(这是一个虚构的例子,用来说明我现实世界需求的本质(:
grammar Ips;
ips: ip (WS ip)*;
ip: FOUR_OCTETS;
FOUR_OCTETS: OCTET '.' OCTET '.' OCTET '.' OCTET;
OCTET: HEX_OCTET | DEC_OCTET;
HEX_OCTET: 'x[A-Fa-f][A-Fa-f]?;
DEC_OCTET: [0-2][0-9]?[0-9]?;
WS: [ trn]+ -> skip; // skip spaces, tabs, newlines
使用基本侦听器遍历树,当解析器规则"ip"匹配时,是否有方法确定FOUR_OCTES lexer令牌的组成?我想知道每个OCET是HEX_OCET还是DEC_OCTET。
在解析器规则的上下文对象中,我看到了一种获取FOUR_OCTES令牌的方法,但没有任何进一步深入该令牌的方法。
我意识到,我可以简单地将lexer令牌表示为解析器规则,但随后我必须在现实世界的用例中显式地处理空白和其他混乱的方面。
在ANTLR4中没有什么比子标记更好的了。lexer按照lexer语法定义扫描输入,并只显示最终结果(包括开始和停止索引、类型、通道和其他一些内容(。最终结果是一个单独的令牌,而不是为解析器规则生成的解析上下文(因此没有子令牌或类似的令牌(。
如果你可以接受点周围的空白,你可以定义ip规则,这样:
ip: OCTET DOT OCTET DOT OCTET DOT OCTET;
这将允许检查各个八位字节。否则,您只能获取结果字符串,将其按点拆分,然后手动处理4个子字符串。