Attribute compatibility and Semantic actions
Joel de Guzman <[email protected]> Tue, 15 Feb 2011 12:17:54 +0800
| Newsgroups | gmane.comp.parsers.spirit.general,gmane.comp.parsers.spirit.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi Y'all,
I've been thinking about attribute compatibility and semantic actions
recently. I am also having a keen eye on IRC and the recent threads
regarding the topic. If you've read Hartmut's excellent article on
"Attribute Propagation and Attribute Compatibility":
http://tinyurl.com/46ndfsv
you now are aware that the current behavior of Qi is to synthesize the
expected attribute (using attribute propagation rules) when an action
/a/ is attached to a parser /p/:
p[a] // propagate the expected attribute of p to a
For example, if you have this:
(+char_)[f(_1)]
f will always get a std::vector<char>. This vector is synthesized by
the action class which handles semantic actions. This is also the
reason why semantic actions in Qi are frowned upon. The synthesis of
the propagated attribute is not efficient especially if the client
passes in the attribute herself. There's always an unwanted conversion
to and from the synthesized attribute and the actual attribute.
It also leads to confusion because the nice attribute compatibility
rules now do not apply.
I am now of the opinion that this behavior should be changed.
Consider this code:
void f(std::string const& s)
{
std::cout << "parsing got: " << s << std::endl;
}
qi::rule<char const*, std::string()> r;
r %= (+qi::char_)[phoenix::bind(&f, qi::_1)];
If we pass in a std::string attribute to qi::parse with the
rule above, I see no reason why it should not compile. Currently,
if you do this, attribute compatibility is disabled and Qi
synthesizes a std::vector<char>. Thus, the compiler will complain
that it is trying to call f with the wrong attribute std::vector<char>
instead of std::string.
(Note: some might notice the use of %=. This is needed to force
the rule to be an auto rule and make it use the attribute
passed in by the client.)
Now, I committed code to the boost trunk that allows attribute
compatibility on semantic actions. This code (Boost trunk) will
kick in when you
#define BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT
This is necessary because the code is **will break existing code**.
Without the define, the old behavior will work as usual.
So, what are the advantages:
1) The nice attribute compatibility rules can now apply to
semantic actions giving us uniform behavior
2) Parsers with semantic actions will now be a lot more
efficient. While semantic-action-less attribute grammars
are cool, a lot of times, we still have to resort to SAs
to do some computation. This behavior will again give SAs
equal footing in terms of performance.
Regards,
--
Joel de Guzman
http://www.boostpro.com
http://boost-spirit.com
------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb