Boost.Fusion适应结构中的默认值的Boost.Spirit.Qi语法

时间:2018-07-06 20:01:47

标签: c++ grammar default-value boost-spirit-qi boost-fusion

struct coordinate {
  int x;
  int y;
  int z;
};

BOOST_FUSION_ADAPT_STRUCT(
  coordinate,
  (int, x)
  (int, y)
  (int, z)
)

template <typename Iterator>
struct coordinate_grammar : qi::grammar<Iterator, coordinate(), ascii::space_type>
{
  coordinate_grammar()
  :
    coordinate_grammar::base_type(start),
    optional_x(-(qi::int_ >> ':')),
    optional_z(-('@' >> qi::int_)),
    start(optional_x >> qi::int_ >> optional_z)
  {
  }

  qi::rule<Iterator, int, ascii::space_type> optional_x;
  qi::rule<Iterator, int, ascii::space_type> optional_z;
  qi::rule<Iterator, coordinate(), ascii::space_type> start;
};

我想将0设置为x的默认值,并将1000设置为z的默认值。

输入->所需输出:

  • 200:400@300-> [200,400,300]
  • 200:400-> [200,400,1000]
  • 400@300-> [0,400,300]
  • 400-> [0,400,1000]

当未为可选的optional_xoptional_z解析器指定值时,如何修改规则语法以提供默认值? / p>

1 个答案:

答案 0 :(得分:1)

诀窍是重新考虑“可选”的概念...

optional_x(-(qi::int_ >> ':')),
optional_z(-('@' >> qi::int_)),

我们知道,-前缀表示此规则可以指定0或1次,因此使其成为可选。

但是,我们实际上并不希望有一个“可选”值。我们需要已解析的值或默认值。这不是可选的,只是一个或另一个。

通过修改规则语法,何时可以更好地描述我们的意图。

optional_x((qi::int_ >> ':') | qi::attr(0)),
optional_z(('@' >> qi::int_) | qi::attr(1000)),

现在,在处理选项时,如果您尚未提供xz的值,那么qi:attr(...)将代表您提供一个值。