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 <L33Simpson+boostuser@gmail.com> wrote:
That is _exactly_ what I was after! Thanks so much.

On Wed, May 6, 2009 at 3:11 AM, Eric Niebler <eric@boostpro.com> 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 <boost/xpressive/xpressive_static.hpp>
#include <boost/xpressive/regex_actions.hpp>
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