diff --git a/doc/tutorial.qbk b/doc/tutorial.qbk index 0ab8a7e3..aa41e503 100644 --- a/doc/tutorial.qbk +++ b/doc/tutorial.qbk @@ -169,6 +169,17 @@ followed /immediately/ by a `double`, but I inserted a space after the comma. The same failure to parse would occur if I put a space before the comma, or before or after the list of `double`s. +One more thing: there is a much better way to write the parser above. Instead +of repeating the `double_` subparser, we could have written this: + + bp::double_ % ',' + +That's semantically identical to `bp::double_ >> *(',' >> bp::double_)`. This +pattern _emdash_ some bit of input repeated one or more times, with a +separator between each instance _emdash_ comes up so often that there's an +operator specifically for that, `operator%`. We'll be using that operator +from now on. + [endsect] [section A Trivial Example That Gracefully Handles Whitespace] @@ -2054,7 +2065,7 @@ If we wanted to use a `std::deque` as the attribute type of our rule: // Attribute changed to std::deque. bp::rule> doubles = "doubles"; - auto const doubles_def = bp::double_ >> *(',' >> bp::double_); + auto const doubles_def = bp::double_ % ','; BOOST_PARSER_DEFINE_RULES(doubles); int main() @@ -2064,9 +2075,9 @@ If we wanted to use a `std::deque` as the attribute type of our rule: } So, the attribute flexibility is still available, but only *within* the rule -_emdash_ the parser `bp::double_ >> *(',' >> bp::double_)` can parse into a -`std::vector` or a `std::deque`, but the rule `doubles` must -parse into only the exact attribute it was declared to generate. +_emdash_ the parser `bp::double_ % ','` can parse into a `std::vector` +or a `std::deque`, but the rule `doubles` must parse into only the +exact attribute it was declared to generate. The reason for this is that, inside the rule parsing implementation, there is code something like this: @@ -2088,7 +2099,7 @@ themselves to get the attribute flexibility we want across our code: namespace bp = boost::parser; // We only need to write the definition once... - auto const generic_doubles_def = bp::double_ >> *(',' >> bp::double_); + auto const generic_doubles_def = bp::double_ % ','; bp::rule> vec_doubles = "vec_doubles"; auto const & vec_doubles_def = generic_doubles_def; // ... and re-use it, diff --git a/example/rule_intro.cpp b/example/rule_intro.cpp index 6c3701f4..b3ec5ee9 100644 --- a/example/rule_intro.cpp +++ b/example/rule_intro.cpp @@ -19,7 +19,7 @@ namespace bp = boost::parser; bp::rule> doubles = "doubles"; //] //[ rule_intro_rule_definition_rule_def -auto const doubles_def = bp::double_ >> *(',' >> bp::double_); +auto const doubles_def = bp::double_ % ','; //] //[ rule_intro_rule_definition_macro BOOST_PARSER_DEFINE_RULE(doubles); diff --git a/example/semantic_actions.cpp b/example/semantic_actions.cpp index 95f3e430..35bfc36f 100644 --- a/example/semantic_actions.cpp +++ b/example/semantic_actions.cpp @@ -26,8 +26,7 @@ int main() }; //] auto const action_parser = bp::double_[action]; - auto const success = - bp::parse(input, action_parser >> *(',' >> action_parser), bp::ws); + auto const success = bp::parse(input, action_parser % ',', bp::ws); if (success) { std::cout << "You entered:\n"; diff --git a/example/trivial_skipper.cpp b/example/trivial_skipper.cpp index d182add0..0f7378b1 100644 --- a/example/trivial_skipper.cpp +++ b/example/trivial_skipper.cpp @@ -18,8 +18,7 @@ int main() std::string input; std::getline(std::cin, input); - auto const result = - bp::parse(input, bp::double_ >> *(',' >> bp::double_), bp::ws); + auto const result = bp::parse(input, bp::double_ % ',', bp::ws); if (result) { std::cout << "Great! It looks like you entered:\n";