提升精神重复解析器意外行为

时间:2015-03-09 22:07:51

标签: boost-spirit-qi

在Windows 7下使用boost 1.57 spirit :: qi 我正在研究ipv6解析器,必须误解重复解析器指令的工作原理。 鉴于以下(简化)

ipv6part = repeat(1, 4)[xdigit];

ipv6address =
-(repeat(1,4)[ipv6part >> lit(':')] >> ipv6part) >> 
    lit("::") >> ipv6part >> lit(':') >> ipv6part
| ...

我希望匹配以下地址:

  

1111:5555 :: FFFF:EEEE
  1111:2222:5555 :: FFFF:EEEE
  1111:2222:3333:5555 :: FFFF:EEEE
  1111:2222:3333:4444:5555 :: ffff:eeee

然而,当我测试时,唯一匹配是repeat子句中的最大值:

  

1111:2222:3333:4444:5555 :: ffff:eeee

现在,明确指定每个组合符合所有情况:

ipv6address =
-(repeat(1)[ipv6part >> lit(':')] >> ipv6part) >> 
    lit("::") >> ipv6part >> lit(':') >> ipv6part
| -(repeat(2)[ipv6part >> lit(':')] >> ipv6part) >> 
    lit("::") >> ipv6part >> lit(':') >> ipv6part
| -(repeat(3)[ipv6part >> lit(':')] >> ipv6part) >> 
    lit("::") >> ipv6part >> lit(':') >> ipv6part
| -(repeat(4)[ipv6part >> lit(':')] >> ipv6part) >> 
    lit("::") >> ipv6part >> lit(':') >> ipv6part
| ...

但这看起来很傻;它不对。

1 个答案:

答案 0 :(得分:0)

当解析的其余部分失败时,重复(N,M)似乎不会回溯。 所以,如果输入是 11:22:55 :: ff:ee ,则重复部分需要 11:22:55:离开:ff:ee < / strong>失败了。

我不确定文档是否是预期的行为,但解决方法是不要将冒号作为重复中的最后一个字符,这样可以避免分裂&#39的问题; ::&#39; ,像这样

ipv6address =
-(ipv6part >> repeat(1,4)[lit(':') >> ipv6part]) >> lit("::") >> ipv6part >> lit(':') >> ipv6part