2010-08-21 65 views
1

我使用屬性傳播爲玩具語言構建語法樹。我在我的if語句的定義中遇到了一個問題,很難從錯誤消息中分辨出來,但我認爲rhs屬性沒有摺疊到預期的屬性中。它應該崩潰到我認爲的tuple <double,Statement,optional<Statement>>Boost Spirit自動排除問題

錯誤:C:\Program Files (x86)\CodeBlocks\MinGW\boost_1_43_0\boost\variant\variant.hpp|1293|error: no matching function for call to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list3<boost::recursive_wrapper<Lang::CompoundStatement>, boost::recursive_wrapper<Lang::IfStatement>, Lang::VarStatement> > >::initializer_node, mpl_::int_<1> >, boost::mpl::l_iter<boost::mpl::list2<boost::recursive_wrapper<Lang::IfStatemen [error cuts out here]

謝謝。

P.S. 我無法讓代碼正確顯示,這裏有一個純文本版本:http://freetexthost.com/a3smzx0zk5

P.P.S. 我提供一些資訊。 它可以工作,如果我刪除"else" >>並將> statement更改爲>> statement,但"else" >> statement應崩潰到只是聲明。明確地將「else」創建爲qi :: lit並沒有幫助。

回答

3

序列operator>>()和期望operator>()在屬性處理方面不能很好地混合。如果在同一表達式中使用兩個運算符,則整體屬性不會變平。如果您僅使用其中一種,則會發生這種情況。

爲此屬性由表達式暴露:

if_statement %= "if" > qi::double_ > statement >> -("else" > statement) ; 

是:

tuple <tuple <double, Statement>, optional<Statement> > 

這也解釋了你的編譯問題。重寫epression爲:

if_statement %= "if" > qi::double_ > statement > -("else" > statement) ; 

雖然(不改變語義)應該解決這個問題。

+0

好想法,但它仍然無法正常工作。如果我刪除了其他東西,這是我唯一的線索。 – Dave 2010-08-23 19:53:58

+0

好吧,那麼我想看一個我可以編譯的小型自包含測試。否則幾乎不可能知道什麼是錯的。 – hkaiser 2010-08-24 00:09:41

0

呃,好像我不能編輯或發表評論,所以我必須發表這個答案。

我通過將規則拆分爲if語句規則和if-else語句規則來解決問題。但是,這個問題又回到了我對init聲明的定義中。
init_decl %= identifier >> -('=' >> expression) ;

identifier %= lexeme[(alpha | char_('')) >> *(alnum | char('_'))] ;

expression %= literal ;

literal %= real_literal | string_literal ;

real_literal %= double_ ;

string_literal %= lexeme['"' >> *(char_ - '"') >> '"'] ;

像以前

同樣的問題。但是,我第一次沒有做好調查問題的工作。

In member function 'void boost::variant::convert_construct(T&, int, mpl_::false_) [with T = const Lang::Elements::Expression, T0_ = double, T1 = std::basic_string, std::allocator >, T2 = boost::detail::variant::void_, T3 = boost::detail::variant::void_, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::vari

即此方法:

模板<類型名稱Ť>

void convert_construct(
     T& operand 
    , int 
    , mpl::false_ = mpl::false_() // is_foreign_variant 
    ) 
{ 
    // NOTE TO USER : 
    // Compile error here indicates that the given type is not 
    // unambiguously convertible to one of the variant's types 
    // (or that no conversion exists). 
    // 
    indicate_which(
      initializer::initialize(
       storage_.address() 
      , operand 
      ) 
     ); 
}</code> 

記住此誤差從init_decl表達(%)=發起。該表達式中唯一的變體是Expression對象所包含的表達式規則的屬性值。這個錯誤似乎是說一個變體(對象Expression包含的類型)試圖從一個Expression實例化自己,但我在代碼中的任何地方都看不到它。無論如何,我將演員操作符添加到了公開其基礎變體的Expression結構中,但仍然出現了錯誤。

調用上面的方法,該方法是這樣的:

模板<類型名牛逼>

variant(const T& operand) { convert_construct(operand, 1L); }</code> 

好像它試圖調用此方法代替:

模板<類型名稱變>

void convert_construct(
     Variant& operand 
    , long 
    , mpl::true_// is_foreign_variant 
    ) 
{ 
    convert_copy_into visitor(storage_.address()); 
    indicate_which(
      operand.internal_apply_visitor(visitor) 
     ); 
}</code> 

這是編譯器誤解,是這個錯誤的原因?