2012-04-10 55 views
2

中間值給定一個語法,其合成一個用戶定義的類型,如何可以寫另一個語法是:再合成與升壓::精神::氣

  1. 重用第一語法。
  2. 使用底層第一個類型的值合成第二個不同的類型?

在下面的例子中,我已經按照升壓精神文檔來創建一個解析器,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

我沒有時間通過​​編譯器來運行它,但我認爲富在你bar_parser的聲明錯誤。如果不是:'foo_parser foo' – 2012-04-10 08:11:13

+0

@AndréNo.'foo_parser'只能獲取一個模板參數 – sehe 2012-04-10 09:01:38

回答

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一個解決方案,但我不能得到它工作,也看到了[精神-一般]郵件列表:

下面是一個完整的示例:

#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