2
0
mirror of https://github.com/boostorg/parser.git synced 2026-01-28 07:22:29 +00:00
Files
parser/doc/html/boost_parser__proposed_/tutorial/directives.html
2023-12-02 17:28:57 -06:00

158 lines
17 KiB
HTML
Raw 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>Directives</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 (Proposed)">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="the_parsers_and_their_uses.html" title="The Parsers And Their Uses">
<link rel="next" href="combining_operations.html" title="Combining Operations">
<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="the_parsers_and_their_uses.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="combining_operations.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__proposed_.tutorial.directives"></a><a class="link" href="directives.html" title="Directives">Directives</a>
</h3></div></div></div>
<p>
A directive is an element of your parser that doesn't have any meaning by
itself. Some are second-order parsers that need a first-order parser to do
the actual parsing. Others influence the parse in some way. Lexically, you
can spot a directive by its use of <code class="computeroutput"><span class="special">[]</span></code>.
Non-directives never use <code class="computeroutput"><span class="special">[]</span></code>,
and directives always do.
</p>
<p>
The directives that are second order parsers are technically directives,
but since they are also used to create parsers, it is more useful just to
focus on that. The directives <code class="computeroutput"><a class="link" href="../../boost/parser/repeat_idm19502.html" title="Function template repeat">repeat()</a></code>
and <code class="computeroutput"><a class="link" href="../../boost/parser/if_.html" title="Function template if_">if_()</a></code> were already described in
the section on parsers; we won't say more about them here.
</p>
<p>
That leaves the directives that affect aspects of the parse:
</p>
<h5>
<a name="boost_parser__proposed_.tutorial.directives.h0"></a>
<span class="phrase"><a name="boost_parser__proposed_.tutorial.directives._globalname_alt__boost__parser__omit___code__phrase_role__identifier__omit__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="directives.html#boost_parser__proposed_.tutorial.directives._globalname_alt__boost__parser__omit___code__phrase_role__identifier__omit__phrase__phrase_role__special______phrase___code___globalname_">omit[]</a>
</h5>
<p>
<code class="computeroutput"><a class="link" href="../../boost/parser/omit.html" title="Global omit">omit</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
disables attribute generation for the parser <code class="computeroutput"><span class="identifier">p</span></code>.
Not only does <code class="computeroutput"><a class="link" href="../../boost/parser/omit.html" title="Global omit">omit</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
have no attribute, but any attribute generation work that normally happens
within <code class="computeroutput"><span class="identifier">p</span></code> is skipped.
</p>
<p>
This directive can be useful in cases like this: say you have some fairly
complicated parser <code class="computeroutput"><span class="identifier">p</span></code> that
generates a large and expensive-to-construct attribute. Now say that you
want to write a function that just counts how many times <code class="computeroutput"><span class="identifier">p</span></code>
can match a string (where the matches are non-overlapping). Instead of using
<code class="computeroutput"><span class="identifier">p</span></code> directly, and building
all those attributes, or rewriting <code class="computeroutput"><span class="identifier">p</span></code>
without the attribute generation, use <code class="computeroutput"><a class="link" href="../../boost/parser/omit.html" title="Global omit">omit[]</a></code>.
</p>
<h5>
<a name="boost_parser__proposed_.tutorial.directives.h1"></a>
<span class="phrase"><a name="boost_parser__proposed_.tutorial.directives._globalname_alt__boost__parser__raw___code__phrase_role__identifier__raw__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="directives.html#boost_parser__proposed_.tutorial.directives._globalname_alt__boost__parser__raw___code__phrase_role__identifier__raw__phrase__phrase_role__special______phrase___code___globalname_">raw[]</a>
</h5>
<p>
<code class="computeroutput"><a class="link" href="../../boost/parser/raw.html" title="Global raw">raw</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
changes the attribute from <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
to to a view that delimits the subrange of the input that was matched by
<code class="computeroutput"><span class="identifier">p</span></code>. The type of the view is
<code class="computeroutput"><a class="link" href="../../boost/parser/view.html" title="Struct template view">view</a><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;</span></code>,
where <code class="computeroutput"><span class="identifier">I</span></code> is the type of the
iterator used within the parse. Note that this may not be the same as the
iterator type passed to <code class="computeroutput"><a class="link" href="../../boost/parser/parse_idm19819.html" title="Function template parse">parse()</a></code>.
For instance, when parsing UTF-8, the iterator passed to <code class="computeroutput"><a class="link" href="../../boost/parser/parse_idm19819.html" title="Function template parse">parse()</a></code>
may be <code class="computeroutput"><span class="identifier">char8_t</span> <span class="keyword">const</span>
<span class="special">*</span></code>, but within the parse it will be
a UTF-8 to UTF-32 transcoding (converting) iterator. Just like <code class="computeroutput"><a class="link" href="../../boost/parser/omit.html" title="Global omit">omit[]</a></code>, <code class="computeroutput"><a class="link" href="../../boost/parser/raw.html" title="Global raw">raw[]</a></code>
causes all attribute-generation work within <code class="computeroutput"><span class="identifier">p</span></code>
to be skipped.
</p>
<p>
Similar to the re-use scenario for <code class="computeroutput"><a class="link" href="../../boost/parser/omit.html" title="Global omit">omit[]</a></code>
above, <code class="computeroutput"><a class="link" href="../../boost/parser/raw.html" title="Global raw">raw[]</a></code> could be used to find the
<span class="bold"><strong>locations</strong></span> of all non-overlapping matches
of <code class="computeroutput"><span class="identifier">p</span></code> in a string.
</p>
<h5>
<a name="boost_parser__proposed_.tutorial.directives.h2"></a>
<span class="phrase"><a name="boost_parser__proposed_.tutorial.directives._globalname_alt__boost__parser__lexeme___code__phrase_role__identifier__lexeme__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="directives.html#boost_parser__proposed_.tutorial.directives._globalname_alt__boost__parser__lexeme___code__phrase_role__identifier__lexeme__phrase__phrase_role__special______phrase___code___globalname_">lexeme[]</a>
</h5>
<p>
<code class="computeroutput"><a class="link" href="../../boost/parser/lexeme.html" title="Global lexeme">lexeme</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
disables use of the skipper, if a skipper is being used, within the parse
of <code class="computeroutput"><span class="identifier">p</span></code>. This is useful, for
instance, if you want to enable skipping in most parts of your parser, but
disable it only in one section where it doesn't belong. If you are skipping
whitespace in most of your parser, but want to parse strings that may contain
spaces, you should use <code class="computeroutput"><a class="link" href="../../boost/parser/lexeme.html" title="Global lexeme">lexeme[]</a></code>:
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">string_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">=</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="char">'"'</span><span class="special">];</span>
</pre>
<p>
Without <code class="computeroutput"><a class="link" href="../../boost/parser/lexeme.html" title="Global lexeme">lexeme[]</a></code>, our string parser would correctly
match <code class="computeroutput"><span class="string">"foo bar"</span></code>, but
the generated attribute would be <code class="computeroutput"><span class="string">"foobar"</span></code>.
</p>
<h5>
<a name="boost_parser__proposed_.tutorial.directives.h3"></a>
<span class="phrase"><a name="boost_parser__proposed_.tutorial.directives._globalname_alt__boost__parser__skip___code__phrase_role__identifier__skip__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="directives.html#boost_parser__proposed_.tutorial.directives._globalname_alt__boost__parser__skip___code__phrase_role__identifier__skip__phrase__phrase_role__special______phrase___code___globalname_">skip[]</a>
</h5>
<p>
<code class="computeroutput"><a class="link" href="../../boost/parser/skip.html" title="Global skip">skip[]</a></code> is like the inverse of <code class="computeroutput"><a class="link" href="../../boost/parser/lexeme.html" title="Global lexeme">lexeme[]</a></code>. It enables skipping in the
parse, even if it was not enabled before. For example, within a call to
<code class="computeroutput"><a class="link" href="../../boost/parser/parse_idm19819.html" title="Function template parse">parse()</a></code> that uses a skipper, let's
say we have these parsers in use:
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">one_or_more</span> <span class="special">=</span> <span class="special">+</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">skip_or_skip_not_there_is_no_try</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">skip</span><span class="special">[</span><span class="identifier">one_or_more</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="identifier">one_or_more</span><span class="special">];</span>
</pre>
<p>
The use of <code class="computeroutput"><a class="link" href="../../boost/parser/lexeme.html" title="Global lexeme">lexeme[]</a></code> disables skipping, but then
the use of <code class="computeroutput"><a class="link" href="../../boost/parser/skip.html" title="Global skip">skip[]</a></code> turns it back on. The net
result is that the first occurrence of <code class="computeroutput"><span class="identifier">one_or_more</span></code>
will use the skipper passed to <code class="computeroutput"><a class="link" href="../../boost/parser/parse_idm19819.html" title="Function template parse">parse()</a></code>;
the second will not.
</p>
<p>
<code class="computeroutput"><a class="link" href="../../boost/parser/skip.html" title="Global skip">skip[]</a></code> has another use. You can parameterize
skip with a different parser to change the skipper just within the scope
of the directive. Let's say we passed <code class="computeroutput"><a class="link" href="../../boost/parser/ascii/space.html" title="Global space">ascii::space</a></code> to <code class="computeroutput"><a class="link" href="../../boost/parser/parse_idm19819.html" title="Function template parse">parse()</a></code>,
and we're using these parsers somewhere within that <code class="computeroutput"><a class="link" href="../../boost/parser/parse_idm19819.html" title="Function template parse">parse()</a></code>
call:
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">zero_or_more</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">skip_both_ways</span> <span class="special">=</span> <span class="identifier">zero_or_more</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">skip</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">)[</span><span class="identifier">zero_or_more</span><span class="special">];</span>
</pre>
<p>
The first occurrence of <code class="computeroutput"><span class="identifier">zero_or_more</span></code>
will use the skipper passed to <code class="computeroutput"><a class="link" href="../../boost/parser/parse_idm19819.html" title="Function template parse">parse()</a></code>,
which is <code class="computeroutput"><a class="link" href="../../boost/parser/ascii/space.html" title="Global space">ascii::space</a></code>;
the second will use <code class="computeroutput"><a class="link" href="../../boost/parser/ws.html" title="Global ws">ws</a></code>
as its skipper.
</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="the_parsers_and_their_uses.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="combining_operations.html"><img src="../../images/next.png" alt="Next"></a>
</div>
</body>
</html>