Boost logo

Boost Users :

Subject: Re: [Boost-users] Xpressive, symantic actions and combination enumeration
From: Lee Simpson (L33Simpson+boostuser_at_[hidden])
Date: 2009-05-06 05:52:39

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

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

I hope this description is adequate, but I'm sure it probably not. Let me
know if/where it needs more explaining.

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 <eric_at_[hidden]> 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
>> _______________________________________________
>> Boost-users mailing list
>> Boost-users_at_[hidden]

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at