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/directives.html
2024-12-08 17:19:48 -06:00

325 lines
38 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>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">
<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.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. You can often
spot a directive lexically by its use of <code class="computeroutput"><span class="special">[]</span></code>;
directives always <code class="computeroutput"><span class="special">[]</span></code>. Non-directives
might, but only when attaching a semantic action.
</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_id13.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 much about them here.
</p>
<h5>
<a name="boost_parser.tutorial.directives.h0"></a>
<span class="phrase"><a name="boost_parser.tutorial.directives.interaction_with_sequence__alternative__and_permutation_parsers"></a></span><a class="link" href="directives.html#boost_parser.tutorial.directives.interaction_with_sequence__alternative__and_permutation_parsers">Interaction
with sequence, alternative, and permutation parsers</a>
</h5>
<p>
Sequence, alternative, and permutation parsers do not nest in most cases.
(Let's consider just sequence parsers to keep thinkgs simple, but most of
this logic applies to alternative parsers as well.) <code class="computeroutput"><span class="identifier">a</span>
<span class="special">&gt;&gt;</span> <span class="identifier">b</span>
<span class="special">&gt;&gt;</span> <span class="identifier">c</span></code>
is the same as <code class="computeroutput"><span class="special">(</span><span class="identifier">a</span>
<span class="special">&gt;&gt;</span> <span class="identifier">b</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="identifier">c</span></code> and <code class="computeroutput"><span class="identifier">a</span>
<span class="special">&gt;&gt;</span> <span class="special">(</span><span class="identifier">b</span> <span class="special">&gt;&gt;</span> <span class="identifier">c</span><span class="special">)</span></code>, and
they are each represented by a single <code class="computeroutput"><a class="link" href="../../boost/parser/seq_parser.html" title="Struct template seq_parser">seq_parser</a></code> with three subparsers,
<code class="computeroutput"><span class="identifier">a</span></code>, <code class="computeroutput"><span class="identifier">b</span></code>,
and <code class="computeroutput"><span class="identifier">c</span></code>. However, if something
prevents two <code class="computeroutput"><a class="link" href="../../boost/parser/seq_parser.html" title="Struct template seq_parser">seq_parsers</a></code>
from interacting directly, they <span class="bold"><strong>will</strong></span> nest.
For instance, <code class="computeroutput"><span class="identifier">lexeme</span><span class="special">[</span><span class="identifier">a</span> <span class="special">&gt;&gt;</span> <span class="identifier">b</span><span class="special">]</span> <span class="special">&gt;&gt;</span>
<span class="identifier">c</span></code> is a <code class="computeroutput"><a class="link" href="../../boost/parser/seq_parser.html" title="Struct template seq_parser">seq_parser</a></code> containing two parsers,
<code class="computeroutput"><span class="identifier">lexeme</span><span class="special">[</span><span class="identifier">a</span> <span class="special">&gt;&gt;</span> <span class="identifier">b</span><span class="special">]</span></code> and
<code class="computeroutput"><span class="identifier">c</span></code>. This is because <code class="computeroutput"><a class="link" href="../../boost/parser/lexeme.html" title="Global lexeme">lexeme[]</a></code> takes its given parser and
wraps it in a <code class="computeroutput"><a class="link" href="../../boost/parser/lexeme_parser.html" title="Struct template lexeme_parser">lexeme_parser</a></code>. This in turn
turns off the sequence parser combining logic, since both sides of the second
<code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;&gt;</span></code>
in <code class="computeroutput"><span class="identifier">lexeme</span><span class="special">[</span><span class="identifier">a</span> <span class="special">&gt;&gt;</span> <span class="identifier">b</span><span class="special">]</span> <span class="special">&gt;&gt;</span>
<span class="identifier">c</span></code> are not <code class="computeroutput"><a class="link" href="../../boost/parser/seq_parser.html" title="Struct template seq_parser">seq_parsers</a></code>. Sequence parsers
have several rules that govern what the overall attribute type of the parser
is, based on the positions and attributes of it subparsers (see <a class="link" href="attribute_generation.html" title="Attribute Generation">Attribute
Generation</a>). Therefore, it's important to know which directives create
a new parser (and what kind), and which ones do not; this is indicated for
each directive below.
</p>
<h5>
<a name="boost_parser.tutorial.directives.h1"></a>
<span class="phrase"><a name="boost_parser.tutorial.directives.the_directives"></a></span><a class="link" href="directives.html#boost_parser.tutorial.directives.the_directives">The
directives</a>
</h5>
<h5>
<a name="boost_parser.tutorial.directives.h2"></a>
<span class="phrase"><a name="boost_parser.tutorial.directives._functionname_alt__boost__parser__repeat___code__phrase_role__identifier__repeat__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="directives.html#boost_parser.tutorial.directives._functionname_alt__boost__parser__repeat___code__phrase_role__identifier__repeat__phrase__phrase_role__special______phrase___code___functionname_">repeat()</a>
</h5>
<p>
See <a class="link" href="the_parsers_and_their_uses.html" title="The Parsers And Their Uses">The
Parsers And Their Uses</a>. Creates a <code class="computeroutput"><a class="link" href="../../boost/parser/repeat_parser.html" title="Struct template repeat_parser">repeat_parser</a></code>.
</p>
<h5>
<a name="boost_parser.tutorial.directives.h3"></a>
<span class="phrase"><a name="boost_parser.tutorial.directives._functionname_alt__boost__parser__if____code__phrase_role__identifier__if___phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="directives.html#boost_parser.tutorial.directives._functionname_alt__boost__parser__if____code__phrase_role__identifier__if___phrase__phrase_role__special______phrase___code___functionname_">if_()</a>
</h5>
<p>
See <a class="link" href="the_parsers_and_their_uses.html" title="The Parsers And Their Uses">The
Parsers And Their Uses</a>. Creates a <code class="computeroutput"><a class="link" href="../../boost/parser/seq_parser.html" title="Struct template seq_parser">seq_parser</a></code>.
</p>
<h5>
<a name="boost_parser.tutorial.directives.h4"></a>
<span class="phrase"><a name="boost_parser.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.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>
<p>
Creates an <code class="computeroutput"><a class="link" href="../../boost/parser/omit_parser.html" title="Struct template omit_parser">omit_parser</a></code>.
</p>
<h5>
<a name="boost_parser.tutorial.directives.h5"></a>
<span class="phrase"><a name="boost_parser.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.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/subrange.html" title="Struct template subrange">subrange</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_id2.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_id2.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>
<p>
Creates a <code class="computeroutput"><a class="link" href="../../boost/parser/raw_parser.html" title="Struct template raw_parser">raw_parser</a></code>.
</p>
<h5>
<a name="boost_parser.tutorial.directives.h6"></a>
<span class="phrase"><a name="boost_parser.tutorial.directives._globalname_alt__boost__parser__string_view___code__phrase_role__identifier__string_view__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="directives.html#boost_parser.tutorial.directives._globalname_alt__boost__parser__string_view___code__phrase_role__identifier__string_view__phrase__phrase_role__special______phrase___code___globalname_">string_view[]</a>
</h5>
<p>
<code class="computeroutput"><a class="link" href="../../boost/parser/string_view.html" title="Global string_view">string_view</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
is very similar to <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>, except
that it changes the attribute of <code class="computeroutput"><span class="identifier">p</span></code>
to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string_view</span><span class="special">&lt;</span><span class="identifier">C</span><span class="special">&gt;</span></code>,
where <code class="computeroutput"><span class="identifier">C</span></code> is the character
type of the underlying range being parsed. <code class="computeroutput"><a class="link" href="../../boost/parser/string_view.html" title="Global string_view">string_view[]</a></code>
requires that the underlying range being parsed is contiguous. Since this
can only be detected in C++20 and later, <code class="computeroutput"><a class="link" href="../../boost/parser/string_view.html" title="Global string_view">string_view[]</a></code>
is not available in C++17 mode.
</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/string_view.html" title="Global string_view">string_view[]</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. Whether
<code class="computeroutput"><a class="link" href="../../boost/parser/raw.html" title="Global raw">raw[]</a></code> or <code class="computeroutput"><a class="link" href="../../boost/parser/string_view.html" title="Global string_view">string_view[]</a></code>
is more natural to use to report the locations depends on your use case,
but they are essentially the same.
</p>
<p>
Creates a <code class="computeroutput"><a class="link" href="../../boost/parser/string_view_parser.html" title="Struct template string_view_parser">string_view_parser</a></code>.
</p>
<h5>
<a name="boost_parser.tutorial.directives.h7"></a>
<span class="phrase"><a name="boost_parser.tutorial.directives._globalname_alt__boost__parser__no_case___code__phrase_role__identifier__no_case__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="directives.html#boost_parser.tutorial.directives._globalname_alt__boost__parser__no_case___code__phrase_role__identifier__no_case__phrase__phrase_role__special______phrase___code___globalname_">no_case[]</a>
</h5>
<p>
<code class="computeroutput"><a class="link" href="../../boost/parser/no_case.html" title="Global no_case">no_case</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
enables case-insensitive parsing within the parse of <code class="computeroutput"><span class="identifier">p</span></code>.
This applies to the text parsed by <code class="computeroutput"><a class="link" href="../../boost/parser/char_.html" title="Global char_">char_</a><span class="special">()</span></code>,
<code class="computeroutput"><a class="link" href="../../boost/parser/string.html" title="Function template string">string()</a></code>, and <code class="computeroutput"><a class="link" href="../../boost/parser/bool_.html" title="Global bool_">bool_</a></code> parsers. The number
parsers are already case-insensitive. The case-insensitivity is achieved
by doing Unicode case folding on the text being parsed and the values in
the parser being matched (see note below if you want to know more about Unicode
case folding). In the non-Unicode code path, a full Unicode case folding
is not done; instead, only the transformations of values less than <code class="computeroutput"><span class="number">0x100</span></code> are done. Examples:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">transcode_view</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// For as_utfN.</span>
<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">street_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="identifier">u8</span><span class="string">"Tobias Straße"</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(!</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"Tobias Strasse"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf32</span><span class="special">,</span> <span class="identifier">street_parser</span><span class="special">));</span> <span class="comment">// No match.</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"Tobias Strasse"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf32</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">no_case</span><span class="special">[</span><span class="identifier">street_parser</span><span class="special">]));</span> <span class="comment">// Match!</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">alpha_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">no_case</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">'a'</span><span class="special">,</span> <span class="char">'z'</span><span class="special">)];</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"a"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf32</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">no_case</span><span class="special">[</span><span class="identifier">alpha_parser</span><span class="special">]));</span> <span class="comment">// Match!</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"B"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf32</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">no_case</span><span class="special">[</span><span class="identifier">alpha_parser</span><span class="special">]));</span> <span class="comment">// Match!</span>
</pre>
<p>
Everything pretty much does what you'd naively expect inside <code class="computeroutput"><a class="link" href="../../boost/parser/no_case.html" title="Global no_case">no_case[]</a></code>, except that the two-character
range version of <code class="computeroutput"><span class="identifier">char_</span></code> has
a limitation. It only compares a code point from the input to its two arguments
(e.g. <code class="computeroutput"><span class="char">'a'</span></code> and <code class="computeroutput"><span class="char">'z'</span></code>
in the example above). It does not do anything special for multi-code point
case folding expansions. For instance, <code class="computeroutput"><span class="identifier">char_</span><span class="special">(</span><span class="identifier">U</span><span class="char">'ß'</span><span class="special">,</span> <span class="identifier">U</span><span class="char">'ß'</span><span class="special">)</span></code> matches the input <code class="computeroutput"><span class="identifier">U</span><span class="string">"s"</span></code>, which makes sense, since <code class="computeroutput"><span class="identifier">U</span><span class="char">'ß'</span></code> expands
to <code class="computeroutput"><span class="identifier">U</span><span class="string">"ss"</span></code>.
However, that same parser <span class="bold"><strong>does not</strong></span> match
the input <code class="computeroutput"><span class="identifier">U</span><span class="string">"ß"</span></code>!
In short, stick to pairs of code points that have single-code point case
folding expansions. If you need to support the multi-expanding code points,
use the other overload, like: <code class="computeroutput"><span class="identifier">char_</span><span class="special">(</span><span class="identifier">U</span><span class="string">"abcd/*...*/ß"</span><span class="special">)</span></code>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Unicode case folding is an operation that makes text uniformly one case,
and if you do it to two bits of text <code class="computeroutput"><span class="identifier">A</span></code>
and <code class="computeroutput"><span class="identifier">B</span></code>, then you can compare
them bitwise to see if they are the same, except of case. Case folding
may sometimes expand a code point into multiple code points (e.g. case
folding <code class="computeroutput"><span class="string">"ẞ"</span></code> yields
<code class="computeroutput"><span class="string">"ss"</span></code>. When such a
multi-code point expansion occurs, the expanded code points are in the
NFKC normalization form.
</p></td></tr>
</table></div>
<p>
Creates a <code class="computeroutput"><a class="link" href="../../boost/parser/no_case_parser.html" title="Struct template no_case_parser">no_case_parser</a></code>.
</p>
<h5>
<a name="boost_parser.tutorial.directives.h8"></a>
<span class="phrase"><a name="boost_parser.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.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>
<p>
Creates a <code class="computeroutput"><a class="link" href="../../boost/parser/lexeme_parser.html" title="Struct template lexeme_parser">lexeme_parser</a></code>.
</p>
<h5>
<a name="boost_parser.tutorial.directives.h9"></a>
<span class="phrase"><a name="boost_parser.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.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_id2.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_id2.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/ws.html" title="Global ws">ws</a></code> to <code class="computeroutput"><a class="link" href="../../boost/parser/parse_id2.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_id2.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">blank</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_id2.html" title="Function template parse">parse()</a></code>,
which is <code class="computeroutput"><a class="link" href="../../boost/parser/ws.html" title="Global ws">ws</a></code>;
the second will use <code class="computeroutput"><a class="link" href="../../boost/parser/blank.html" title="Global blank">blank</a></code> as its skipper.
</p>
<p>
Creates a <code class="computeroutput"><a class="link" href="../../boost/parser/skip_parser.html" title="Struct template skip_parser">skip_parser</a></code>.
</p>
<h5>
<a name="boost_parser.tutorial.directives.h10"></a>
<span class="phrase"><a name="boost_parser.tutorial.directives._globalname_alt__boost__parser__merge___code__phrase_role__identifier__merge__phrase__phrase_role__special______phrase___code___globalname____globalname_alt__boost__parser__separate___code__phrase_role__identifier__separate__phrase__phrase_role__special______phrase___code___globalname___and__globalname_alt__boost__parser__transform___code__phrase_role__identifier__transform__phrase__phrase_role__special_____phrase__phrase_role__identifier__f__phrase__phrase_role__special_______phrase___code___globalname_"></a></span><a class="link" href="directives.html#boost_parser.tutorial.directives._globalname_alt__boost__parser__merge___code__phrase_role__identifier__merge__phrase__phrase_role__special______phrase___code___globalname____globalname_alt__boost__parser__separate___code__phrase_role__identifier__separate__phrase__phrase_role__special______phrase___code___globalname___and__globalname_alt__boost__parser__transform___code__phrase_role__identifier__transform__phrase__phrase_role__special_____phrase__phrase_role__identifier__f__phrase__phrase_role__special_______phrase___code___globalname_">merge[], separate[],
and <code class="computeroutput">transform(f)[]</code></a>
</h5>
<p>
These directives influence the generation of attributes. See <a class="link" href="attribute_generation.html" title="Attribute Generation">Attribute
Generation</a> section for more details on them.
</p>
<p>
<code class="computeroutput"><a class="link" href="../../boost/parser/merge.html" title="Global merge">merge[]</a></code> and <code class="computeroutput"><a class="link" href="../../boost/parser/separate.html" title="Global separate">separate[]</a></code>
create a copy of the given <code class="computeroutput"><a class="link" href="../../boost/parser/seq_parser.html" title="Struct template seq_parser">seq_parser</a></code>.
</p>
<p>
<code class="computeroutput">transform(f)[]</code>
creates a <code class="computeroutput"><a class="link" href="../../boost/parser/transform_parser.html" title="Struct template transform_parser">tranform_parser</a></code>.
</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>