[proto] [ was Re: [spirit2] Trivial parser crashes ]

Joel de Guzman wrote:
Joel de Guzman wrote:
sm4 wrote:
Oops - seems formatting got in the way.
Hope this is better:
Ooops, I missed your reply. Its better to post spirit related questions to spirit's mailing list. I'm re-posting this there.
Ok, this looks like a bug in handling aliases of the form:
r1 %= r2;
where r1 and r2 are rules with the same type. A quick workaround is to copy the rhs rule:
r1 %= r2.copy();
Eric, It seems to be a problem with Spirit2's usage of proto extends. Here's what's happening: 1) Rule uses proto::extends 2) Rule implements operator %= On expressions: r %= some-expression; The rule's operator%= kicks in. However, on expressions: r %= r2; // r and r2 has the same type Then proto %= kicks in leaving it as a no-op. Nothing happens. Hence, the rhs is never "auto-assigned" to the lhs. I'm not sure how to deal with this. Do you have a hint? I place the original test code here. Tracing the code, the first %= works as expected while the second and third becomes no-ops calling proto operator %=.
-----------------------------------------------------------------------------------------
#include <boost/config/warning_disable.hpp> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/include/phoenix_operator.hpp> #include <boost/spirit/include/phoenix_fusion.hpp> #include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/include/adapt_struct.hpp>
#include <iostream> #include <string>
using namespace boost::spirit; using namespace boost::spirit::qi; using namespace boost::spirit::ascii; using namespace boost::spirit::arg_names;
namespace phoenix = boost::phoenix;
using phoenix::at_c;
struct key_val { std::string key; std::string value; };
BOOST_FUSION_ADAPT_STRUCT( key_val, (std::string, key) (std::string, value) )
template <typename Iterator> struct my_grammar : grammar<Iterator, key_val(), space_type> { my_grammar() : my_grammar::base_type(start) { quoted_string %= lexeme['"' >> +(char_ - '"') >> '"']; key %= quoted_string; value %= quoted_string;
start = key [at_c<0>(_val) = _1] >> ':' >> value [at_c<1>(_val) = _1] ; }
rule<Iterator, std::string(), space_type> key; rule<Iterator, std::string(), space_type> quoted_string; rule<Iterator, std::string(), space_type> value;
rule<Iterator, key_val(), space_type> start;
};
int main() { typedef std::string::const_iterator citerator; std::string str = "\"x\": \"25\" ";
citerator iter = str.begin(); citerator end = str.end();
my_grammar<citerator> my_parser; key_val kv; phrase_parse(iter, end, my_parser, kv, space); // ASSERTs
return 0; }
----------------------------------------------------------------------------------------- Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Joel de Guzman wrote:
On expressions:
r %= some-expression;
The rule's operator%= kicks in. However, on expressions:
r %= r2; // r and r2 has the same type
Then proto %= kicks in leaving it as a no-op. Nothing happens. Hence, the rhs is never "auto-assigned" to the lhs.
I'm not sure how to deal with this. Do you have a hint? I place the original test code here. Tracing the code, the first %= works as expected while the second and third becomes no-ops calling proto operator %=.
You can disable proto's operator%= by specifying a domain with a grammar to proto::extends as described in the docs. You could also try defining a rule::operator%=(rule) member and see if that one gets picked up. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Joel de Guzman wrote:
I'm not sure how to deal with this. Do you have a hint? I place the original test code here. Tracing the code, the first %= works as expected while the second and third becomes no-ops calling proto operator %=.
I checked and you just need to define an operator%= that takes a non-const RHS. Patch attached. Karma might need a similar patch. -- Eric Niebler BoostPro Computing http://www.boostpro.com Index: rule.hpp =================================================================== --- rule.hpp (revision 49819) +++ rule.hpp (working copy) @@ -90,6 +90,23 @@ } template <typename Expr> + friend rule& operator%=(rule& r, Expr& xpr) + { + typedef spirit::traits::is_component<qi::domain, Expr> is_component; + + // report invalid expression error as early as possible + //~ BOOST_MPL_ASSERT_MSG( + //~ is_component::value, + //~ xpr_is_not_convertible_to_a_parser, ()); + + // temp workaround for mpl problem + BOOST_STATIC_ASSERT(is_component::value); + + r.define(xpr, mpl::true_()); + return r; + } + + template <typename Expr> friend rule& operator%=(rule& r, Expr const& xpr) { typedef spirit::traits::is_component<qi::domain, Expr> is_component;
participants (3)
-
Eric Niebler
-
Eric Niebler
-
Joel de Guzman