1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-16 22:14:23 +03:00
inform7/docs/words-module/4-prf.html
2020-05-09 13:07:39 +01:00

2417 lines
517 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Preform</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul><h2>Compiler Webs</h2><ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul><h2>Inbuild Modules</h2><ul>
<li><a href="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul><h2>Inter Modules</h2><ul>
<li><a href="../bytecode-module/index.html">bytecode</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul><h2>Shared Modules</h2><ul>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="index.html"><span class="selectedlink">words</span></a></li>
<li><a href="../html-module/index.html">html</a></li>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Preform' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</a></li><li><a href="index.html">words</a></li><li><a href="index.html#4">Chapter 4: Parsing</a></li><li><b>Preform</b></li></ul></div>
<p class="purpose">To read in structural definitions of natural language written in a meta-language called Preform.</p>
<ul class="toc"><li><a href="4-prf.html#SP1">&#167;1. Definitions</a></li><li><a href="4-prf.html#SP2">&#167;2. Introduction</a></li><li><a href="4-prf.html#SP8">&#167;8. Implementation</a></li><li><a href="4-prf.html#SP17">&#167;17. Logging</a></li><li><a href="4-prf.html#SP23">&#167;23. Building grammar</a></li><li><a href="4-prf.html#SP31">&#167;31. Optimisation calculations</a></li><li><a href="4-prf.html#SP49">&#167;49. Parsing</a></li><li><a href="4-prf.html#SP53">&#167;53. Reading Preform syntax from a file</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. Introduction. </b></p>
<pre class="definitions code-font"><span class="plain-syntax">@</span><span class="reserved-syntax">default</span><span class="plain-syntax"> </span><span class="constant-syntax">PREFORM_LANGUAGE_TYPE</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. </b>The parser reads source text against a specific language only, if
<span class="extract"><span class="extract-syntax">language_of_source_text</span></span> is set; or, if it isn't, from any language.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="constant-syntax">PREFORM_LANGUAGE_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">language_of_source_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="constant-syntax">PREFORM_LANGUAGE_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">language_being_read_by_Preform</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. </b>Preform is parsed with the regular lexer, using the following set of
characters as word-breaking punctuation marks:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PREFORM_PUNCTUATION_MARKS</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="string-syntax">"{}[]_^?&amp;\\"</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5"></a><b>&#167;5. </b>That's what it would look like in the Preform file, but here is how it's
typed in the Inform source code. Definitions like this one are scattered all
across the Inform web, in order to keep them close to the code which relates to
them. The <span class="extract"><span class="extract-syntax">inweb</span></span> tangler compiles them in two halves: the instructions right
of the <span class="extract"><span class="extract-syntax">==&gt;</span></span> arrows are extracted and compiled into a C routine called the
"compositor" for the nonterminal (see below), while the actual grammar is
extracted and placed into Inform's "Preform.txt" file.
</p>
<p class="commentary">In the document of Preform grammar extracted from Inform's source code to
lay the language out for translators, the <span class="extract"><span class="extract-syntax">==&gt;</span></span> arrows and formulae to the
right of them are omitted &mdash; those represent semantics, not syntax.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> &lt;competitor&gt; ::=</span>
<span class="plain-syntax"> &lt;ordinal-number&gt; runner | ==&gt; TRUE</span>
<span class="plain-syntax"> runner no &lt;cardinal-number&gt; ==&gt; FALSE</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. </b>Each nonterminal, when successfully matched, can provide both or more usually
just one of two results: an integer, to be stored in <span class="extract"><span class="extract-syntax">*X</span></span>, and a void pointer,
to be stored in <span class="extract"><span class="extract-syntax">*XP</span></span>. For example, &lt;k-kind&gt; matches if and only if the
text declares a legal kind, such as "number"; its pointer result is to the
kind found, such as <span class="extract"><span class="extract-syntax">K_number</span></span>. But &lt;competitor&gt; only results in an integer.
The <span class="extract"><span class="extract-syntax">==&gt;</span></span> arrow is optional, but if present, it says what the result is if
the given production is matched; the <span class="extract"><span class="extract-syntax">inweb</span></span> tangler, if it sees an expression
on the right of the arrow, assigns that value to the integer result. So,
for example, "runner bean" or "beetroot" would not match &lt;competitor&gt;;
"4th runner" would match with integer result <span class="extract"><span class="extract-syntax">TRUE</span></span>; "runner no 17" would
match with integer result <span class="extract"><span class="extract-syntax">FALSE</span></span>.
</p>
<p class="commentary">Usually, though, the result(s) of a nonterminal depend on the result(s) of
other nonterminals used to make the match. In the compositing expression,
so called because it composes together the various intermediate results into
one final result, <span class="extract"><span class="extract-syntax">R[1]</span></span> is the integer result of the first nonterminal in
the production, <span class="extract"><span class="extract-syntax">R[2]</span></span> the second, and so on; <span class="extract"><span class="extract-syntax">RP[1]</span></span> and so on hold the
pointer results. Here, on both productions, there's just one nonterminal
in the line, &lt;ordinal-number&gt; in the first case, &lt;cardinal-number&gt; in
the second. So the following refinement of &lt;competitor&gt; means that "4th
runner" matches with integer result 4, because &lt;ordinal-number&gt; matches
"4th" with integer result 4, and that goes into <span class="extract"><span class="extract-syntax">R[1]</span></span>. Similarly,
"runner no 17" ends up with integer result 17. "The pacemaker" matches
with integer result 1; here there are no intermediate results to make use
of, so <span class="extract"><span class="extract-syntax">R[...]</span></span> can't be used.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> &lt;competitor&gt; ::=</span>
<span class="plain-syntax"> the pacemaker | ==&gt; 1</span>
<span class="plain-syntax"> &lt;ordinal-number&gt; runner | ==&gt; R[1]</span>
<span class="plain-syntax"> runner no &lt;cardinal-number&gt; ==&gt; R[1]</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7"></a><b>&#167;7. </b>The arrows and expressions are optional, and if they are omitted, then the
result integer is set to the production number, counting up from 0. For
example, given the following, "polkadot" matches with result 1, and "green"
with result 2.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> &lt;race-jersey&gt; ::=</span>
<span class="plain-syntax"> yellow | polkadot | green | white</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. Implementation. </b>We must first clarify how word ranges, once matched in the parser, will be
stored. Within each production, word ranges are numbered upwards from 1. Thus:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">man</span><span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> ... </span><span class="identifier-syntax">on</span><span class="plain-syntax"> </span><span class="identifier-syntax">his</span><span class="plain-syntax"> ...</span>
</pre>
<p class="commentary">would, if it matched successfully, generate two word ranges, numbered 1 and 2.
These are stored in memory belonging to the nonterminal; they are usually, but
not always, then retrieved by whatever part of Inform requested the parse,
using the <span class="extract"><span class="extract-syntax">GET_RW</span></span> macro rather than a function call for speed. It's rare,
but a few internal nonterminals also generate word ranges: they use the
corresponding <span class="extract"><span class="extract-syntax">PUT_RW</span></span> macro to do so. Lastly, we can pass word ranges up
from one nonterminal to another, with <span class="extract"><span class="extract-syntax">INHERIT_RANGES</span></span>.
</p>
<p class="commentary">This form of storage incurs very little time or space overhead, and is possible
only because the parser never backtracks. But it also follows that word ranges
are overwritten if a nonterminal calls itself directly or indirectly: that is,
the inner one's results are wiped out by the outer one. But this is no problem,
since we never extract word-ranges from grammar which is recursive.
</p>
<p class="commentary">Word range 0 is reserved in case we ever need it for the entire text matched
by the nonterminal, but at present we don't need that.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_RANGES_PER_PRODUCTION</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax"> </span><span class="comment-syntax"> in fact, one less than this, since range 0 is reserved</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">) (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_result</span><span class="plain-syntax">[</span><span class="identifier-syntax">N</span><span class="plain-syntax">])</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">PUT_RW</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">) { </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_result</span><span class="plain-syntax">[</span><span class="identifier-syntax">N</span><span class="plain-syntax">] = </span><span class="identifier-syntax">W</span><span class="plain-syntax">; }</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">INHERIT_RANGES</span><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=1; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_RANGES_PER_PRODUCTION</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="comment-syntax"> not copying range 0</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_result</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">from</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_result</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax">}</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">CLEAR_RW</span><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_RANGES_PER_PRODUCTION</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="comment-syntax"> including range 0</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_result</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="constant-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. </b>So here's the nonterminal structure. There are a few further complications
for speed reasons:
</p>
<ul class="items"><li>(a) The minimum and maximum number of words which could ever be a match are
precalculated. For example, if Preform can tell that N will only a run of
between 3 and 7 words inclusive, then it can quickly reject any run of words
outside that range. <span class="extract"><span class="extract-syntax">INFINITE_WORD_COUNT</span></span> is taken as the maximum if N
could in principle match text of any length. (However: note that a maximum of
0 means that the maximum and minimum word counts are disregarded.)
</li><li>(b) A few internal nonterminals are "voracious". These are given the entire
word range for their productions to eat, and encouraged to eat as much as
they like, returning a word number to show how far they got. While this
effect could be duplicated with suitable grammar and non-voracious nonterminals,
it would be quite a bit slower, since it would have to test every possible
word range.
</li></ul>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_RESULTS_PER_PRODUCTION</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax"> </span><span class="constant-syntax">1000000000</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nonterminal_id</span><span class="plain-syntax">; </span><span class="comment-syntax"> e.g. </span><span class="extract"><span class="extract-syntax">"&lt;cardinal-number&gt;"</span></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">voracious</span><span class="plain-syntax">; </span><span class="comment-syntax"> if true, scans whole rest of word range</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">multiplicitous</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">marked_internal</span><span class="plain-syntax">; </span><span class="comment-syntax"> has, or will be given, an internal definition...</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">internal_definition</span><span class="plain-syntax">)(</span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">result</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> **</span><span class="identifier-syntax">result_p</span><span class="plain-syntax">); </span><span class="comment-syntax"> ...this one</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="comment-syntax"> if not internal, this defines it</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">result_compositor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">r</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> **</span><span class="identifier-syntax">rp</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inters</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> **</span><span class="identifier-syntax">inter_ps</span><span class="plain-syntax">, </span><span class="reserved-syntax">wording</span><span class="plain-syntax"> *</span><span class="identifier-syntax">interW</span><span class="plain-syntax">, </span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">range_result</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_RANGES_PER_PRODUCTION</span><span class="plain-syntax">]; </span><span class="comment-syntax"> storage for word ranges matched</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">optimised_in_this_pass</span><span class="plain-syntax">; </span><span class="comment-syntax"> have the following been worked out yet?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">min_nt_words</span><span class="plain-syntax">, </span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax">; </span><span class="comment-syntax"> for speed</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> </span><span class="identifier-syntax">nonterminal_req</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">nt_req_bit</span><span class="plain-syntax">; </span><span class="comment-syntax"> which hashing category the words belong to, or </span>\(-1\)<span class="comment-syntax"> if none</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">number_words_by_production</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">flag_words_in_production</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">watched</span><span class="plain-syntax">; </span><span class="comment-syntax"> watch goings-on to the debugging log</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">nonterminal_tries</span><span class="plain-syntax">; </span><span class="comment-syntax"> used only in instrumented mode</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">nonterminal_matches</span><span class="plain-syntax">; </span><span class="comment-syntax"> ditto</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure nonterminal is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP10"></a><b>&#167;10. </b>Each (external) nonterminal is then defined by lists of productions:
potentially one for each language, though only English is required to define
all of them, and English will always be the first in the list of lists.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">PREFORM_LANGUAGE_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">definition_language</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_production</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_production_list</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">match_avinue</span><span class="plain-syntax"> *</span><span class="identifier-syntax">as_avinue</span><span class="plain-syntax">; </span><span class="comment-syntax"> when compiled to a trie rather than for Preform</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">production_list</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure production_list is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP11"></a><b>&#167;11. </b>So now we reach the production, which encodes a typical "row" of grammar;
see the examples above. A production is another list, of "ptokens" (the
"p" is silent). For example, the production
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">runner</span><span class="plain-syntax"> </span><span class="identifier-syntax">no</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;cardinal-number&gt;</span>
</pre>
<p class="commentary">contains three ptokens. (Note that the stroke sign and the defined-by sign are
not ptokens; they divide up productions, but aren't part of them.)
</p>
<p class="commentary">Like nonterminals, productions also count the minimum and maximum words
matched: in the above example, both are 3.
</p>
<p class="commentary">There's a new idea here as well, though: struts. A "strut" is a run of
ptokens in the interior of the production whose position relative to the
ends is not known. For example, if we match:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">frogs</span><span class="plain-syntax"> </span><span class="identifier-syntax">like</span><span class="plain-syntax"> ... </span><span class="identifier-syntax">but</span><span class="plain-syntax"> </span><span class="identifier-syntax">not</span><span class="plain-syntax"> ... </span><span class="identifier-syntax">to</span><span class="plain-syntax"> </span><span class="identifier-syntax">eat</span>
</pre>
<p class="commentary">then we know that in a successful match, "frogs" and "like" must be the
first two words in the text matched, and "eat" and "to" the last two.
They are said to have positions 1, 2, \(-1\) and \(-2\) respectively: a positive
number is relative to the start of the range, a negative relative to the end,
so that position 1 is always the first word and position \(-1\) is the last.
</p>
<p class="commentary">But we don't know where "but not" will occur; it could be anywhere in the
middle of the text. So the ptokens for these words have position 0. A run of
such ptokens, not counting wildcards like <span class="extract"><span class="extract-syntax">...</span></span>, is called a strut. We can
think of it as a partition which can slide backwards and forwards. Many
productions have no struts at all; the above example has just one. It has
length 2, not because it contains two ptokens, but because it is always
two words wide.
</p>
<p class="commentary">Finding struts when Preform grammar is read in means that we don't have to
do so much work devising search patterns at parsing time, when speed is
critical.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_STRUTS_PER_PRODUCTION</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">MAX_PTOKENS_PER_PRODUCTION</span><span class="plain-syntax"> </span><span class="constant-syntax">16</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="comment-syntax"> the linked list of ptokens</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">match_number</span><span class="plain-syntax">; </span><span class="comment-syntax"> 0 for </span><span class="extract"><span class="extract-syntax">/a/</span></span><span class="comment-syntax">, 1 for </span><span class="extract"><span class="extract-syntax">/b/</span></span><span class="comment-syntax"> and so on</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_ranges</span><span class="plain-syntax">; </span><span class="comment-syntax"> actually one more, since range 0 is reserved (see above)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">min_pr_words</span><span class="plain-syntax">, </span><span class="identifier-syntax">max_pr_words</span><span class="plain-syntax">; </span><span class="comment-syntax"> for speed</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> </span><span class="identifier-syntax">production_req</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_struts</span><span class="plain-syntax">; </span><span class="comment-syntax"> the actual number, this time</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">struts</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_STRUTS_PER_PRODUCTION</span><span class="plain-syntax">]; </span><span class="comment-syntax"> first ptoken in strut</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">strut_lengths</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_STRUTS_PER_PRODUCTION</span><span class="plain-syntax">]; </span><span class="comment-syntax"> length of the strut in words</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">production_tries</span><span class="plain-syntax">; </span><span class="comment-syntax"> used only in instrumented mode</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">production_matches</span><span class="plain-syntax">; </span><span class="comment-syntax"> ditto</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">sample_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> ditto</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_production</span><span class="plain-syntax">; </span><span class="comment-syntax"> within its production list</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">production</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure production is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;12. </b>And at the bottom of the chain, the lowly ptoken. Even this can spawn another
list, though: the token <span class="extract"><span class="extract-syntax">fried/green/tomatoes</span></span> is a list of three ptokens joined
by the <span class="extract"><span class="extract-syntax">alternative_ptoken</span></span> links.
</p>
<p class="commentary">There are two modifiers left to represent: the effects of <span class="extract"><span class="extract-syntax">^</span></span> (negation) and
<span class="extract"><span class="extract-syntax">_</span></span> (casing), and they each have flags. If the ptoken is at the head of a list
of alternatives, they apply to all of the alternatives, even though set only
for the headword.
</p>
<p class="commentary">Each ptoken has a <span class="extract"><span class="extract-syntax">range_starts</span></span> and <span class="extract"><span class="extract-syntax">range_ends</span></span> number. This is either \(-1\),
or marks that the ptoken occurs as the first or last in a range (or both). For
example, in the production
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">make</span><span class="plain-syntax"> ... </span><span class="identifier-syntax">from</span><span class="plain-syntax"> {</span><span class="identifier-syntax">rice</span><span class="plain-syntax"> ... </span><span class="identifier-syntax">onions</span><span class="plain-syntax">} </span><span class="identifier-syntax">and</span><span class="plain-syntax"> </span><span class="identifier-syntax">peppers</span>
</pre>
<p class="commentary">the first <span class="extract"><span class="extract-syntax">...</span></span> ptoken has start and end set to 1; <span class="extract"><span class="extract-syntax">rice</span></span> has start 2; <span class="extract"><span class="extract-syntax">onions</span></span>
has end 2. Note that the second <span class="extract"><span class="extract-syntax">...</span></span>, inside the braces, doesn't start or
end anything; it normally would, but the wider range consumes it.
</p>
<p class="commentary">There are really only three kinds of ptoken, wildcards, fixed words, and
nonterminals, but it's fractionally quicker to differentiate the sorts of
wildcard here, so we'll actually divide them into five. The remaining wildcard,
the <span class="extract"><span class="extract-syntax">......</span></span> form of <span class="extract"><span class="extract-syntax">...</span></span>, is represented as <span class="extract"><span class="extract-syntax">MULTIPLE_WILDCARD_PTC</span></span> but with
the <span class="extract"><span class="extract-syntax">balanced_wildcard</span></span> flag set.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">SINGLE_WILDCARD_PTC</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">MULTIPLE_WILDCARD_PTC</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">POSSIBLY_EMPTY_WILDCARD_PTC</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">NONTERMINAL_PTC</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ptoken_category</span><span class="plain-syntax">; </span><span class="comment-syntax"> one of the </span><span class="extract"><span class="extract-syntax">*_PTC</span></span><span class="comment-syntax"> values</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">negated_ptoken</span><span class="plain-syntax">; </span><span class="comment-syntax"> the </span><span class="extract"><span class="extract-syntax">^</span></span><span class="comment-syntax"> modifier applies</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">disallow_unexpected_upper</span><span class="plain-syntax">; </span><span class="comment-syntax"> the </span><span class="extract"><span class="extract-syntax">_</span></span><span class="comment-syntax"> modifier applies</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt_pt</span><span class="plain-syntax">; </span><span class="comment-syntax"> for </span><span class="extract"><span class="extract-syntax">NONTERMINAL_PTC</span></span><span class="comment-syntax"> ptokens</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve_pt</span><span class="plain-syntax">; </span><span class="comment-syntax"> for </span><span class="extract"><span class="extract-syntax">FIXED_WORD_PTC</span></span><span class="comment-syntax"> ptokens</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alternative_ptoken</span><span class="plain-syntax">; </span><span class="comment-syntax"> linked list of other vocabulary ptokens</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">balanced_wildcard</span><span class="plain-syntax">; </span><span class="comment-syntax"> for </span><span class="extract"><span class="extract-syntax">MULTIPLE_WILDCARD_PTC</span></span><span class="comment-syntax"> ptokens: brackets balanced?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">result_index</span><span class="plain-syntax">; </span><span class="comment-syntax"> for </span><span class="extract"><span class="extract-syntax">NONTERMINAL_PTC</span></span><span class="comment-syntax"> ptokens: what result number, counting from 1?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">range_starts</span><span class="plain-syntax">; </span><span class="comment-syntax"> 1, 2, 3, ... if word range 1, 2, 3, ... starts with this</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">range_ends</span><span class="plain-syntax">; </span><span class="comment-syntax"> 1, 2, 3, ... if word range 1, 2, 3, ... ends with this</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ptoken_position</span><span class="plain-syntax">; </span><span class="comment-syntax"> fixed position in range: 1, 2, ... for left, </span>\(-1\)<span class="comment-syntax">, </span>\(-2\)<span class="comment-syntax">, ... for right</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">strut_number</span><span class="plain-syntax">; </span><span class="comment-syntax"> if this is part of a strut, what number? or </span>\(-1\)<span class="comment-syntax"> if not</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ptoken_is_fast</span><span class="plain-syntax">; </span><span class="comment-syntax"> can be checked in the fast pass of the parser</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> </span><span class="identifier-syntax">token_req</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_ptoken</span><span class="plain-syntax">; </span><span class="comment-syntax"> within its production list</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure ptoken is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP13"></a><b>&#167;13. </b>The parser records the result of the most recently matched nonterminal in the
following global variables:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">most_recent_result</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> this is the variable which </span><span class="extract"><span class="extract-syntax">inweb</span></span><span class="comment-syntax"> writes </span><span class="extract"><span class="extract-syntax">&lt;&lt;r&gt;&gt;</span></span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">most_recent_result_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> this is the variable which </span><span class="extract"><span class="extract-syntax">inweb</span></span><span class="comment-syntax"> writes </span><span class="extract"><span class="extract-syntax">&lt;&lt;rp&gt;&gt;</span></span>
</pre>
<p class="commentary firstcommentary"><a id="SP14"></a><b>&#167;14. </b>Preform's aim is to purge the Inform source code of all English vocabulary,
but we do still the letters "K" and "L", to define the wording of kind constructors.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CAPITAL_K_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CAPITAL_L_V</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15"></a><b>&#167;15. </b>Preform can run in an instrumented mode, which collects statistics on the
usage of syntax it sees, but there's a performance hit for this. So it's
enabled only if the constant <span class="extract"><span class="extract-syntax">INSTRUMENTED_PREFORM</span></span> defined to <span class="extract"><span class="extract-syntax">TRUE</span></span>: here's
where to do it.
</p>
<p class="commentary firstcommentary"><a id="SP16"></a><b>&#167;16. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_requirements</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ditto_flag</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">DW_req</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">DS_req</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">CW_req</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">CS_req</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">FW_req</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">FS_req</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_req_bits</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure range_requirement is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP17"></a><b>&#167;17. Logging. </b>Descending these wheels within wheels:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::log_language</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">detailed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">INSTRUMENTED_PREFORM</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%d/%d: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_matches</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_tries</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%V: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::log_range_requirement</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">internal_definition</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" (internal)\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" $J:\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">definition_language</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">); </span><a href="4-prf.html#SP18" class="function-link"><span class="function-syntax">Preform::log_production</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">INSTRUMENTED_PREFORM</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" %d/%d: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_matches</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_tries</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-wrd.html#SP12" class="function-link"><span class="function-syntax">Wordings::nonempty</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sample_text</span><span class="plain-syntax">)) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;%W&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sample_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" ==&gt; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::log_range_requirement</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" min %d, max %d\n\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%d req bits.\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_req_bits</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18"></a><b>&#167;18. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::log_production</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Preform::log_production</span></span>:<br/><a href="4-prf.html#SP17">&#167;17</a>, <a href="4-prf.html#SP50_2">&#167;50.2</a>, <a href="4-prf.html#SP50_2_1">&#167;50.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;empty-production&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP19" class="function-link"><span class="function-syntax">Preform::log_ptoken</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19"></a><b>&#167;19. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::log_ptoken</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Preform::log_ptoken</span></span>:<br/><a href="4-prf.html#SP18">&#167;18</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"(@%d)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_number</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"(S%d)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">disallow_unexpected_upper</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"_"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"^"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"{"</span><span class="plain-syntax">); </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%d:"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%V"</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"=%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_index</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%V"</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ve_pt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"/"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_ends</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">":%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_ends</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"}"</span><span class="plain-syntax">); }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20"></a><b>&#167;20. </b>A less detailed form used in linguistic problem messages:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::write_ptoken</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">disallow_unexpected_upper</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"^"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"{"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%V"</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%V"</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ve_pt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"/"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_ends</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"}"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21"></a><b>&#167;21. </b>This is a typical internal nonterminal being defined. It's used only to parse
inclusion requests for the debugging log. Note that we use the "1" to signal
that a correct match must have exactly one word.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="function-syntax">&lt;preform-nonterminal&gt;</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP27" class="function-link"><span class="function-syntax">Preform::detect_nonterminal</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) { *</span><span class="identifier-syntax">XP</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22"></a><b>&#167;22. </b>To use which, the debugging log code needs:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::watch</span><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">watched</span><span class="plain-syntax"> = </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23"></a><b>&#167;23. Building grammar. </b>So, to begin. Since we can't use Preform to parse Preform, we have to define
its syntactic tokens by hand:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">AMPERSAND_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">BACKSLASH_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CARET_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">COLONCOLONEQUALS_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">QUESTIONMARK_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">QUOTEQUOTE_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SIXDOTS_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">THREEASTERISKS_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">THREEDOTS_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">THREEHASHES_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">UNDERSCORE_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">language_V</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">internal_V</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24"></a><b>&#167;24. </b>And off we go.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::begin</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Preform::begin</span></span>:<br/>Words Module - <a href="1-wm.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CAPITAL_K_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"k"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CAPITAL_L_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"l"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP24_1" class="named-paragraph-link"><span class="named-paragraph">Register the internal and source-code-referred-to nonterminals</span><span class="named-paragraph-number">24.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">AMPERSAND_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"&amp;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">BACKSLASH_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"\\"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CARET_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"^"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">COLONCOLONEQUALS_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">":"</span><span class="plain-syntax"> </span><span class="string-syntax">":="</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">QUESTIONMARK_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"?"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">QUOTEQUOTE_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"\"\""</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">SIXDOTS_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"......"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">THREEASTERISKS_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"***"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">THREEDOTS_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"..."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">THREEHASHES_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"###"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">UNDERSCORE_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"_"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">language_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"language"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"internal"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24_1"></a><b>&#167;24.1. </b>The tangler of <span class="extract"><span class="extract-syntax">inweb</span></span> replaces the <span class="extract"><span class="extract-syntax">[[nonterminals]]</span></span> below with
invocations of the <span class="extract"><span class="extract-syntax">REGISTER_NONTERMINAL</span></span> and <span class="extract"><span class="extract-syntax">INTERNAL_NONTERMINAL</span></span> macros.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Register the internal and source-code-referred-to nonterminals</span><span class="named-paragraph-number">24.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> [[</span><span class="identifier-syntax">nonterminals</span><span class="plain-syntax">]];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">marked_internal</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">internal_definition</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"internal undefined"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP25"></a><b>&#167;25. </b>These macros connect nonterminals with their mentions in the Inform source
code, and with the compositor routines compiled for them by <span class="extract"><span class="extract-syntax">inweb</span></span>. It invokes
<span class="extract"><span class="extract-syntax">REGISTER_NONTERMINAL</span></span> if it has compiled Preform productions for a nonterminal,
and compiled a compositor routine; the name of which is the nonterminal's name
with a <span class="extract"><span class="extract-syntax">C</span></span> suffix. If it found an internal nonterminal, it invokes
<span class="extract"><span class="extract-syntax">INTERNAL_NONTERMINAL</span></span>, and compiles a routine whose name has the suffix <span class="extract"><span class="extract-syntax">R</span></span>
as the definition.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">REGISTER_NONTERMINAL</span><span class="plain-syntax">(</span><span class="identifier-syntax">quotedname</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP27" class="function-link"><span class="function-syntax">Preform::find_nonterminal</span></a><span class="plain-syntax">(</span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">quotedname</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_compositor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">##</span><span class="identifier-syntax">C</span><span class="plain-syntax">;</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">INTERNAL_NONTERMINAL</span><span class="plain-syntax">(</span><span class="identifier-syntax">quotedname</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">min</span><span class="plain-syntax">, </span><span class="identifier-syntax">max</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP27" class="function-link"><span class="function-syntax">Preform::find_nonterminal</span></a><span class="plain-syntax">(</span><a href="2-vcb.html#SP16" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">quotedname</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">min</span><span class="plain-syntax">; </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">max</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">internal_definition</span><span class="plain-syntax"> = </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">##</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">marked_internal</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP26"></a><b>&#167;26. </b>Parsing Preform is exactly what Preform would do elegantly, but of course,
for chicken-and-egg reasons, we need to do the job by hand. Fortunately the
syntax is very simple.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::parse_preform</span><span class="plain-syntax">(</span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">break_first</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">break_first</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">, </span><span class="string-syntax">"%+W"</span><span class="plain-syntax">, </span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::one_word</span></a><span class="plain-syntax">(</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><a href="3-fds.html#SP4" class="function-link"><span class="function-syntax">Feeds::feed_stream_punctuated</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">, </span><span class="constant-syntax">PREFORM_PUNCTUATION_MARKS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">nonterminals_declared</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">) == </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PREFORM_LANGUAGE_FROM_NAME</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) &gt;= </span><span class="identifier-syntax">wn</span><span class="plain-syntax">+1) &amp;&amp; (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">) == </span><span class="identifier-syntax">language_V</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP26_1" class="named-paragraph-link"><span class="named-paragraph">Parse a definition language switch</span><span class="named-paragraph-number">26.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) &gt;= </span><span class="identifier-syntax">wn</span><span class="plain-syntax">+1) &amp;&amp; (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">+1) == </span><span class="identifier-syntax">internal_V</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP26_2" class="named-paragraph-link"><span class="named-paragraph">Parse an internal nonterminal declaration</span><span class="named-paragraph-number">26.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nonterminals_declared</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) &gt;= </span><span class="identifier-syntax">wn</span><span class="plain-syntax">+2) &amp;&amp; (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">+1) == </span><span class="identifier-syntax">COLONCOLONEQUALS_V</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP26_3" class="named-paragraph-link"><span class="named-paragraph">Parse an external nonterminal declaration</span><span class="named-paragraph-number">26.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nonterminals_declared</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"language definition failed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP31" class="function-link"><span class="function-syntax">Preform::optimise_counts</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">nonterminals_declared</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP26_1"></a><b>&#167;26.1. </b>We either switch to an existing natural language, or create a new one.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse a definition language switch</span><span class="named-paragraph-number">26.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">lname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">lname</span><span class="plain-syntax">, </span><span class="string-syntax">"%W"</span><span class="plain-syntax">, </span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::one_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">+1));</span>
<span class="plain-syntax"> </span><span class="constant-syntax">PREFORM_LANGUAGE_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PREFORM_LANGUAGE_FROM_NAME</span><span class="plain-syntax">(</span><span class="identifier-syntax">lname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nl</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Missing: %S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">lname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to define for missing language"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">lname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">language_being_read_by_Preform</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nl</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP26">&#167;26</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_2"></a><b>&#167;26.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse an internal nonterminal declaration</span><span class="named-paragraph-number">26.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP27" class="function-link"><span class="function-syntax">Preform::find_nonterminal</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"internal is defined"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">marked_internal</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP26">&#167;26</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_3"></a><b>&#167;26.3. </b>The declaration continues until the end of the text, or until we reach a
paragraph break. Internally, it's a list of productions divided by stroke symbols.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse an external nonterminal declaration</span><span class="named-paragraph-number">26.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP27" class="function-link"><span class="function-syntax">Preform::find_nonterminal</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP26_3_1" class="named-paragraph-link"><span class="named-paragraph">Find or create the production list for this language</span><span class="named-paragraph-number">26.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> += </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">x</span><span class="plain-syntax"> &lt;= </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">x</span><span class="plain-syntax">) != </span><span class="identifier-syntax">STROKE_V</span><span class="plain-syntax">) &amp;&amp; (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">x</span><span class="plain-syntax">) != </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">)) </span><span class="identifier-syntax">x</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">x</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP28" class="function-link"><span class="function-syntax">Preform::new_production</span></a><span class="plain-syntax">(</span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="identifier-syntax">x</span><span class="plain-syntax">-1), </span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pc</span><span class="plain-syntax">++);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">x</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP26_3_2" class="named-paragraph-link"><span class="named-paragraph">Place the new production within the production list</span><span class="named-paragraph-number">26.3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> &gt; </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) || (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">x</span><span class="plain-syntax">) == </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">)) </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> reached end</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">++; </span><span class="comment-syntax"> advance past the stroke and continue</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">--;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP26">&#167;26</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_3_1"></a><b>&#167;26.3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Find or create the production list for this language</span><span class="named-paragraph-number">26.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">definition_language</span><span class="plain-syntax"> == </span><span class="identifier-syntax">language_being_read_by_Preform</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">production_list</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">definition_language</span><span class="plain-syntax"> = </span><span class="identifier-syntax">language_being_read_by_Preform</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_avinue</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP26_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Place the new production list within the nonterminal</span><span class="named-paragraph-number">26.3.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP26_3">&#167;26.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_3_1_1"></a><b>&#167;26.3.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Place the new production list within the nonterminal</span><span class="named-paragraph-number">26.3.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">first_production_list</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">)) </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_production_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP26_3_1">&#167;26.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_3_2"></a><b>&#167;26.3.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Place the new production within the production list</span><span class="named-paragraph-number">26.3.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">)) </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_production</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP26_3">&#167;26.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP27"></a><b>&#167;27. </b>Nonterminals are identified by their name-words:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="function-syntax">Preform::detect_nonterminal</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Preform::detect_nonterminal</span></span>:<br/><a href="4-prf.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> == </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="function-syntax">Preform::find_nonterminal</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Preform::find_nonterminal</span></span>:<br/><a href="4-prf.html#SP25">&#167;25</a>, <a href="4-prf.html#SP26_2">&#167;26.2</a>, <a href="4-prf.html#SP26_3">&#167;26.3</a>, <a href="4-prf.html#SP30">&#167;30</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP27" class="function-link"><span class="function-syntax">Preform::detect_nonterminal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ve</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">voracious</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">multiplicitous</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">optimised_in_this_pass</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_req_bit</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">marked_internal</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">internal_definition</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_compositor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_words_by_production</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">flag_words_in_production</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_RANGES_PER_PRODUCTION</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_result</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="constant-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">watched</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_tries</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_matches</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP28"></a><b>&#167;28. </b>We now descend to the creation of productions for (external) nonterminals.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="function-syntax">Preform::new_production</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Preform::new_production</span></span>:<br/><a href="4-prf.html#SP26_3">&#167;26.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">production</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">match_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_ranges</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="comment-syntax"> so that they count from 1; range 0 is unused</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_struts</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> they will be detected later</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_pr_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_pr_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_tries</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_matches</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sample_text</span><span class="plain-syntax"> = </span><span class="constant-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">head</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">tail</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP28_1" class="named-paragraph-link"><span class="named-paragraph">Parse the row of production tokens into a linked list of ptokens</span><span class="named-paragraph-number">28.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">head</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP28_1"></a><b>&#167;28.1. </b></p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">OUTSIDE_PTBRACE</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ABOUT_TO_OPEN_PTBRACE</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">INSIDE_PTBRACE</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the row of production tokens into a linked list of ptokens</span><span class="named-paragraph-number">28.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">result_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">negation_modifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">lower_case_modifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bracing_mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">OUTSIDE_PTBRACE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">bracing_begins_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">tc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP28_1_1" class="named-paragraph-link"><span class="named-paragraph">Parse the token modifier symbols</span><span class="named-paragraph-number">28.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP29" class="function-link"><span class="function-syntax">Preform::parse_slashed_chain</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; </span><span class="comment-syntax"> we have set the production match number instead</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">NONTERMINAL_PTC</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP28_1_3" class="named-paragraph-link"><span class="named-paragraph">Assign the ptoken a result number</span><span class="named-paragraph-number">28.1.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP28_1_2" class="named-paragraph-link"><span class="named-paragraph">Modify the new token according to the current token modifier settings</span><span class="named-paragraph-number">28.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tc</span><span class="plain-syntax">++ &lt; </span><span class="constant-syntax">MAX_PTOKENS_PER_PRODUCTION</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">head</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">head</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">tail</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">tail</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP28">&#167;28</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP28_1_1"></a><b>&#167;28.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the token modifier symbols</span><span class="named-paragraph-number">28.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CARET_V</span><span class="plain-syntax">) { </span><span class="identifier-syntax">negation_modifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">UNDERSCORE_V</span><span class="plain-syntax">) { </span><span class="identifier-syntax">lower_case_modifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">BACKSLASH_V</span><span class="plain-syntax">) { </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bracing_mode</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">OUTSIDE_PTBRACE:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACE_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">bracing_mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">ABOUT_TO_OPEN_PTBRACE</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INSIDE_PTBRACE:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACE_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bracing_begins_at</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rnum</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_ranges</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2 &lt;= </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">+1) == </span><span class="identifier-syntax">QUESTIONMARK_V</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="2-vcb.html#SP11" class="function-link"><span class="function-syntax">Vocabulary::test_flags</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2, </span><span class="constant-syntax">NUMBER_MC</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rnum</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP9" class="function-link"><span class="function-syntax">Vocabulary::get_literal_number_value</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> += </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">bracing_begins_at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rnum</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">tail</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_ends</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rnum</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">bracing_mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">OUTSIDE_PTBRACE</span><span class="plain-syntax">; </span><span class="identifier-syntax">bracing_begins_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP28_1">&#167;28.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP28_1_2"></a><b>&#167;28.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Modify the new token according to the current token modifier settings</span><span class="named-paragraph-number">28.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">negation_modifier</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lower_case_modifier</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">disallow_unexpected_upper</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">negation_modifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lower_case_modifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bracing_mode</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">OUTSIDE_PTBRACE:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">SINGLE_WILDCARD_PTC</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">MULTIPLE_WILDCARD_PTC</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">POSSIBLY_EMPTY_WILDCARD_PTC</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> &amp;&amp; (</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_ranges</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">MAX_RANGES_PER_PRODUCTION</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rnum</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_ranges</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rnum</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_ends</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rnum</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ABOUT_TO_OPEN_PTBRACE:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_ranges</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">MAX_RANGES_PER_PRODUCTION</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">bracing_begins_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">bracing_mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">INSIDE_PTBRACE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP28_1">&#167;28.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP28_1_3"></a><b>&#167;28.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Assign the ptoken a result number</span><span class="named-paragraph-number">28.1.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">result_count</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">MAX_RESULTS_PER_PRODUCTION</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2 &lt;= </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">+1) == </span><span class="identifier-syntax">QUESTIONMARK_V</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="2-vcb.html#SP11" class="function-link"><span class="function-syntax">Vocabulary::test_flags</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2, </span><span class="constant-syntax">NUMBER_MC</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_index</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP9" class="function-link"><span class="function-syntax">Vocabulary::get_literal_number_value</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> += </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_index</span><span class="plain-syntax"> = </span><span class="identifier-syntax">result_count</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">result_count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP28_1">&#167;28.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP29"></a><b>&#167;29. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="function-syntax">Preform::parse_slashed_chain</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Preform::parse_slashed_chain</span></span>:<br/><a href="4-prf.html#SP28_1">&#167;28.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::one_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP29_1" class="named-paragraph-link"><span class="named-paragraph">Expand the word range if the token text is slashed</span><span class="named-paragraph-number">29.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP29_2" class="named-paragraph-link"><span class="named-paragraph">Parse the word range into a linked list of alternative ptokens</span><span class="named-paragraph-number">29.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP29_1"></a><b>&#167;29.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Expand the word range if the token text is slashed</span><span class="named-paragraph-number">29.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word_raw_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">, </span><span class="identifier-syntax">breakme</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">[0] == </span><span class="character-syntax">'/'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">islower</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[1])) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[2] == </span><span class="character-syntax">'/'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[3] == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">match_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">[1] - </span><span class="character-syntax">'a'</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">[0] == </span><span class="character-syntax">'/'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">islower</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[1])) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[2] == </span><span class="identifier-syntax">p</span><span class="plain-syntax">[1]) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[3] == </span><span class="character-syntax">'/'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[4] == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">match_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">[1] - </span><span class="character-syntax">'a'</span><span class="plain-syntax"> + </span><span class="constant-syntax">26</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k</span><span class="plain-syntax">=0; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">]) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+1]); </span><span class="identifier-syntax">k</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">k</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">] == </span><span class="character-syntax">'/'</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">breakme</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">breakme</span><span class="plain-syntax">) </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><a href="3-fds.html#SP5" class="function-link"><span class="function-syntax">Feeds::feed_text_full</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"/"</span><span class="plain-syntax">); </span><span class="comment-syntax"> break only at slashes</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP29">&#167;29</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP29_2"></a><b>&#167;29.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the word range into a linked list of alternative ptokens</span><span class="named-paragraph-number">29.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (; </span><a href="3-wrd.html#SP12" class="function-link"><span class="function-syntax">Wordings::nonempty</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">); </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP9" class="function-link"><span class="function-syntax">Wordings::trim_first_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">)) != </span><span class="identifier-syntax">FORWARDSLASH_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">latest</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP30" class="function-link"><span class="function-syntax">Preform::new_ptoken</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">)), </span><span class="identifier-syntax">mode</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">match_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">latest</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">latest</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">latest</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP29">&#167;29</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP30"></a><b>&#167;30. </b>So we come to the end of the trail: the code to create a single ptoken.
In "escaped" mode, where a backslash has made the text literal, it just
becomes a fixed word; otherwise it could be any of the five categories.
</p>
<p class="commentary">If the text refers to a nonterminal which doesn't yet exist, then this
creates it; that's how we deal with forward references.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="function-syntax">Preform::new_ptoken</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Preform::new_ptoken</span></span>:<br/><a href="4-prf.html#SP29_2">&#167;29.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">ptoken</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">disallow_unexpected_upper</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_index</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax"> = -1; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_ends</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_number</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ve_pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">balanced_wildcard</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_is_fast</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP8" class="function-link"><span class="function-syntax">Vocabulary::get_exemplar</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[0] == </span><span class="character-syntax">'&lt;'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">Wide::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)-1] == </span><span class="character-syntax">'&gt;'</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP27" class="function-link"><span class="function-syntax">Preform::find_nonterminal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">NONTERMINAL_PTC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ve_pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ve</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> == </span><span class="identifier-syntax">SIXDOTS_V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">MULTIPLE_WILDCARD_PTC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">balanced_wildcard</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> == </span><span class="identifier-syntax">THREEDOTS_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">MULTIPLE_WILDCARD_PTC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> == </span><span class="identifier-syntax">THREEHASHES_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">SINGLE_WILDCARD_PTC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> == </span><span class="identifier-syntax">THREEASTERISKS_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">POSSIBLY_EMPTY_WILDCARD_PTC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ve</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">flags</span><span class="plain-syntax"> |= (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">flag_words_in_production</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_words_by_production</span><span class="plain-syntax">) </span><span class="identifier-syntax">ve</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">literal_number_value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP31"></a><b>&#167;31. Optimisation calculations. </b>After each round of fresh Preform grammar, we need to recalculate the various
maximum and minimum lengths, struts, and so on, because those all depend on
knowing the length of text a token will match, and new grammar may have
changed that.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">first_round_of_nt_optimisation_made</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::optimise_counts</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Preform::optimise_counts</span></span>:<br/><a href="4-prf.html#SP26">&#167;26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::clear_rreq</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">marked_internal</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">optimised_in_this_pass</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">optimised_in_this_pass</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_round_of_nt_optimisation_made</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">first_round_of_nt_optimisation_made</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">LINGUISTICS_MODULE</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LinguisticsModule::preform_optimiser</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PREFORM_OPTIMISER</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PREFORM_OPTIMISER</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax">) </span><a href="4-prf.html#SP31" class="function-link"><span class="function-syntax">Preform::optimise_nt</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax">) </span><a href="4-prf.html#SP32" class="function-link"><span class="function-syntax">Preform::optimise_nt_reqs</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::optimise_nt</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Preform::optimise_nt</span></span>:<br/><a href="4-prf.html#SP31_6">&#167;31.6</a>, <a href="4-prf.html#SP48">&#167;48</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">optimised_in_this_pass</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">optimised_in_this_pass</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP31_1" class="named-paragraph-link"><span class="named-paragraph">Compute the minimum and maximum match lengths</span><span class="named-paragraph-number">31.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> this will point to the last ptoken in the production</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP31_2" class="named-paragraph-link"><span class="named-paragraph">Compute front-end ptoken positions</span><span class="named-paragraph-number">31.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP31_3" class="named-paragraph-link"><span class="named-paragraph">Compute back-end ptoken positions</span><span class="named-paragraph-number">31.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP31_4" class="named-paragraph-link"><span class="named-paragraph">Compute struts within the production</span><span class="named-paragraph-number">31.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP31_5" class="named-paragraph-link"><span class="named-paragraph">Work out which ptokens are fast</span><span class="named-paragraph-number">31.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP31_6" class="named-paragraph-link"><span class="named-paragraph">Mark the vocabulary's incidence list with this nonterminal</span><span class="named-paragraph-number">31.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP31_1"></a><b>&#167;31.1. </b>The minimum matched text length for a nonterminal is the smallest of the
minima for its possible productions; for a production, it's the sum of the
minimum match lengths of its tokens.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compute the minimum and maximum match lengths</span><span class="named-paragraph-number">31.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">min</span><span class="plain-syntax"> = -1, </span><span class="identifier-syntax">max</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">min_p</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">max_p</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">min_t</span><span class="plain-syntax">, </span><span class="identifier-syntax">max_t</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP48" class="function-link"><span class="function-syntax">Preform::ptoken_extrema</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">min_t</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">max_t</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">min_p</span><span class="plain-syntax"> += </span><span class="identifier-syntax">min_t</span><span class="plain-syntax">; </span><span class="identifier-syntax">max_p</span><span class="plain-syntax"> += </span><span class="identifier-syntax">max_t</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">min_p</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">) </span><span class="identifier-syntax">min_p</span><span class="plain-syntax"> = </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">max_p</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">) </span><span class="identifier-syntax">max_p</span><span class="plain-syntax"> = </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_pr_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">min_p</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_pr_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">max_p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">min</span><span class="plain-syntax"> == -1) &amp;&amp; (</span><span class="identifier-syntax">max</span><span class="plain-syntax"> == -1)) { </span><span class="identifier-syntax">min</span><span class="plain-syntax"> = </span><span class="identifier-syntax">min_p</span><span class="plain-syntax">; </span><span class="identifier-syntax">max</span><span class="plain-syntax"> = </span><span class="identifier-syntax">max_p</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">min_p</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">min</span><span class="plain-syntax">) </span><span class="identifier-syntax">min</span><span class="plain-syntax"> = </span><span class="identifier-syntax">min_p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">max_p</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">max</span><span class="plain-syntax">) </span><span class="identifier-syntax">max</span><span class="plain-syntax"> = </span><span class="identifier-syntax">max_p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">min</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">min</span><span class="plain-syntax">; </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">max</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP31">&#167;31</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_2"></a><b>&#167;31.2. </b>A token is "elastic" if it can match text of differing lengths, and
"inelastic" otherwise. For example, in English, &lt;indefinite-article&gt; is
elastic (it always matches a single word). If the first ptoken is inelastic,
we know it must match words 1 to \(L_1\) of whatever text is to be matched,
and we give it position 1; if the second is also inelastic, that will match
\(L_1+1\) to \(L_2\), and it gets position \(L_1+1\); and so on. As soon as we
hit an elastic token &mdash; a wildcard like <span class="extract"><span class="extract-syntax">...</span></span>, for example &mdash; this
predictability stops, and we can only assign position 0, which means that
we don't know.
</p>
<p class="commentary">Note that we only assign a nonzero position if we know where the ptoken both
starts and finishes; it's not enough just to know where it starts.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compute front-end ptoken positions</span><span class="named-paragraph-number">31.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">posn</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP47" class="function-link"><span class="function-syntax">Preform::ptoken_width</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">posn</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> != </span><span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">posn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">posn</span><span class="plain-syntax"> += </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> thus clearing any expired positions from earlier</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">posn</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP31">&#167;31</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_3"></a><b>&#167;31.3. </b>And similarly from the back end, if there are inelastic ptokens at the end
of the production (and which are separated from the front end by at least one
elastic one).
</p>
<p class="commentary">The following has quadratic running time in the number of tokens in the
production, but this is never larger than about 10.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compute back-end ptoken positions</span><span class="named-paragraph-number">31.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">posn</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; ) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> don't use a back-end position if there's a front one</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP47" class="function-link"><span class="function-syntax">Preform::ptoken_width</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">posn</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> != </span><span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">posn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">posn</span><span class="plain-syntax"> -= </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prevt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prevt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">prevt</span><span class="plain-syntax">; </span><span class="identifier-syntax">prevt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prevt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prevt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">pt</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prevt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP31">&#167;31</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_4"></a><b>&#167;31.4. </b>By definition, a strut is a maximal sequence of one or more inelastic ptokens
each of which has no known position. (Clearly if one of them has a known
position then all of them have, but we're in no hurry so we don't exploit that.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compute struts within the production</span><span class="named-paragraph-number">31.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_struts</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><a href="4-prf.html#SP47" class="function-link"><span class="function-syntax">Preform::ptoken_width</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">) != </span><span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_struts</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_STRUTS_PER_PRODUCTION</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">struts</span><span class="plain-syntax">[</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_struts</span><span class="plain-syntax">] = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_struts</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><a href="4-prf.html#SP47" class="function-link"><span class="function-syntax">Preform::ptoken_width</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">) != </span><span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_struts</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_struts</span><span class="plain-syntax">] += </span><a href="4-prf.html#SP47" class="function-link"><span class="function-syntax">Preform::ptoken_width</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> should be impossible</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_struts</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP31">&#167;31</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_5"></a><b>&#167;31.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Work out which ptokens are fast</span><span class="named-paragraph-number">31.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_ends</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_is_fast</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP31">&#167;31</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_6"></a><b>&#167;31.6. </b>Weak requirement: one word in range must match one of these bits
Strong ": all bits in this range must be matched by one word
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Mark the vocabulary's incidence list with this nonterminal</span><span class="named-paragraph-number">31.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">first_production</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::clear_rreq</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PREFORM_CIRCULARITY_BREAKER</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PREFORM_CIRCULARITY_BREAKER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> </span><span class="identifier-syntax">nnt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::clear_rreq</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">nnt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP33" class="function-link"><span class="function-syntax">Preform::set_nt_incidence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ve_pt</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> </span><span class="identifier-syntax">prt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::clear_rreq</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">prt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">all</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">first</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::clear_rreq</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">token_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP33" class="function-link"><span class="function-syntax">Preform::set_nt_incidence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ve_pt</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::atomic_rreq</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">token_req</span><span class="plain-syntax">), </span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">all</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">self_referential</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">empty</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">NONTERMINAL_PTC</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">empty</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> even if negated, notice</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">NONTERMINAL_PTC</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> if (pt-&gt;nt_pt == nt) self_referential = TRUE;</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP31" class="function-link"><span class="function-syntax">Preform::optimise_nt</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">token_req</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">self_referential</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">empty</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">token_req</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP36" class="function-link"><span class="function-syntax">Preform::concatenate_rreq</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">prt</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">token_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">first</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nnt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP42" class="function-link"><span class="function-syntax">Preform::disjoin_rreq</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">nnt</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">prt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">first_production</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_req</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nnt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PREFORM_CIRCULARITY_BREAKER</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PREFORM_CIRCULARITY_BREAKER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP31">&#167;31</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP32"></a><b>&#167;32. </b></p>
<p class="commentary">The constant <span class="extract"><span class="extract-syntax">AL_BITMAP</span></span> used in this code has a pleasingly Arabic sound to it
&mdash; a second-magnitude star, an idiotically tall hotel &mdash; but is in fact a
combination of the meaning codes found in an adjective list.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::optimise_nt_reqs</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Preform::optimise_nt_reqs</span></span>:<br/><a href="4-prf.html#SP31">&#167;31</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prev_req</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP32" class="function-link"><span class="function-syntax">Preform::optimise_req</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_req</span><span class="plain-syntax">), </span><span class="identifier-syntax">prev_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prev_req</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP32" class="function-link"><span class="function-syntax">Preform::optimise_req</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::optimise_req</span><span class="plain-syntax">(</span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax">, </span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prev</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_requirements</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_requirements</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ditto_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">prev</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ditto_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP33"></a><b>&#167;33. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::mark_nt_as_requiring_itself</span><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::mark_nt_as_requiring_itself_first</span><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">FS_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::mark_nt_as_requiring_itself_conj</span><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">CS_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">FS_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::mark_nt_as_requiring_itself_augmented</span><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) + </span><span class="identifier-syntax">x</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">.</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) + </span><span class="identifier-syntax">x</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::set_nt_incidence</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Preform::set_nt_incidence</span></span>:<br/><a href="4-prf.html#SP31_6">&#167;31.6</a>, <a href="4-prf.html#SP34">&#167;34</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::get_ntb</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax"> |= (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::set_ntb</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::test_nt_incidence</span><span class="plain-syntax">(</span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::get_ntb</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> &amp; (</span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP34"></a><b>&#167;34. </b></p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">RESERVED_NT_BITS</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::nt_bitmap_bit</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Preform::nt_bitmap_bit</span></span>:<br/><a href="4-prf.html#SP33">&#167;33</a>, <a href="4-prf.html#SP46">&#167;46</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_req_bit</span><span class="plain-syntax"> == -1) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><span class="constant-syntax">RESERVED_NT_BITS</span><span class="plain-syntax"> + ((</span><span class="identifier-syntax">no_req_bits</span><span class="plain-syntax">++)%(32-</span><span class="constant-syntax">RESERVED_NT_BITS</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_req_bit</span><span class="plain-syntax"> = (1 &lt;&lt; </span><span class="identifier-syntax">b</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_req_bit</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"null NT"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_req_bit</span><span class="plain-syntax"> = (1 &lt;&lt; </span><span class="identifier-syntax">b</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::test_word</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::get_ntb</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">))) &amp; </span><span class="identifier-syntax">b</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::mark_word</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP33" class="function-link"><span class="function-syntax">Preform::set_nt_incidence</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">), </span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::mark_vocabulary</span><span class="plain-syntax">(</span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP33" class="function-link"><span class="function-syntax">Preform::set_nt_incidence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::test_vocabulary</span><span class="plain-syntax">(</span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::get_ntb</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">)) &amp; </span><span class="identifier-syntax">b</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::get_range_disjunction</span><span class="plain-syntax">(</span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax"> |= </span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::get_ntb</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::get_range_conjunction</span><span class="plain-syntax">(</span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::get_ntb</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax"> &amp;= </span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::get_ntb</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP35"></a><b>&#167;35. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::nt_bitmap_violates</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Preform::nt_bitmap_violates</span></span>:<br/><a href="4-prf.html#SP50_2">&#167;50.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_requirements</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) == </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bm</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::get_ntb</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">C_set</span><span class="plain-syntax"> = ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">) | (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">D_set</span><span class="plain-syntax"> = ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) | (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">F_set</span><span class="plain-syntax"> = ((</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) | (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">C_set</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">D_set</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">disj</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bm</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::get_ntb</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">disj</span><span class="plain-syntax"> |= </span><span class="identifier-syntax">bm</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">F_set</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">disj</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">disj</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_set</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bm</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::get_ntb</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">F_set</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D_set</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">disj</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bm</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::get_ntb</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">disj</span><span class="plain-syntax"> |= </span><span class="identifier-syntax">bm</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">F_set</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">disj</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">disj</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">F_set</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bm</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP13" class="function-link"><span class="function-syntax">Vocabulary::get_ntb</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP36"></a><b>&#167;36. </b>The first operation on RRs is concatenation. Suppose we are required to
match some words against X, then some more against Y.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::concatenate_rreq</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Preform::concatenate_rreq</span></span>:<br/><a href="4-prf.html#SP31_6">&#167;31.6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax">, </span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">with</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP37" class="function-link"><span class="function-syntax">Preform::concatenate_ds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP39" class="function-link"><span class="function-syntax">Preform::concatenate_dw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP38" class="function-link"><span class="function-syntax">Preform::concatenate_cs</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP40" class="function-link"><span class="function-syntax">Preform::concatenate_cw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP41" class="function-link"><span class="function-syntax">Preform::concatenate_fs</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP41" class="function-link"><span class="function-syntax">Preform::concatenate_fw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP37"></a><b>&#167;37. </b>The strong requirements are well-defined. Suppose all of the bits of <span class="extract"><span class="extract-syntax">m1</span></span>
are found in X, and all of the bits of <span class="extract"><span class="extract-syntax">m2</span></span> are found in Y. Then clearly
all of the bits in the union of these two sets are found in XY, and that's
the strongest requirement we can make. So:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::concatenate_ds</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Preform::concatenate_ds</span></span>:<br/><a href="4-prf.html#SP36">&#167;36</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax"> | </span><span class="identifier-syntax">m2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP38"></a><b>&#167;38. </b>Similarly, suppose all of the bits of <span class="extract"><span class="extract-syntax">m1</span></span> are found in every word of X,
and all of those of <span class="extract"><span class="extract-syntax">m2</span></span> are in every word of Y. The most which can be said
about every word of XY is to take the intersection, so:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::concatenate_cs</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Preform::concatenate_cs</span></span>:<br/><a href="4-prf.html#SP36">&#167;36</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">m2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP39"></a><b>&#167;39. </b>Now suppose that at least one bit of <span class="extract"><span class="extract-syntax">m1</span></span> can be found in X, and one bit
of <span class="extract"><span class="extract-syntax">m2</span></span> can be found in Y. This gives us two pieces of information about
XY, and we can freely choose which to go for: we may as well pick <span class="extract"><span class="extract-syntax">m1</span></span> and
say that one bit of <span class="extract"><span class="extract-syntax">m1</span></span> can be found in XY. In principle we ought to choose
the rarest for best effect, but that's too much work.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::concatenate_dw</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Preform::concatenate_dw</span></span>:<br/><a href="4-prf.html#SP36">&#167;36</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m1</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">; </span><span class="comment-syntax"> the case where we have no information about X</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m2</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">; </span><span class="comment-syntax"> and about Y</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">; </span><span class="comment-syntax"> the general case discussed above</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP40"></a><b>&#167;40. </b>Now suppose that each word of X matches at least one bit of <span class="extract"><span class="extract-syntax">m1</span></span>, and
similarly for Y and <span class="extract"><span class="extract-syntax">m2</span></span>. Then each word of XY matches at least one bit of
the union, so:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::concatenate_cw</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">Preform::concatenate_cw</span></span>:<br/><a href="4-prf.html#SP36">&#167;36</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m1</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> the case where we have no information about X</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m2</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> and about Y</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax"> | </span><span class="identifier-syntax">m2</span><span class="plain-syntax">; </span><span class="comment-syntax"> the general case discussed above</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP41"></a><b>&#167;41. </b>The first word of XY is the first word of X, so:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::concatenate_fs</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">Preform::concatenate_fs</span></span>:<br/><a href="4-prf.html#SP36">&#167;36</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::concatenate_fw</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">Preform::concatenate_fw</span></span>:<br/><a href="4-prf.html#SP36">&#167;36</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP42"></a><b>&#167;42. </b>The second operation is disjunction: we'll write X/Y, meaning that the text
has to match either X or Y. This is easier, since it amounts to a disguised
form of de Morgan's laws.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::disjoin_rreq</span><button class="popup" onclick="togglePopup('usagePopup22')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup22">Usage of <span class="code-font"><span class="function-syntax">Preform::disjoin_rreq</span></span>:<br/><a href="4-prf.html#SP31_6">&#167;31.6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax">, </span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">with</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP43" class="function-link"><span class="function-syntax">Preform::disjoin_ds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP45" class="function-link"><span class="function-syntax">Preform::disjoin_dw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP44" class="function-link"><span class="function-syntax">Preform::disjoin_cs</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::disjoin_cw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::disjoin_fs</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::disjoin_fw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP43"></a><b>&#167;43. </b>Suppose all of the bits of <span class="extract"><span class="extract-syntax">m1</span></span> are found in X, and all of the bits of <span class="extract"><span class="extract-syntax">m2</span></span>
are found in Y. Then the best we can say is that all of the bits in the
intersection of these two sets are found in X/Y. (If they have no bits in
common, we can't say anything.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::disjoin_ds</span><button class="popup" onclick="togglePopup('usagePopup23')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup23">Usage of <span class="code-font"><span class="function-syntax">Preform::disjoin_ds</span></span>:<br/><a href="4-prf.html#SP42">&#167;42</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">m2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP44"></a><b>&#167;44. </b>Similarly, suppose all of the bits of <span class="extract"><span class="extract-syntax">m1</span></span> are found in every word of X,
and all of those of <span class="extract"><span class="extract-syntax">m2</span></span> are in every word of Y. The most which can be said
about every word of XY is to take the intersection, so:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::disjoin_cs</span><button class="popup" onclick="togglePopup('usagePopup24')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup24">Usage of <span class="code-font"><span class="function-syntax">Preform::disjoin_cs</span></span>:<br/><a href="4-prf.html#SP42">&#167;42</a>, <a href="4-prf.html#SP46">&#167;46</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">m2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP45"></a><b>&#167;45. </b>Now suppose that at least one bit of <span class="extract"><span class="extract-syntax">m1</span></span> can be found in X, and one bit
of <span class="extract"><span class="extract-syntax">m2</span></span> can be found in Y. All we can say is that one of these various bits
must be found in X/Y, so:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::disjoin_dw</span><button class="popup" onclick="togglePopup('usagePopup25')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup25">Usage of <span class="code-font"><span class="function-syntax">Preform::disjoin_dw</span></span>:<br/><a href="4-prf.html#SP42">&#167;42</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m1</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> the case where we have no information about X</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m2</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> and about Y</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax"> | </span><span class="identifier-syntax">m2</span><span class="plain-syntax">; </span><span class="comment-syntax"> the general case discussed above</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP46"></a><b>&#167;46. </b>And exactly the same is true for conjunctions:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::disjoin_cw</span><button class="popup" onclick="togglePopup('usagePopup26')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup26">Usage of <span class="code-font"><span class="function-syntax">Preform::disjoin_cw</span></span>:<br/><a href="4-prf.html#SP42">&#167;42</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m1</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> the case where we have no information about X</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m2</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> and about Y</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax"> | </span><span class="identifier-syntax">m2</span><span class="plain-syntax">; </span><span class="comment-syntax"> the general case discussed above</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::disjoin_fw</span><button class="popup" onclick="togglePopup('usagePopup27')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup27">Usage of <span class="code-font"><span class="function-syntax">Preform::disjoin_fw</span></span>:<br/><a href="4-prf.html#SP42">&#167;42</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::disjoin_cw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="identifier-syntax">m2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::disjoin_fs</span><button class="popup" onclick="togglePopup('usagePopup28')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup28">Usage of <span class="code-font"><span class="function-syntax">Preform::disjoin_fs</span></span>:<br/><a href="4-prf.html#SP42">&#167;42</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-prf.html#SP44" class="function-link"><span class="function-syntax">Preform::disjoin_cs</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">m1</span><span class="plain-syntax">, </span><span class="identifier-syntax">m2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::clear_rreq</span><button class="popup" onclick="togglePopup('usagePopup29')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup29">Usage of <span class="code-font"><span class="function-syntax">Preform::clear_rreq</span></span>:<br/><a href="4-prf.html#SP31">&#167;31</a>, <a href="4-prf.html#SP31_6">&#167;31.6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::atomic_rreq</span><button class="popup" onclick="togglePopup('usagePopup30')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup30">Usage of <span class="code-font"><span class="function-syntax">Preform::atomic_rreq</span></span>:<br/><a href="4-prf.html#SP31_6">&#167;31.6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP34" class="function-link"><span class="function-syntax">Preform::nt_bitmap_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> = </span><span class="identifier-syntax">b</span><span class="plain-syntax">; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><span class="identifier-syntax">b</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax"> = </span><span class="identifier-syntax">b</span><span class="plain-syntax">; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> = </span><span class="identifier-syntax">b</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::log_range_requirement</span><button class="popup" onclick="togglePopup('usagePopup31')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup31">Usage of <span class="code-font"><span class="function-syntax">Preform::log_range_requirement</span></span>:<br/><a href="4-prf.html#SP17">&#167;17</a>, <a href="4-prf.html#SP50_2">&#167;50.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">range_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" DW: %08x"</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" DS: %08x"</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" CW: %08x"</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" CS: %08x"</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" FW: %08x"</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" FS: %08x"</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">); }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP47"></a><b>&#167;47. </b>Now to define elasticity:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax"> -1</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::ptoken_width</span><button class="popup" onclick="togglePopup('usagePopup32')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup32">Usage of <span class="code-font"><span class="function-syntax">Preform::ptoken_width</span></span>:<br/><a href="4-prf.html#SP31_2">&#167;31.2</a>, <a href="4-prf.html#SP31_3">&#167;31.3</a>, <a href="4-prf.html#SP31_4">&#167;31.4</a>, <a href="4-prf.html#SP50_2_1_2_3_3_3_1">&#167;50.2.1.2.3.3.3.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">min</span><span class="plain-syntax">, </span><span class="identifier-syntax">max</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP48" class="function-link"><span class="function-syntax">Preform::ptoken_extrema</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">min</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">max</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">min</span><span class="plain-syntax"> != </span><span class="identifier-syntax">max</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">min</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP48"></a><b>&#167;48. </b>An interesting point here is that the negation of a ptoken can in principle
have any length, except that we specified <span class="extract"><span class="extract-syntax">^ example</span></span> to match only a single
word &mdash; any word other than "example". So the extrema for <span class="extract"><span class="extract-syntax">^ example</span></span> are
1 and 1, whereas for <span class="extract"><span class="extract-syntax">^ &lt;sample-nonterminal&gt;</span></span> they would have to be 0 and
infinity.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::ptoken_extrema</span><button class="popup" onclick="togglePopup('usagePopup33')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup33">Usage of <span class="code-font"><span class="function-syntax">Preform::ptoken_extrema</span></span>:<br/><a href="4-prf.html#SP31_1">&#167;31.1</a>, <a href="4-prf.html#SP47">&#167;47</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">min_t</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">max_t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">min_t</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; *</span><span class="identifier-syntax">max_t</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> != </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">) { *</span><span class="identifier-syntax">min_t</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; *</span><span class="identifier-syntax">max_t</span><span class="plain-syntax"> = </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NONTERMINAL_PTC:</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP31" class="function-link"><span class="function-syntax">Preform::optimise_nt</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">); </span><span class="comment-syntax"> recurse as needed to find its extrema</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">min_t</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">max_t</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MULTIPLE_WILDCARD_PTC:</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">max_t</span><span class="plain-syntax"> = </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">POSSIBLY_EMPTY_WILDCARD_PTC:</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">min_t</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">max_t</span><span class="plain-syntax"> = </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP49"></a><b>&#167;49. Parsing. </b>Since I have found that well-known computer programmers look at me strangely
when I tell them that Inform doesn't use <span class="extract"><span class="extract-syntax">yacc</span></span>, or <span class="extract"><span class="extract-syntax">antlr</span></span>, or for that
matter any of the elegant theory of LALR parsers, perhaps an explanation
is called for.
</p>
<p class="commentary">One reason is that I am sceptical that formal grammars specify natural language
terribly well &mdash; which is ironic, considering that the relevant computer
science, dating from the 1950s and 1960s, was strongly influenced by Noam
Chomsky's generative linguistics. Such formal descriptions tend to be too rigid
to be applied universally. The classical use case for <span class="extract"><span class="extract-syntax">yacc</span></span> is to manage
hierarchies of associative operators on different levels: well, natural language
doesn't have those.
</p>
<p class="commentary">Another reason is that <span class="extract"><span class="extract-syntax">yacc</span></span>-style grammars tend to react badly to uncompliant
input: that is, they correctly reject it, but are bad at diagnosing the
problem, and at recovering their wits afterwards. For Inform purposes, this
would be too sloppy: the user more often miscompiles than compiles, and quality
lies in how good our problem messages are in reply.
</p>
<p class="commentary">Lastly, there are two pragmatic reasons. In order to make Preform grammar
extensible, we couldn't use a parser-compiler like <span class="extract"><span class="extract-syntax">yacc</span></span> anyway: we have to
interpret our grammar, not compile code to parse it. And we also want speed;
folk wisdom has it that <span class="extract"><span class="extract-syntax">yacc</span></span> parsers are about half as fast as a shrewdly
hand-coded equivalent. (<span class="extract"><span class="extract-syntax">gcc</span></span> abandoned the use of <span class="extract"><span class="extract-syntax">bison</span></span> for exactly this
reason some years ago.) Until Preform's arrival in February 2011, Inform had a
hard-coded syntax analyser scattered throughout its code, which often made what
were provably the minimum possible number of comparisons. Even Preform's
parser is intentionally lean.
</p>
<p class="commentary firstcommentary"><a id="SP50"></a><b>&#167;50. </b>Make of that apologia what you will. Speed is important in the following
code, but not critical: I optimised it until profiling showed that Inform spent
only about 6\% of its time here.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ptraci</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> in this mode, we trace parsing to the debugging log</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> in this mode, we are looking ahead</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">fail_nonterminal_quantum</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> jump forward by this many words in lookahead</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">preform_backtrack</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> position to backtrack from in voracious internal</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::parse_nt_against_word_range</span><button class="popup" onclick="togglePopup('usagePopup34')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup34">Usage of <span class="code-font"><span class="function-syntax">Preform::parse_nt_against_word_range</span></span>:<br/><a href="4-prf.html#SP50_2_1_2_3_3_5">&#167;50.2.1.2.3.3.5</a>, <a href="4-prf.html#SP50_2_1_2_3_3_3_1">&#167;50.2.1.2.3.3.3.1</a>, <a href="4-prf.html#SP51">&#167;51</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">result</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> **</span><span class="identifier-syntax">result_p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">start_of_nt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">time</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can't parse a null nonterminal"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">INSTRUMENTED_PREFORM</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_tries</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">success_rval</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> what to return in the event of a successful match</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">fail_nonterminal_quantum</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">teppic</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">; </span><span class="comment-syntax"> Teppic saves Ptraci</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ptraci</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">watched</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">ptraci</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%V: &lt;%W&gt;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">input_length</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">input_length</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">input_length</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2" class="named-paragraph-link"><span class="named-paragraph">Try to match the input text to the nonterminal</span><span class="named-paragraph-number">50.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_1" class="named-paragraph-link"><span class="named-paragraph">The nonterminal has failed to parse</span><span class="named-paragraph-number">50.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP50_1"></a><b>&#167;50.1. </b>The routine ends here...
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">The nonterminal has failed to parse</span><span class="named-paragraph-number">50.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Failed %V (time %d)\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">time</span><span class="plain-syntax">(0)-</span><span class="identifier-syntax">start_of_nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ptraci</span><span class="plain-syntax"> = </span><span class="identifier-syntax">teppic</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50">&#167;50</a>, <a href="4-prf.html#SP50_2_1_2_1">&#167;50.2.1.2.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP_1"></a><b>&#167;.1. </b>...unless a match was made, in which case it ends here. At this point <span class="extract"><span class="extract-syntax">Q</span></span>
and <span class="extract"><span class="extract-syntax">QP</span></span> will hold the results of the match.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">The nonterminal has successfully parsed</span><span class="named-paragraph-number">.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">result</span><span class="plain-syntax">) *</span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Q</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">result_p</span><span class="plain-syntax">) *</span><span class="identifier-syntax">result_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">QP</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">most_recent_result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Q</span><span class="plain-syntax">; </span><span class="identifier-syntax">most_recent_result_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">QP</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">INSTRUMENTED_PREFORM</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_matches</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ptraci</span><span class="plain-syntax"> = </span><span class="identifier-syntax">teppic</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">success_rval</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2">&#167;50.2</a> (twice), <a href="4-prf.html#SP50_2_1">&#167;50.2.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2"></a><b>&#167;50.2. </b>Here we see that a successful voracious NT returns the word number it got
to, rather than <span class="extract"><span class="extract-syntax">TRUE</span></span>. Otherwise this is straightforward: we delegate to
an internal NT, or try all possible productions for an external one.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">RANGE_OPTIMISATION_LENGTH</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Try to match the input text to the nonterminal</span><span class="named-paragraph-number">50.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-wrd.html#SP12" class="function-link"><span class="function-syntax">Wordings::empty</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) || (</span><span class="identifier-syntax">input_length</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">RANGE_OPTIMISATION_LENGTH</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">internal_definition</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">voracious</span><span class="plain-syntax">) </span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax">) || (</span><a href="4-prf.html#SP35" class="function-link"><span class="function-syntax">Preform::nt_bitmap_violates</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">r</span><span class="plain-syntax">, </span><span class="identifier-syntax">Q</span><span class="plain-syntax">; </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">QP</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">r</span><span class="plain-syntax"> = (*(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">internal_definition</span><span class="plain-syntax">))(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">Q</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">QP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> { </span><span class="identifier-syntax">r</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="identifier-syntax">Q</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">r</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">voracious</span><span class="plain-syntax">) </span><span class="identifier-syntax">success_rval</span><span class="plain-syntax"> = </span><span class="identifier-syntax">r</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Succeeded %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">time</span><span class="plain-syntax">(0)-</span><span class="identifier-syntax">start_of_nt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP_1" class="named-paragraph-link"><span class="named-paragraph">The nonterminal has successfully parsed</span><span class="named-paragraph-number">.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%V: &lt;%W&gt; violates "</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::log_range_requirement</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax">) || (</span><a href="4-prf.html#SP35" class="function-link"><span class="function-syntax">Preform::nt_bitmap_violates</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">acc_result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">PREFORM_LANGUAGE_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">definition_language</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">language_of_source_text</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">language_of_source_text</span><span class="plain-syntax"> == </span><span class="identifier-syntax">nl</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_v</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">violates</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_req</span><span class="plain-syntax">.</span><span class="element-syntax">ditto_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">violates</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last_v</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">violates</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP35" class="function-link"><span class="function-syntax">Preform::nt_bitmap_violates</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_v</span><span class="plain-syntax"> = </span><span class="identifier-syntax">violates</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">violates</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1" class="named-paragraph-link"><span class="named-paragraph">Parse the given production</span><span class="named-paragraph-number">50.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"production in %V: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP18" class="function-link"><span class="function-syntax">Preform::log_production</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">": &lt;%W&gt; violates "</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::log_range_requirement</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">multiplicitous</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">acc_result</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">QP</span><span class="plain-syntax"> = </span><span class="identifier-syntax">acc_result</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP_1" class="named-paragraph-link"><span class="named-paragraph">The nonterminal has successfully parsed</span><span class="named-paragraph-number">.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%V: &lt;%W&gt; violates "</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP46" class="function-link"><span class="function-syntax">Preform::log_range_requirement</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50">&#167;50</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1"></a><b>&#167;50.2.1. </b>So from here on we look only at the external case, where we're parsing the
text against a production.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the given production</span><span class="named-paragraph-number">50.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_1" class="named-paragraph-link"><span class="named-paragraph">Log the production match number</span><span class="named-paragraph-number">50.2.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-prf.html#SP18" class="function-link"><span class="function-syntax">Preform::log_production</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">INSTRUMENTED_PREFORM</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_tries</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">slow_scan_needed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">added_to_result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">input_length</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_pr_words</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">input_length</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_pr_words</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q</span><span class="plain-syntax">; </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">QP</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2" class="named-paragraph-link"><span class="named-paragraph">Actually parse the given production, going to Fail if we can't</span><span class="named-paragraph-number">50.2.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">INSTRUMENTED_PREFORM</span><span class="plain-syntax"> </span><span class="comment-syntax"> record the sentence containing the longest example</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">production_matches</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">sample_text</span><span class="plain-syntax">) &lt; </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sample_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_1" class="named-paragraph-link"><span class="named-paragraph">Log the production match number</span><span class="named-paragraph-number">50.2.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"succeeded (%s): "</span><span class="plain-syntax">, (</span><span class="identifier-syntax">slow_scan_needed</span><span class="plain-syntax">)?</span><span class="string-syntax">"slowly"</span><span class="plain-syntax">:</span><span class="string-syntax">"quickly"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"result: %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">Q</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP_1" class="named-paragraph-link"><span class="named-paragraph">The nonterminal has successfully parsed</span><span class="named-paragraph-number">.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Fail:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_1" class="named-paragraph-link"><span class="named-paragraph">Log the production match number</span><span class="named-paragraph-number">50.2.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">added_to_result</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"added to result (%s): $P\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">slow_scan_needed</span><span class="plain-syntax">)?</span><span class="string-syntax">"slowly"</span><span class="plain-syntax">:</span><span class="string-syntax">"quickly"</span><span class="plain-syntax">, </span><span class="identifier-syntax">added_to_result</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"failed (%s)\n"</span><span class="plain-syntax">, (</span><span class="identifier-syntax">slow_scan_needed</span><span class="plain-syntax">)?</span><span class="string-syntax">"slowly"</span><span class="plain-syntax">:</span><span class="string-syntax">"quickly"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2">&#167;50.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_1"></a><b>&#167;50.2.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Log the production match number</span><span class="named-paragraph-number">50.2.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">match_number</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">26</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"production /%c%c/: "</span><span class="plain-syntax">, </span><span class="character-syntax">'a'</span><span class="plain-syntax">+</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">match_number</span><span class="plain-syntax">-26, </span><span class="character-syntax">'a'</span><span class="plain-syntax">+</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">match_number</span><span class="plain-syntax">-26);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"production /%c/: "</span><span class="plain-syntax">, </span><span class="character-syntax">'a'</span><span class="plain-syntax">+</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">match_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1">&#167;50.2.1</a> (three times).</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2"></a><b>&#167;50.2.1.2. </b>Okay. So, the strategy is: a fast scan checking the easy things; if that's
not sufficient, a slow scan checking the rest; then making sure brackets
match, if there were any, and last composing the intermediate results into
the final ones. For example, if the production is
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">adjust</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;achingly-slow&gt;</span><span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;exhaustive&gt;</span><span class="plain-syntax"> </span><span class="identifier-syntax">at</span><span class="plain-syntax"> </span><span class="identifier-syntax">once</span>
</pre>
<p class="commentary">then the fast scan verifies the presence of "adjust the" and "at once";
the slow scan next looks for all occurrences of "to the", the single strut
for this production; and only then does it test the two slow nonterminals
on the intervening words, if there are any.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Actually parse the given production, going to Fail if we can't</span><span class="named-paragraph-number">50.2.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">checked</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_PTOKENS_PER_PRODUCTION</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">intermediates</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_RESULTS_PER_PRODUCTION</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">intermediate_ps</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_RESULTS_PER_PRODUCTION</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">parsed_open_pos</span><span class="plain-syntax"> = -1, </span><span class="identifier-syntax">parsed_close_pos</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_2" class="named-paragraph-link"><span class="named-paragraph">Try a fast scan through the production</span><span class="named-paragraph-number">50.2.1.2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">slow_scan_needed</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_3" class="named-paragraph-link"><span class="named-paragraph">Try a slow scan through the production</span><span class="named-paragraph-number">50.2.1.2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">parsed_open_pos</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">parsed_close_pos</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-wrd.html#SP18" class="function-link"><span class="function-syntax">Wordings::paired_brackets</span></a><span class="plain-syntax">(</span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parsed_open_pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">parsed_close_pos</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Fail</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_1" class="named-paragraph-link"><span class="named-paragraph">Compose and store the result</span><span class="named-paragraph-number">50.2.1.2.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1">&#167;50.2.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2_1"></a><b>&#167;50.2.1.2.1. </b>Once we have successfully matched the line, we need to compose the
intermediate results into a final result. If <span class="extract"><span class="extract-syntax">inweb</span></span> has compiled a compositor
routine for the nonterminal, we call it: note that it can then return <span class="extract"><span class="extract-syntax">FALSE</span></span>
to fail the production after all, and can even return <span class="extract"><span class="extract-syntax">FAIL_NONTERMINAL</span></span> to
abandon not just this production, but all of the productions. (This is quite
useful as a way to put exceptional syntaxes into the grammar, since it can
make subsequent productions only available in some cases.)
</p>
<p class="commentary">If there's no compositor then the integer result is the production's number,
and the pointer result is null.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">FAIL_NONTERMINAL</span><span class="plain-syntax"> -100000</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">FAIL_NONTERMINAL_TO</span><span class="plain-syntax"> </span><span class="constant-syntax">FAIL_NONTERMINAL</span><span class="plain-syntax">+1000</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compose and store the result</span><span class="named-paragraph-number">50.2.1.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_compositor</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">intermediates</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">match_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax"> = (*(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_compositor</span><span class="plain-syntax">))(&amp;</span><span class="identifier-syntax">Q</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">QP</span><span class="plain-syntax">, </span><span class="identifier-syntax">intermediates</span><span class="plain-syntax">, </span><span class="identifier-syntax">intermediate_ps</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_result</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Fail</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">multiplicitous</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">added_to_result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">QP</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">acc_result</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">ParseTree::add_possible_reading</span><span class="plain-syntax">((</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">acc_result</span><span class="plain-syntax">, </span><span class="identifier-syntax">QP</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Fail</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">f</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">FAIL_NONTERMINAL</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">f</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">FAIL_NONTERMINAL_TO</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">fail_nonterminal_quantum</span><span class="plain-syntax"> = </span><span class="identifier-syntax">f</span><span class="plain-syntax"> - </span><span class="constant-syntax">FAIL_NONTERMINAL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_1" class="named-paragraph-link"><span class="named-paragraph">The nonterminal has failed to parse</span><span class="named-paragraph-number">50.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Q</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">match_number</span><span class="plain-syntax">; </span><span class="identifier-syntax">QP</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1_2">&#167;50.2.1.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2_2"></a><b>&#167;50.2.1.2.2. </b>In the fast scan, we check that all fixed words with known positions
are in those positions.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Try a fast scan through the production</span><span class="named-paragraph-number">50.2.1.2.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = -1, </span><span class="identifier-syntax">tc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">, </span><span class="identifier-syntax">tc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">, </span><span class="identifier-syntax">tc</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_is_fast</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)+</span><span class="identifier-syntax">p</span><span class="plain-syntax">-1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)+</span><span class="identifier-syntax">p</span><span class="plain-syntax">+1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-prf.html#SP52" class="function-link"><span class="function-syntax">Preform::parse_fixed_word_ptoken</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="identifier-syntax">pt</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">slow_scan_needed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Fail</span><span class="plain-syntax">; </span><span class="comment-syntax"> the word should have been here, and it wasn't</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ve_pt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">parsed_open_pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ve_pt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">CLOSEBRACKET_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">parsed_close_pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">checked</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">] = </span><span class="identifier-syntax">wn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">slow_scan_needed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">checked</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">] = -1;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">slow_scan_needed</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> != </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">))) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Fail</span><span class="plain-syntax">; </span><span class="comment-syntax"> input text goes on further</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1_2">&#167;50.2.1.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2_3"></a><b>&#167;50.2.1.2.3. </b>The slow scan is more challenging. We want to loop through all possible
strut positions, where by "possible" we mean that
$$ s_i+\ell_i &lt;= s_{i+1}, \quad i = 0, 1, ..., s $$
and that for each \(i\) the \(i\)-th strut matches the text beginning at \(s_i\).
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Try a slow scan through the production</span><span class="named-paragraph-number">50.2.1.2.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_STRUTS_PER_PRODUCTION</span><span class="plain-syntax">]; </span><span class="comment-syntax"> word numbers for where we are trying the struts</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">NS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_struts</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_3_1" class="named-paragraph-link"><span class="named-paragraph">Start from the lexicographically earliest strut position</span><span class="named-paragraph-number">50.2.1.2.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">backtrack_token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">backtrack_index</span><span class="plain-syntax"> = -1, </span><span class="identifier-syntax">backtrack_to</span><span class="plain-syntax"> = -1, </span><span class="identifier-syntax">backtrack_tc</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_3_3" class="named-paragraph-link"><span class="named-paragraph">Try a slow scan with the current strut positions</span><span class="named-paragraph-number">50.2.1.2.3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition:</span><span class="plain-syntax"> ;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">backtrack_token</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_3_2" class="named-paragraph-link"><span class="named-paragraph">Move on to the next strut position</span><span class="named-paragraph-number">50.2.1.2.3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1_2">&#167;50.2.1.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2_3_1"></a><b>&#167;50.2.1.2.3.1. </b>We start by finding the lexicographically earliest, i.e., we find the earliest
possible position for \(s_0\), then the earliest position from \(s_0+\ell_0\) for
\(s_1\), and so on. (Our wildcards are not greedy: we match with shortest possible
text rather than longest.)
</p>
<p class="commentary">In all of the code below, the general case with <span class="extract"><span class="extract-syntax">NS</span></span> greater than 1 is actually
valid code for all cases, but experiment shows about a 5\% speed gain from
handling the popular case of one strut separately.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Start from the lexicographically earliest strut position</span><span class="named-paragraph-number">50.2.1.2.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NS</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[0] = </span><a href="4-prf.html#SP51" class="function-link"><span class="function-syntax">Preform::next_strut_posn_after</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">struts</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_lengths</span><span class="plain-syntax">[0], </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">spos</span><span class="plain-syntax">[0] == -1) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Fail</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NS</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">s</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">s</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">NS</span><span class="plain-syntax">; </span><span class="identifier-syntax">s</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">] = </span><a href="4-prf.html#SP51" class="function-link"><span class="function-syntax">Preform::next_strut_posn_after</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">struts</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">], </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">], </span><span class="identifier-syntax">from</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">spos</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">] == -1) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Fail</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">] + </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">strut_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">] + </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1_2_3">&#167;50.2.1.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2_3_2"></a><b>&#167;50.2.1.2.3.2. </b>In the general case, we move the final strut forward if we can; if we can't,
we move the penultimate one, then move the final one to the first subsequent
position valid for it; and so on. Ultimately this results in the first strut
being unable to move forwards, at which point, we've lost.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Move on to the next strut position</span><span class="named-paragraph-number">50.2.1.2.3.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NS</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Fail</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NS</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[0] = </span><a href="4-prf.html#SP51" class="function-link"><span class="function-syntax">Preform::next_strut_posn_after</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">struts</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_lengths</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[0]+1);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">spos</span><span class="plain-syntax">[0] == -1) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Fail</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NS</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">s</span><span class="plain-syntax">=</span><span class="identifier-syntax">NS</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">s</span><span class="plain-syntax">&gt;=0; </span><span class="identifier-syntax">s</span><span class="plain-syntax">--) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP51" class="function-link"><span class="function-syntax">Preform::next_strut_posn_after</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">struts</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">], </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">], </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">]+1);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> != -1) { </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">] = </span><span class="identifier-syntax">n</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">s</span><span class="plain-syntax"> == -1) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Fail</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">] + </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">s</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (; </span><span class="identifier-syntax">s</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">NS</span><span class="plain-syntax">; </span><span class="identifier-syntax">s</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">] = </span><a href="4-prf.html#SP51" class="function-link"><span class="function-syntax">Preform::next_strut_posn_after</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">struts</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">], </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">], </span><span class="identifier-syntax">from</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">spos</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">] == -1) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Fail</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">] + </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">strut_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">s</span><span class="plain-syntax">] + </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1_2_3">&#167;50.2.1.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2_3_3"></a><b>&#167;50.2.1.2.3.3. </b>We can now forget about struts, thankfully, and check the remaining unchecked
ptokens.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Try a slow scan with the current strut positions</span><span class="named-paragraph-number">50.2.1.2.3.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">), </span><span class="identifier-syntax">tc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, *</span><span class="identifier-syntax">nextpt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">backtrack_token</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">backtrack_token</span><span class="plain-syntax">; </span><span class="identifier-syntax">nextpt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">backtrack_token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">tc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">backtrack_tc</span><span class="plain-syntax">; </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">backtrack_to</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Reenter</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">, </span><span class="identifier-syntax">nextpt</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">tc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nextpt</span><span class="plain-syntax">, </span><span class="identifier-syntax">nextpt</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">tc</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Reenter:</span><span class="plain-syntax"> ;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">known_pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">checked</span><span class="plain-syntax">[</span><span class="identifier-syntax">tc</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">known_pos</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">known_pos</span><span class="plain-syntax">) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Fail</span><span class="plain-syntax">; </span><span class="comment-syntax"> a theoretical possibility if strut lookahead overreaches</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">known_pos</span><span class="plain-syntax">+1;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_result</span><span class="plain-syntax">[</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax">] = </span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::one_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FIXED_WORD_PTC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_3_3_1" class="named-paragraph-link"><span class="named-paragraph">Match a fixed word ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.1</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SINGLE_WILDCARD_PTC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_3_3_2" class="named-paragraph-link"><span class="named-paragraph">Match a single wildcard ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.2</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MULTIPLE_WILDCARD_PTC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_3_3_3" class="named-paragraph-link"><span class="named-paragraph">Match a multiple wildcard ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.3</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">POSSIBLY_EMPTY_WILDCARD_PTC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_3_3_4" class="named-paragraph-link"><span class="named-paragraph">Match a possibly empty wildcard ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.4</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NONTERMINAL_PTC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_3_3_5" class="named-paragraph-link"><span class="named-paragraph">Match a nonterminal ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.5</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_ends</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_result</span><span class="plain-syntax">[</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_ends</span><span class="plain-syntax">] = </span><a href="3-wrd.html#SP7" class="function-link"><span class="function-syntax">Wordings::up_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_result</span><span class="plain-syntax">[</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_ends</span><span class="plain-syntax">], </span><span class="identifier-syntax">wn</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> != </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)+1) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1_2_3">&#167;50.2.1.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2_3_3_1"></a><b>&#167;50.2.1.2.3.3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match a fixed word ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP52" class="function-link"><span class="function-syntax">Preform::parse_fixed_word_ptoken</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="identifier-syntax">pt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">q</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ve_pt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">parsed_open_pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ve_pt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">CLOSEBRACKET_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">parsed_close_pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1_2_3_3">&#167;50.2.1.2.3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2_3_3_2"></a><b>&#167;50.2.1.2.3.3.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match a single wildcard ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1_2_3_3">&#167;50.2.1.2.3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2_3_3_3"></a><b>&#167;50.2.1.2.3.3.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match a multiple wildcard ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> &gt; </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_3_3_3_1" class="named-paragraph-link"><span class="named-paragraph">Calculate how much to stretch this elastic ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">wt</span><span class="plain-syntax">) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition</span><span class="plain-syntax">; </span><span class="comment-syntax"> zero length</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">balanced_wildcard</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">bl</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=</span><span class="identifier-syntax">wn</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">wt</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACKET_V</span><span class="plain-syntax">) || (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACE_V</span><span class="plain-syntax">)) </span><span class="identifier-syntax">bl</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACKET_V</span><span class="plain-syntax">) || (</span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACE_V</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wt</span><span class="plain-syntax">+1;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1_2_3_3">&#167;50.2.1.2.3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2_3_3_4"></a><b>&#167;50.2.1.2.3.3.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match a possibly empty wildcard ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_3_3_3_1" class="named-paragraph-link"><span class="named-paragraph">Calculate how much to stretch this elastic ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wt</span><span class="plain-syntax">+1;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1_2_3_3">&#167;50.2.1.2.3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2_3_3_5"></a><b>&#167;50.2.1.2.3.3.5. </b>A voracious nonterminal is offered the entire rest of the word range, and
returns how much it ate. Otherwise, we offer the maximum amount of space
available: if, for word-count reasons, that's never going to match, then
we rely on the recursive call to <span class="extract"><span class="extract-syntax">Preform::parse_nt_against_word_range</span></span> returning a
quick no.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match a nonterminal ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> &gt; </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">voracious</span><span class="plain-syntax">) </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> == </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> + </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP50_2_1_2_3_3_3_1" class="named-paragraph-link"><span class="named-paragraph">Calculate how much to stretch this elastic ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">backtrack_token</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Reached backtrack position %V: &lt;%W&gt;\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">, </span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="identifier-syntax">wt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">preform_backtrack</span><span class="plain-syntax"> = </span><span class="identifier-syntax">intermediate_ps</span><span class="plain-syntax">[</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_index</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP50" class="function-link"><span class="function-syntax">Preform::parse_nt_against_word_range</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">, </span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="identifier-syntax">wt</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> &amp;(</span><span class="identifier-syntax">intermediates</span><span class="plain-syntax">[</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_index</span><span class="plain-syntax">]), &amp;(</span><span class="identifier-syntax">intermediate_ps</span><span class="plain-syntax">[</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_index</span><span class="plain-syntax">]));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">backtrack_token</span><span class="plain-syntax">) { </span><span class="identifier-syntax">preform_backtrack</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">backtrack_token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">voracious</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">q</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">q</span><span class="plain-syntax">; </span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">q</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">q</span><span class="plain-syntax">; </span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">backtrack_index</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_index</span><span class="plain-syntax">; </span><span class="identifier-syntax">backtrack_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">backtrack_token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">backtrack_tc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">tc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Set backtrack position %V: &lt;%W&gt;\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">, </span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="identifier-syntax">wt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> { </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax">) </span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><span class="identifier-syntax">q</span><span class="plain-syntax">?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">q</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wt</span><span class="plain-syntax">+1;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1_2_3_3">&#167;50.2.1.2.3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP50_2_1_2_3_3_3_1"></a><b>&#167;50.2.1.2.3.3.3.1. </b>How much text from the input should this ptoken match? We feed it as much
as possible, and to calculate that, we must either be at the end of the run,
or else know exactly where the next ptoken starts: because its position is
known, or because it's a strut.
</p>
<p class="commentary">This is why two elastic nonterminals in a row won't parse correctly:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">frog</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;amphibian&gt;</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;pond-preference&gt;</span><span class="plain-syntax"> </span><span class="identifier-syntax">toad</span>
</pre>
<p class="commentary">Preform is unable to work out where the central boundary will occur. In theory
it should try every possibility. But that's inefficient: in practice the
solution is to write the grammar to minimise these cases, and then to set up
&lt;amphibian&gt; as a voracious token, so that it decides the boundary position
for itself. (If &lt;amphibian&gt; is not voracious, the following calculation
probably gives the wrong answer.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Calculate how much to stretch this elastic ptoken</span><span class="named-paragraph-number">50.2.1.2.3.3.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lookahead</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nextpt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lookahead</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lookahead</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)+</span><span class="identifier-syntax">p</span><span class="plain-syntax">-2;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)+</span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lookahead</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_number</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[</span><span class="identifier-syntax">lookahead</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">strut_number</span><span class="plain-syntax">]-1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lookahead</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> &amp;&amp; (</span><a href="4-prf.html#SP47" class="function-link"><span class="function-syntax">Preform::ptoken_width</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">) == </span><span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">target</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lookahead</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">save_preform_lookahead_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax">+1; </span><span class="identifier-syntax">j</span><span class="plain-syntax"> &lt;= </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">); </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-prf.html#SP50" class="function-link"><span class="function-syntax">Preform::parse_nt_against_word_range</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">target</span><span class="plain-syntax">, </span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><a href="4-prf.html#SP50" class="function-link"><span class="function-syntax">Preform::parse_nt_against_word_range</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">, </span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">-1), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">j</span><span class="plain-syntax">-1; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fail_nonterminal_quantum</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">j</span><span class="plain-syntax"> += </span><span class="identifier-syntax">fail_nonterminal_quantum</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">save_preform_lookahead_mode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wt</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP50_2_1_2_3_3_3">&#167;50.2.1.2.3.3.3</a>, <a href="4-prf.html#SP50_2_1_2_3_3_4">&#167;50.2.1.2.3.3.4</a>, <a href="4-prf.html#SP50_2_1_2_3_3_5">&#167;50.2.1.2.3.3.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP51"></a><b>&#167;51. </b>Here we find the next possible match position for the strut beginning <span class="extract"><span class="extract-syntax">start</span></span>
and of width <span class="extract"><span class="extract-syntax">len</span></span> in words, which begins at word <span class="extract"><span class="extract-syntax">from</span></span> or after. Note that
the strut might run up right to the end of the input text: for example, in
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">neckties</span><span class="plain-syntax"> ... </span><span class="identifier-syntax">tied</span><span class="plain-syntax"> ***</span>
</pre>
<p class="commentary">the word "tied" is a strut, because the <span class="extract"><span class="extract-syntax">***</span></span> makes its position uncertain,
but since <span class="extract"><span class="extract-syntax">***</span></span> might match the empty text, "tied" might legally be the
last word in the input text.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::next_strut_posn_after</span><button class="popup" onclick="togglePopup('usagePopup35')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup35">Usage of <span class="code-font"><span class="function-syntax">Preform::next_strut_posn_after</span></span>:<br/><a href="4-prf.html#SP50_2_1_2_3_1">&#167;50.2.1.2.3.1</a>, <a href="4-prf.html#SP50_2_1_2_3_2">&#167;50.2.1.2.3.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">start</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">len</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_legal_position</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) - </span><span class="identifier-syntax">len</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">from</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">last_legal_position</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">from</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">start</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-prf.html#SP52" class="function-link"><span class="function-syntax">Preform::parse_fixed_word_ptoken</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">pt</span><span class="plain-syntax">)) </span><span class="identifier-syntax">pos</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP50" class="function-link"><span class="function-syntax">Preform::parse_nt_against_word_range</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">+</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax">-1),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax">) </span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><span class="identifier-syntax">q</span><span class="plain-syntax">?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">q</span><span class="plain-syntax">) </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> += </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pos</span><span class="plain-syntax">-</span><span class="identifier-syntax">from</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">len</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP52"></a><b>&#167;52. </b>Finally, a single fixed word, with its annotations and alternatives.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::parse_fixed_word_ptoken</span><button class="popup" onclick="togglePopup('usagePopup36')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup36">Usage of <span class="code-font"><span class="function-syntax">Preform::parse_fixed_word_ptoken</span></span>:<br/><a href="4-prf.html#SP50_2_1_2_2">&#167;50.2.1.2.2</a>, <a href="4-prf.html#SP50_2_1_2_3_3_1">&#167;50.2.1.2.3.3.1</a>, <a href="4-prf.html#SP51">&#167;51</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> = </span><a href="3-lxr.html#SP18" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">disallow_unexpected_upper</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> == </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ve_pt</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">m</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) || (</span><a href="4-nw.html#SP5" class="function-link"><span class="function-syntax">Word::unexpectedly_upper_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax">)?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax">)?</span><span class="identifier-syntax">TRUE:FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP53"></a><b>&#167;53. Reading Preform syntax from a file. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::load_from_file</span><span class="plain-syntax">(</span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">feed_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> = </span><a href="3-fds.html#SP3" class="function-link"><span class="function-syntax">Feeds::begin</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><a href="4-prf.html#SP54" class="function-link"><span class="function-syntax">Preform::preform_helper</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Unable to open Preform definition"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-fds.html#SP3" class="function-link"><span class="function-syntax">Feeds::end</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP54"></a><b>&#167;54. </b>We simply feed the lines one at a time:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preform::preform_helper</span><button class="popup" onclick="togglePopup('usagePopup37')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup37">Usage of <span class="code-font"><span class="function-syntax">Preform::preform_helper</span></span>:<br/><a href="4-prf.html#SP53">&#167;53</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">item_name</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vnl</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">item_name</span><span class="plain-syntax">, </span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-fds.html#SP4" class="function-link"><span class="function-syntax">Feeds::feed_stream_punctuated</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">item_name</span><span class="plain-syntax">, </span><span class="constant-syntax">PREFORM_PUNCTUATION_MARKS</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-nw.html">&#10094;</a></li><li class="progresschapter"><a href="1-wm.html">1</a></li><li class="progresschapter"><a href="2-vcb.html">2</a></li><li class="progresschapter"><a href="3-lxr.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-nw.html">nw</a></li><li class="progresscurrent">prf</li><li class="progresssection"><a href="4-bn.html">bn</a></li><li class="progressnext"><a href="4-bn.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>