Boost.Qi 可选解析器出现编译器错误
Boost.Qi compiler error with optional parser
我是一个 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>’
任何人都清楚我在这里做错了什么吗?
解决这个问题的方法是使用 phrase_parse
和 qi::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))
您的原始语法如下所示(带有一些格式):
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_
)
我是一个 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>’
任何人都清楚我在这里做错了什么吗?
解决这个问题的方法是使用 phrase_parse
和 qi::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))
您的原始语法如下所示(带有一些格式):
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_
)