ABNF语法0<pchar>规则匹配逻辑、空串定义及ANTLR4转换方法
问题
在RFC 3986中定义了如下ABNF规则:
path-empty = 0<pchar>
为简化说明,此处假设pchar的定义为:
pchar = 'a' / 'b' / 'c'
待澄清的问题如下:
path-empty实际匹配的内容是什么,匹配执行逻辑是怎样的?- 初步推测该规则匹配空字符串(对应正则为
^(?![\s\S])),若推测成立:- 定义时为什么要引用
pchar? - ABNF里有没有不需要引用其他规则、直接匹配空串的更简洁写法?
- 定义时为什么要引用
- 该ABNF规则如何转换为符合ANTLR4规范的语法规则?
解答
匹配内容与执行逻辑
你的推测完全正确,path-empty仅匹配长度为0的空字符串,不会匹配任何包含a/b/c或其他字符的非空内容。
匹配逻辑来自ABNF的标准重复规则:数字直接加规则名的写法,代表「恰好重复匹配该规则指定的次数」。0<pchar>的含义就是恰好匹配pchar 0次——量词只要满足匹配次数要求就算匹配成功,0次意味着完全不消费任何输入字符,直接返回空串作为匹配结果。
规则引用原因与空串简洁写法
- 引用
pchar是RFC规范的上下文一致性设计要求:URI路径部分的所有子规则都共享统一的合法字符集,哪怕是空路径,也属于路径的合法组成部分。写0<pchar>可以明确空路径的语义是「0个合法路径字符」,而非任意无约束的空内容,整个路径规则体系的字符约束完全统一;后续如果调整pchar的合法字符范围,也不需要单独修改path-empty的定义。 - ABNF原生支持直接匹配空串的写法,不需要引用任何其他规则:规则等号右侧留空即可,比如
path-empty =,部分ABNF实现也支持显式写""代表空串,两种写法的语义和0<pchar>完全一致。
转换为ANTLR4规则的方法
ANTLR4中空规则体的语义就是匹配空串、不消费任何输入,和该ABNF规则的语义完全对应,有两种等价合法写法:
- 最简洁、最符合ANTLR惯例的写法,直接用空规则体表示空串:
// 先定义pchar规则,和前置假设对应 pchar: 'a' | 'b' | 'c'; // 匹配空串,对应path-empty规则 pathEmpty: ;
- 如果需要在规则中显式保留和
pchar的关联、体现原规则的设计意图,可以加语义断言保证匹配位置不会出现pchar,语义和原规则完全等价:
pathEmpty: {!(_input.LA(1) == 'a' || _input.LA(1) == 'b' || _input.LA(1) == 'c')}? ;
注意:如果是参考RFC 3986原文的
0*pchar定义(即匹配0次或多次pchar,对应可空的路径段),直接写pathEmpty: pchar*;即可,但结合path-empty的命名语义,标准定义就是匹配0个pchar的空串,第一种空规则体写法是正确的。
内容的提问来源于stack exchange,提问作者Oliver
相关产品推荐
相关产品推荐

