2

给定一个合成用户定义类型的语法,我如何编写另一个语法:

  1. 重用第一个语法。
  2. 使用第一种类型的基础值合成第二种不同的类型?

在下面的示例中,我按照 Boost Spirit 文档创建了一个解析器,foo_parser它合成了一个 type 的值foo_struct。我想编写第二个解析器,bar_parser它重用foo_parser但合成一个不同(但显然相似)的 type 值bar_struct。注释掉的我的幼稚示例会导致壮观的 g++ 烟花。:)

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

namespace s  {
  using namespace boost::spirit;
  using namespace boost::spirit::qi;
  using namespace boost::spirit::ascii;
}

struct foo_struct {
  int i;
  char c;
};

BOOST_FUSION_ADAPT_STRUCT(
  foo_struct,
  (int, i)
  (char, c)
)

struct bar_struct {
  int i;
  char c;
  int j;
};

template <typename Iterator>
struct foo_parser : s::grammar<Iterator, foo_struct()>
{
  foo_parser() : foo_parser::base_type(start) {
    start %= s::int_ >> s::char_ ;
  }

  s::rule<Iterator, foo_struct()> start;
};

/*
BOOST_FUSION_ADAPT_STRUCT(
  bar_struct,
  (int, i)
  (char, c)
  (int, j)
)

template <typename Iterator>
struct bar_parser : s::grammar<Iterator, bar_struct()>
{
  bar_parser() : bar_parser::base_type(start) {
    // reuse a foo_parser
    start %= foo >> s::int_ ;
  }

  foo_parser<Iterator> foo;
  s::rule<Iterator, bar_struct()> start;
};

*/
4

1 回答 1

1

我以前设计过这个 - 有点 - 解决问题的方法

struct mybase { int a,b; };
struct myderived : mybase 
 { 
    mybase& base;
    int c,d; 

     myderived() : base(*this) { }
};

BOOST_FUSION_ADAPT_STRUCT(mybase,    (int,a)(int,b));
BOOST_FUSION_ADAPT_STRUCT(myderived, (mybase,base)(int,c)(int,d));

我更喜欢基于 BOOST_FUSION_ADAPT_ADT 的解决方案,但我无法让它工作,另请参阅 [spirit-general] 邮件列表:

这是一个完整的示例:

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted.hpp>

struct mybase             { int a,b; };
struct myderived : mybase { 
    myderived() : base(*this) { }
    mybase& base;
    int c,d; 
};

BOOST_FUSION_ADAPT_STRUCT(mybase,    (int,a)(int,b));
BOOST_FUSION_ADAPT_STRUCT(myderived, (mybase,base)(int,c)(int,d));

int main()
{
    using namespace boost::spirit::qi;

    const char input[] = "1 2 3 4";
    const char *f(input), *l(f+strlen(input));

    rule<const char*, mybase()   , space_type> base_     = int_ >> int_;
    rule<const char*, myderived(), space_type> derived_  = base_ >> int_ >> int_;

    myderived data;
    bool ok = phrase_parse(f,l,derived_,space,data);

    if (ok) std::cout << "data: " << data.a << ", " << data.b << ", " << data.c << ", " << data.d << "\n";
    else    std::cerr << "whoops\n";

    if (f!=l)
        std::cerr << "left: '" << std::string(f,l) << std::endl;

    return 0;
}

输出:

data: 1, 2, 3, 4
于 2012-04-10T08:09:03.857 回答