boost.xpressive: using placeholders with custom (check()) assertions

Greetings. Xpressive allows the use of object placeholders in semantic actions, which are being replaced by actual object references during the match, like in this simple example: placeholder<string> p_string; sregex r = (expr)[do_something(p_string, _)]; When executed, do_something() functor will receive a reference to string, as expected. However, if functor is wrapped with assertion, this won't work: sregex r = (expr)[check(do_something(p_string, _))]; Compilation will fail, because do_something has no method which accepts xpressive::placeholder<> objects. And even if such method was to be added, there's no obvious way to obtain a run-time reference to actual object out of placeholder. This leads to some question: 1. Is there any trick allowing to use placeholders within check() assertions? 2. Alternatively, may there be a way to declare a semantic action functor, returning bool, in such a way, that it will act as custom assertion? It seems to me, that some cunning trick involving boost::proto construct may exist, even though I can't think of any particular way to do so. In light of the above, I also thought about sort of feature request: 3. Sometimes, custom assertion applies only to a part of the match, something like: *((expr)[check(cond)] | _) That is, a desire is to consume everything, until some specific "expr" token matches a precondition. However, raised assertion will not stop the matching, because it only applies to one branch of the regexp. It could be very handy if there was a way to signal from assertion that a larger containing expression matched it results. Thanks.

On 6/16/2010 3:04 AM, Alex Dubov wrote:
Greetings.
Xpressive allows the use of object placeholders in semantic actions, which are being replaced by actual object references during the match, like in this simple example:
placeholder<string> p_string; sregex r = (expr)[do_something(p_string, _)];
When executed, do_something() functor will receive a reference to string, as expected.
However, if functor is wrapped with assertion, this won't work:
sregex r = (expr)[check(do_something(p_string, _))];
Compilation will fail, because do_something has no method which accepts xpressive::placeholder<> objects.
It should if it is a lazy function. How is do_something defined? Can you send a self-contained program that demonstrates the problem you're having?
And even if such method was to be added, there's no obvious way to obtain a run-time reference to actual object out of placeholder.
xpressive will do that for you.
This leads to some question: 1. Is there any trick allowing to use placeholders within check() assertions? 2. Alternatively, may there be a way to declare a semantic action functor, returning bool, in such a way, that it will act as custom assertion? It seems to me, that some cunning trick involving boost::proto construct may exist, even though I can't think of any particular way to do so.
In light of the above, I also thought about sort of feature request: 3. Sometimes, custom assertion applies only to a part of the match, something like:
*((expr)[check(cond)] | _)
That is, a desire is to consume everything, until some specific "expr" token matches a precondition.
Yes, that should work.
However, raised assertion will not stop the matching, because it only applies to one branch of the regexp. It could be very handy if there was a way to signal from assertion that a larger containing expression matched it results.
I don't understand that last sentence. Can you clarify? -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler
On 6/16/2010 3:04 AM, Alex Dubov wrote:
Greetings.
However, if functor is wrapped with assertion, this won't work:
sregex r = (expr)[check(do_something(p_string, _))];
Compilation will fail, because do_something has no method which accepts xpressive::placeholder<> objects.
It should if it is a lazy function. How is do_something defined? Can you send a self-contained program that demonstrates the problem you're having?
In the particular case I was working on, I was forced to stop on every match anyway, so I'm not using check() right now. I'll, however, try to recreate the problematic example to see if I keep encountering the problem.
In light of the above, I also thought about sort of feature request: 3. Sometimes, custom assertion applies only to a part of the match, something like:
*((expr)[check(cond)] | _)
That is, a desire is to consume everything, until some specific "expr" token matches a precondition.
Yes, that should work.
However, raised assertion will not stop the matching, because it only applies to one branch of the regexp. It could be very handy if there was a way to signal from assertion that a larger containing expression matched it results.
I don't understand that last sentence. Can you clarify?
I thought about something on the lines of: sregex large_expr(*((expr)[check(cond())] | _)); With cond() being able to use a statement <something>.set_matched(large_expr) to signal that "large_expr" as a whole can be considered matched for now.

On 6/25/2010 7:35 AM, Alex Dubov wrote:
Eric Niebler
writes: On 6/16/2010 3:04 AM, Alex Dubov wrote:
However, raised assertion will not stop the matching, because it only applies to one branch of the regexp. It could be very handy if there was a way to signal from assertion that a larger containing expression matched it results.
I don't understand that last sentence. Can you clarify?
I thought about something on the lines of:
sregex large_expr(*((expr)[check(cond())] | _));
With cond() being able to use a statement
<something>.set_matched(large_expr)
to signal that "large_expr" as a whole can be considered matched for now.
Oh. No, xpressive's flow control would not allow for random jumps like that. It would seriously mess up how xpressive does backtracking. Sorry. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler
On 6/16/2010 3:04 AM, Alex Dubov wrote:
Greetings.
However, if functor is wrapped with assertion, this won't work:
sregex r = (expr)[check(do_something(p_string, _))];
Compilation will fail, because do_something has no method which accepts xpressive::placeholder<> objects.
It should if it is a lazy function. How is do_something defined? Can you send a self-contained program that demonstrates the problem you're having?
I'm using boost-1.41 and gcc-4.4.2. The error I'm receiving compiling an
example:
--------------------------------------------------------------------
testreg1.cpp:51: instantiated from here
/usr/include/boost/proto/context/default.hpp:426: error: no match for call to
‘(const check_a_impl) (const boost::xpressive::detail::action_arg

On 6/25/2010 8:32 AM, Alex Dubov wrote:
const sregex expr2(*(as_xpr('a')[check(check_a(_cnt, 5))] | _)); /* ^ this check() causes a problem */
You found a bug in xpressive. I don't think anybody has ever tried to use a placeholder (_cnt above) in a custom assertion. I've just committed a fix to trunk and added a test for this. I'll do my best to get this fix in the next release. For now, you *should* be able to just apply the attached patch to xpressive/detail/core/matcher/predicate_matcher.hpp. Thanks for the report. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler
On 6/25/2010 8:32 AM, Alex Dubov wrote:
const sregex expr2(*(as_xpr('a')[check(check_a(_cnt, 5))] | _)); /* ^ this check() causes a problem */
You found a bug in xpressive. For now, you *should* be able to just apply the attached patch to xpressive/detail/core/matcher/predicate_matcher.hpp.
Thanks for the report.
Thank you for the fix. Now xpressive is even more fun to use.
participants (2)
-
Alex Dubov
-
Eric Niebler