2
0
mirror of https://github.com/boostorg/parser.git synced 2026-01-21 17:12:16 +00:00
Files
parser/doc/html/boost_parser/tutorial/callback_parsing.html
2024-12-08 17:19:48 -06:00

107 lines
11 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Callback Parsing</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Chapter 1. Boost.Parser">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="unicode_support.html" title="Unicode Support">
<link rel="next" href="error_handling_and_debugging.html" title="Error Handling and Debugging">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="spirit-nav">
<a accesskey="p" href="unicode_support.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="error_handling_and_debugging.html"><img src="../../images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.callback_parsing"></a><a class="link" href="callback_parsing.html" title="Callback Parsing">Callback Parsing</a>
</h3></div></div></div>
<p>
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. <code class="computeroutput">callback_rules</code>
exist for these kinds of uses. A <code class="computeroutput"><a class="link" href="../../boost/parser/callback_rule.html" title="Struct template callback_rule">callback_rule</a></code> 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 <code class="computeroutput"><a class="link" href="../../boost/parser/callback_parse_id6.html" title="Function template callback_parse">callback_parse()</a></code> instead of <code class="computeroutput"><a class="link" href="../../boost/parser/parse_id2.html" title="Function template parse">parse()</a></code>. Within a call to <code class="computeroutput"><a class="link" href="../../boost/parser/parse_id2.html" title="Function template parse">parse()</a></code>, a <code class="computeroutput"><a class="link" href="../../boost/parser/callback_rule.html" title="Struct template callback_rule">callback_rule</a></code> is identical
to a regular <code class="computeroutput"><a class="link" href="../../boost/parser/rule.html" title="Struct template rule">rule</a></code>.
</p>
<p>
For a rule with no attribute, the signature of a callback function is <code class="computeroutput"><span class="keyword">void</span> <span class="special">(</span><span class="identifier">tag</span><span class="special">)</span></code>, where <code class="computeroutput"><span class="identifier">tag</span></code>
is the tag-type used when declaring the rule. For a rule with an attribute
<code class="computeroutput"><span class="identifier">attr</span></code>, the signature is <code class="computeroutput"><span class="keyword">void</span> <span class="special">(</span><span class="identifier">tag</span><span class="special">,</span> <span class="identifier">attr</span><span class="special">)</span></code>. For instance, with this rule:
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">callback_rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">foo_tag</span><span class="special">&gt;</span> <span class="identifier">foo</span> <span class="special">=</span> <span class="string">"foo"</span><span class="special">;</span>
</pre>
<p>
this would be an appropriate callback function:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo_callback</span><span class="special">(</span><span class="identifier">foo_tag</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parsed a 'foo'!\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
For this rule:
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">callback_rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">bar_tag</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">bar</span> <span class="special">=</span> <span class="string">"bar"</span><span class="special">;</span>
</pre>
<p>
this would be an appropriate callback function:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">bar_callback</span><span class="special">(</span><span class="identifier">bar_tag</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parsed a 'bar' containing "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="string">"!\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
In the case of <code class="computeroutput"><span class="identifier">bar_callback</span><span class="special">()</span></code>, we don't need to do anything with <code class="computeroutput"><span class="identifier">s</span></code> besides insert it into a stream, so
we took it as a <code class="computeroutput"><span class="keyword">const</span></code> lvalue
reference. Boost.Parser moves all attributes into callbacks, so the signature
could also have been <code class="computeroutput"><span class="keyword">void</span> <span class="identifier">bar_callback</span><span class="special">(</span><span class="identifier">bar_tag</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">s</span><span class="special">)</span></code> or <code class="computeroutput"><span class="keyword">void</span>
<span class="identifier">bar_callback</span><span class="special">(</span><span class="identifier">bar_tag</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;&amp;</span>
<span class="identifier">s</span><span class="special">)</span></code>.
</p></td></tr>
</table></div>
<p>
You opt into callback parsing by parsing with a call to <code class="computeroutput"><a class="link" href="../../boost/parser/callback_parse_id6.html" title="Function template callback_parse">callback_parse()</a></code>
instead of <code class="computeroutput"><a class="link" href="../../boost/parser/parse_id2.html" title="Function template parse">parse()</a></code>. If you use <code class="computeroutput">callback_rules</code> with <code class="computeroutput"><a class="link" href="../../boost/parser/parse_id2.html" title="Function template parse">parse()</a></code>, they're just regular <code class="computeroutput"><a class="link" href="../../boost/parser/rule.html" title="Struct template rule">rules</a></code>.
This allows you to choose whether to do "normal" attribute-generating/attribute-assigning
parsing with <code class="computeroutput"><a class="link" href="../../boost/parser/parse_id2.html" title="Function template parse">parse()</a></code>, or callback parsing with
<code class="computeroutput"><a class="link" href="../../boost/parser/callback_parse_id6.html" title="Function template callback_parse">callback_parse()</a></code>, without rewriting much
parsing code, if any.
</p>
<p>
The only reason all <code class="computeroutput"><a class="link" href="../../boost/parser/rule.html" title="Struct template rule">rules</a></code>
are not <code class="computeroutput">callback_rules</code>
is that you may want to have some <code class="computeroutput"><a class="link" href="../../boost/parser/rule.html" title="Struct template rule">rules</a></code> use callbacks within
a parse, and have some that do not. For instance, if you want to report the
attribute of <code class="computeroutput"><a class="link" href="../../boost/parser/callback_rule.html" title="Struct template callback_rule">callback_rule</a></code> <code class="computeroutput"><span class="identifier">r1</span></code> via callback, <code class="computeroutput"><span class="identifier">r1</span></code>'s
implementation may use some rule <code class="computeroutput"><span class="identifier">r2</span></code>
to generate some or all of its attribute.
</p>
<p>
See <a class="link" href="../extended_examples/parsing_json_with_callbacks.html" title="Parsing JSON With Callbacks">Parsing
JSON With Callbacks</a> for an extended example of callback parsing.
</p>
</div>
<div class="copyright-footer">Copyright © 2020 T. Zachary Laine<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="unicode_support.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="error_handling_and_debugging.html"><img src="../../images/next.png" alt="Next"></a>
</div>
</body>
</html>