Boost.Qi编译器错误与可选的解析器

时间:2016-11-01 18:46:10

标签: c++ boost boost-spirit

我是一名Boost.Qi的初学者,所以我正在尝试一些简单的例子来试图让我了解它。我正在尝试解析一个看起来像这样的字符串:

A:1     B:2           C:3

字符串中的每个组件之间有任意数量的空格。 A:等部分是固定的,我想解析整数值。上例中字符串的第三个组成部分C:3是可选的。我想出了以下简单示例来测试此应用程序的Boost.Qi:

#include <boost/optional.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>

namespace qi = boost::spirit::qi;

int main()
{
    std::string s = "A:1   B:2          C:3";

    int a, b;
    boost::optional<int> c;

    if (!qi::parse(s.begin(), s.end(),
        qi::lit("A:") >> qi::int_ >> +qi::space >> "B:" >> qi::int_ >> 
            -(+qi::space >> "C:" >> qi::int_), a, b, c))
    {
        std::cout << "failed to parse" << std::endl;
    }

    std::cout << a << ' ' << b << ' ' << c.value_or(-1) << std::endl;
}

然而,这无法编译(在C ++ 11模式下使用Boost v1.58和g ++ 5.4.0)。在典型的C ++模板错误消息中,我发现以下内容:

spirit.cc:15:55:   required from here
/usr/include/boost/spirit/home/support/container.hpp:130:12: error: ‘int’ is not a class, struct, or union type
     struct container_value

spirit.cc:15:55:   required from here
/usr/include/boost/spirit/home/qi/detail/pass_container.hpp:316:66: error: no type named ‘type’ in ‘struct boost::spirit::traits::container_value<int, void>’
             typedef typename traits::container_value<Attr>::type value_type;
                                                                  ^
/usr/include/boost/spirit/home/qi/detail/pass_container.hpp:329:15: error: no type named ‘type’ in ‘struct boost::spirit::traits::container_value<int, void>’

任何人都明白我在这里做错了吗?

2 个答案:

答案 0 :(得分:4)

解决此问题的方法可以是使用phrase_parseqi::space船长:

if (!qi::phrase_parse(s.begin(), s.end(),
        qi::lit("A:") >> qi::int_ >> "B:" >> qi::int_ >> -("C:" >> qi::int_), qi::space, a, b, c))

答案 1 :(得分:3)

您的原始语法看起来像这样(带有一些格式):

   qi::lit("A:")
>> qi::int_
>> +qi::space
>> qi::lit("B:")
>> qi::int_
>> -(  +qi::space
    >> qi::lit("C:")
    >> qi::int_
    )

注意每个终端生成的属性类型非常重要:

此外,请注意compound attributes的相关规则。

基于此,你实际上有:

  • 整数
  • 字符向量(由于+
  • 整数
  • 可选(由于-)元组(由于>>
    • 字符向量(由于+
    • 整数

这与您将parse称为。

的内容不符

关键是使用omit指令来抑制您不关心的属性。

在这种情况下,正确的语法是:

   qi::lit("A:")
>> qi::int_
>> qi::omit[+qi::space]
>> qi::lit("B:")
>> qi::int_
>> -(  qi::omit[+qi::space]
    >> qi::lit("C:")
    >> qi::int_
    )