鉴于合成用户定义类型的语法,我该如何编写另一种语法:
在下面的示例中,我按照Boost Spirit文档创建了一个解析器foo_parser
,它合成了foo_struct
类型的值。我想编写第二个解析器bar_parser
,它重用foo_parser
但合成了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;
};
*/
答案 0 :(得分:1)
我之前已经设计过这种 - 有点 - hacky方式来解决问题
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]邮件列表:
derived base
以下是完整的样本:
#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