Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2008-07-02 00:20:46


Author: eric_niebler
Date: 2008-07-02 00:20:43 EDT (Wed, 02 Jul 2008)
New Revision: 46980
URL: http://svn.boost.org/trac/boost/changeset/46980

Log:
document behavior of actions in independent sub-expressions
Text files modified:
   trunk/libs/xpressive/doc/actions.qbk | 31 +++++++++++++++++++++++++++++--
   1 files changed, 29 insertions(+), 2 deletions(-)

Modified: trunk/libs/xpressive/doc/actions.qbk
==============================================================================
--- trunk/libs/xpressive/doc/actions.qbk (original)
+++ trunk/libs/xpressive/doc/actions.qbk 2008-07-02 00:20:43 EDT (Wed, 02 Jul 2008)
@@ -107,7 +107,7 @@
 sub-expression initially matches, but ultimately fails because the rest of the
 regular expression fails to match, is the action executed at all?
 
-The answers are that actions are executed /lazily/. When a sub-expression
+The answer is that by default, actions are executed /lazily/. When a sub-expression
 matches a string, its action is placed on a queue, along with the current
 values of any sub-matches to which the action refers. If the match algorithm
 must backtrack, actions are popped off the queue as necessary. Only after the
@@ -124,13 +124,40 @@
     // questionable ones.
     sregex rex = +( _d [ ++ref(i) ] >> '!' );
     regex_search(str, rex);
- assert( i == 2 );
+ assert( i == 2 );
 
 The action `++ref(i)` is queued three times: once for each found digit. But
 it is only /executed/ twice: once for each digit that precedes a `'!'`
 character. When the `'?'` character is encountered, the match algorithm
 backtracks, removing the final action from the queue.
 
+[h3 Immediate Action Execution]
+
+When you want semantic actions to execute immediately, you can wrap the
+sub-expression containing the action in a [^[funcref boost::xpressive::keep keep()]].
+`keep()` turns off back-tracking for its sub-expression, but it also causes
+any actions queued by the sub-expression to execute at the end of the `keep()`.
+It is as if the sub-expression in the `keep()` were compiled into an
+independent regex object, and matching the `keep()` is like a separate invocation
+of `regex_search()`. It matches characters and executes actions but never backtracks
+or unwinds. For example, imagine the above example had been written as follows:
+
+ int i = 0;
+ std::string str("1!2!3?");
+ // count all the digits.
+ sregex rex = +( keep( _d [ ++ref(i) ] ) >> '!' );
+ regex_search(str, rex);
+ assert( i == 3 );
+
+We have wrapped the sub-expression `_d [ ++ref(i) ]` in `keep()`. Now, whenever
+this regex matches a digit, the action will be queued and then immediately
+executed before we try to match a `'!'` character. In this case, the action
+executes three times.
+
+[note Like `keep()`, actions within [^[funcref boost::xpressive::before before()]]
+and [^[funcref boost::xpressive::after after()]] are also executed early when their
+sub-expressions have matched.]
+
 [h3 Lazy Functions]
 
 So far, we've seen how to write semantic actions consisting of variables and


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk