PrevUpHomeNext

Callback Parsing

In most parsing cases, being able to generate an attribute that represents the result of the parse, or being able to parse into such an attribute, is sufficient. Sometimes, it is not. If you need to parse a very large chunk of text, the generated attribute may be too large to fit in memory. In other cases, you may want to generate attributes sometimes, and not others. callback_rules exist for these kinds of uses. A callback_rule is just like a rule, except that it allows the rule's attribute to be returned to the caller via a callback, as long as the parse is started with a call to callback_parse() instead of parse(). Within a call to parse(), a callback_rule is identical to a regular rule.

For a rule with no attribute, the signature of a callback function is void (tag), where tag is the tag-type used when declaring the rule. For a rule with an attribute attr, the signature is void (tag, attr). For instance, with this rule:

boost::parser::callback_rule<struct foo_tag> foo = "foo";

this would be an appropriate callback function:

void foo_callback(foo_tag)
{
    std::cout << "Parsed a 'foo'!\n";
}

For this rule:

boost::parser::callback_rule<struct bar_tag, std::string> bar = "bar";

this would be an appropriate callback function:

void bar_callback(bar_tag, std::string const & s)
{
    std::cout << "Parsed a 'bar' containing " << s << "!\n";
}
[Important] Important

In the case of bar_callback(), we don't need to do anything with s besides insert it into a stream, so we took it as a const lvalue reference. Boost.Parser moves all attributes into callbacks, so the signature could also have been void bar_callback(bar_tag, std::string s) or void bar_callback(bar_tag, std::string && s).

You opt into callback parsing by parsing with a call to callback_parse() instead of parse(). If you use callback_rules with parse(), they're just regular rules. This allows you to choose whether to do "normal" attribute-generating/attribute-assigning parsing with parse(), or callback parsing with callback_parse(), without rewriting much parsing code, if any.

The only reason all rules are not callback_rules is that you may want to have some rules use callbacks within a parse, and have some that do not. For instance, if you want to report the attribute of callback_rule r1 via callback, r1's implementation may use some rule r2 to generate some or all of its attribute.

See Parsing JSON With Callbacks for an extended example of callback parsing.


PrevUpHomeNext