Damn. I've just implemented the whole algorithm using your suggested approach, and I've come across a problem.I don't have a simple way to describe my dilemma, so a complex way will ave to do :-/ First of, I'll describe the way I have implemented your suggestion. First off, I utilize an expression of the form ((s1 = expr) >> keep(nil[action(_,...)])) for each significant component of the expression. At the very end of the expression I add keep(nil[consolidate_combination(...)])
~before(nil), which ensures that all combinations are tried. Of course, this solution is fundamentally flawed. This is because each action is executed immediately and thus leaves garbage state information around when the expression backtracks and attempts a different match.
I see that your example does not suffer from this flaw since the example
expression is quite linear and does not contain many significant components
(read: captures). Unfortunately, I need to be able to apply this to
arbitrarily complex expressions.
Ideally I would like to add a function which looks like the 'keep' function,
but does not turn off backtracking. Such that i could do something like the
following:
expr = apply( (+alpha)[action_a(_,...)] >> ((+alpha)[action_b(_,...)] |
(+alnum)[action_c(_,...)]) >> eos >> nil[consolidate]) >> ~before(nil);
the idea being that action_a/action_b/action_c store state
information, consolidate
gathers up that state information (resetting it for the next combination)
and apply would execute all the semantic actions currently queued within it.
I have been looking into the implementation details of xpressive and it
seems that what I need to do is somehow apply a slightly modified version of
xpressive::detail::end_matcher to the expression. Of course, I have no idea
how this would best be achieved so I would need your help to do such a
thing.
I hope this description is adequate, but I'm sure it probably not. Let me
know if/where it needs more explaining.
Thanks,
Lee Simpson
On Wed, May 6, 2009 at 1:20 PM, Lee Simpson
wrote:
That is _exactly_ what I was after! Thanks so much.
On Wed, May 6, 2009 at 3:11 AM, Eric Niebler
wrote: Eric Niebler wrote:
Lee Simpson wrote:
Hi,
First let me say. Awesome library and thanks for releasing it to the world.
Thanks!
I'm looking for a way to apply all the currently queued semantic actions
_without_ turning off backtracking. So, as the manual suggests, keep manages to apply the queued actions but it also turns off backtracking.
<snip>
Any ideas?
You don't have to turn off backtracking for the whole regex. You can use keep() in a few strategic places within your regex as follows:
sregex rx = ... >> keep(nil[ /*semantic action*/ ]) >> ...;
"nil" always succeeds and consumes 0 characters. It's a way to cause the semantic action to execute immediately. Would something like that help you?
In case I wasn't clear, here is a little program that demonstrates what I was getting at:
#include <string> #include <iostream> #include
#include using namespace boost::xpressive; int main() { std::string text = "abcd"; sregex rx = // Match some stuff and save some submatches (s1= +alpha) >> (s2= +alpha) >> eos >> // Display the submatches eagerly. keep(nil[ref(std::cout) << s1 << ", " << s2 << "\n"]) >> // Cause the fail and backtrack. ~before(nil);
regex_match(text, rx);
return 0; }
For me, this dispays:
abc, d ab, cd a, bcd
HTH,
-- Eric Niebler BoostPro Computing http://www.boostpro.com _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users