[spirit][qi] strange attribute composition when using expectation points

Hi, I get a different attribute composition depending on the use of expectation points. Here is a small example: //////////////////////////////////////////////////////////////////////////////////////////////// // BOOST_FUSION_DEFINE_STRUCT( (client), input, (int, index1) (std::string, text) (int, index2) ) namespace client { namespace fusion = boost::fusion; namespace phoenix = boost::phoenix; namespace qi = boost::spirit::qi; namespace char_enc = boost::spirit::iso8859_1; template <typename Iterator, typename Skipper> struct line_grammar : qi::grammar<Iterator, input(), Skipper> { line_grammar() : line_grammar::base_type(line) { using qi::int_; using qi::omit; using char_enc::char_; using qi::lit; line = int_ >> lit(",") #ifdef USE_EXPECTATION_POINT > *(char_ - ( "," >> int_ ) ) #else >> *(char_ - ( "," >> int_ ) ) #endif >> lit(",") >> int_ ; } qi::rule<Iterator, input(), Skipper > line; }; bool read_line( ) { typedef line_grammar<std::string::const_iterator, char_enc::space_type> grammar; grammar gr; // Our grammar input line_read; std::string source = "1,x,2"; std::string::const_iterator iter = source.begin(); std::string::const_iterator end = source.end(); bool r = phrase_parse(iter, end, gr, char_enc::space, line_read); return r && iter == end; } } // ///////////////////////////////////////////////////////////////////////////////////////////////////////// If USE_EXPECTATION_POINT is not defined then parsing succeeds and line_read == {1, "x", 2 }. But if USE_EXPECTATION_POINT is defined then parsing also succeeds but line_read == {1, "x\0x2", 0 }. So, it seems that expectation points somehow break the semantics of attribute composition. Tobias

On 9/10/2010 3:52 PM, Löw, Tobias (Evonik Energy Services GmbH) wrote:
Hi,
I get a different attribute composition depending on the use of expectation points. Here is a small example:
//////////////////////////////////////////////////////////////////////////////////////////////// //
BOOST_FUSION_DEFINE_STRUCT( (client), input, (int, index1) (std::string, text) (int, index2) )
namespace client {
namespace fusion = boost::fusion; namespace phoenix = boost::phoenix; namespace qi = boost::spirit::qi; namespace char_enc = boost::spirit::iso8859_1;
template<typename Iterator, typename Skipper> struct line_grammar : qi::grammar<Iterator, input(), Skipper> { line_grammar() : line_grammar::base_type(line) { using qi::int_; using qi::omit; using char_enc::char_; using qi::lit;
line = int_ >> lit(",") #ifdef USE_EXPECTATION_POINT > *(char_ - ( ",">> int_ ) ) #else >> *(char_ - ( ",">> int_ ) ) #endif >> lit(",") >> int_
;
}
qi::rule<Iterator, input(), Skipper> line;
};
bool read_line( ) { typedef line_grammar<std::string::const_iterator, char_enc::space_type> grammar;
grammar gr; // Our grammar
input line_read;
std::string source = "1,x,2"; std::string::const_iterator iter = source.begin(); std::string::const_iterator end = source.end(); bool r = phrase_parse(iter, end, gr, char_enc::space, line_read);
return r&& iter == end; }
}
// /////////////////////////////////////////////////////////////////////////////////////////////////////////
If USE_EXPECTATION_POINT is not defined then parsing succeeds and line_read == {1, "x", 2 }. But if USE_EXPECTATION_POINT is defined then parsing also succeeds but line_read == {1, "x\0x2", 0 }. So, it seems that expectation points somehow break the semantics of attribute composition.
Yes. That is a known problem. Mixing >> with > is indeed a problem with attribute composition. For now, there is no quick solution yet. You'll just have to tweak the composed attribute type or use semantic actions to "compile" your attribute. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

I get a different attribute composition depending on the use of expectation points. Here is a small example:
////////////////////////////////////////////////////////////////////////// ////////////////////// //
BOOST_FUSION_DEFINE_STRUCT( (client), input, (int, index1) (std::string, text) (int, index2) )
namespace client {
namespace fusion = boost::fusion; namespace phoenix = boost::phoenix; namespace qi = boost::spirit::qi; namespace char_enc = boost::spirit::iso8859_1;
template <typename Iterator, typename Skipper> struct line_grammar : qi::grammar<Iterator, input(), Skipper> { line_grammar() : line_grammar::base_type(line) { using qi::int_; using qi::omit; using char_enc::char_; using qi::lit;
line = int_ >> lit(",") #ifdef USE_EXPECTATION_POINT > *(char_ - ( "," >> int_ ) ) #else >> *(char_ - ( "," >> int_ ) ) #endif >> lit(",") >> int_
;
}
qi::rule<Iterator, input(), Skipper > line;
};
bool read_line( ) { typedef line_grammar<std::string::const_iterator, char_enc::space_type> grammar;
grammar gr; // Our grammar
input line_read;
std::string source = "1,x,2"; std::string::const_iterator iter = source.begin(); std::string::const_iterator end = source.end(); bool r = phrase_parse(iter, end, gr, char_enc::space, line_read);
return r && iter == end; }
}
// ////////////////////////////////////////////////////////////////////////// ///////////////////////////////
If USE_EXPECTATION_POINT is not defined then parsing succeeds and line_read == {1, "x", 2 }. But if USE_EXPECTATION_POINT is defined then parsing also succeeds but line_read == {1, "x\0x2", 0 }. So, it seems that expectation points somehow break the semantics of attribute composition.
Generally, expectation points in terms of attribute handling do not mix well with 'normal' sequences. The parser expression int_ >> *(char_ - ( "," >> int_ ) ) >> int_ exposes as its attribute a tuple<int, vector<char>, int>, while the expression int_ > *(char_ - ( "," >> int_ ) ) >> int_ will expose a tuple<tuple<int, vector<char>>, int>, which is the reason for the problems you're seeing. Regards Hartmut --------------- http://boost-spirit.com
participants (3)
-
Hartmut Kaiser
-
Joel de Guzman
-
Löw, Tobias (Evonik Energy Services GmbH)