mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
791 lines
151 KiB
HTML
791 lines
151 KiB
HTML
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>Nonterminal Incidences</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>
|
||
|
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">
|
||
|
<link href="../docs-assets/Preform-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 'Nonterminal Incidences' 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>Nonterminal Incidences</b></li></ul></div>
|
||
|
<p class="purpose">To work out bitmaps of nonterminal incidences in grammar.</p>
|
||
|
|
||
|
<ul class="toc"><li><a href="4-ni.html#SP1">§1. Introduction</a></li><li><a href="4-ni.html#SP2">§2. Incidence bits</a></li><li><a href="4-ni.html#SP3">§3. The NTI of a word</a></li><li><a href="4-ni.html#SP6">§6. Range requirements</a></li><li><a href="4-ni.html#SP9">§9. Basic range requirements</a></li><li><a href="4-ni.html#SP11">§11. Concatenation of range requirements</a></li><li><a href="4-ni.html#SP17">§17. Disjunction of range requirements</a></li><li><a href="4-ni.html#SP22">§22. Range requirement simplification</a></li><li><a href="4-ni.html#SP25">§25. Calculations</a></li><li><a href="4-ni.html#SP26">§26. Customisation</a></li></ul><hr class="tocbar">
|
||
|
|
||
|
<p class="commentary firstcommentary"><a id="SP1"></a><b>§1. Introduction. </b>The "nonterminal incidences" system provides one of two optimisations enabling
|
||
|
the Preform parser quickly to reject non-matches, the other being
|
||
|
<a href="4-le.html" class="internal">Length Extremes</a>, which is easier to understand.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary">It may elucidate both to see the actual optimisation data for nonterminals
|
||
|
as used in a typical run of Inform 7 — see <a href="../inform7/M-pm.html" class="internal">Performance Metrics (in inform7)</a>.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary firstcommentary"><a id="SP2"></a><b>§2. Incidence bits. </b>Each NT is assigned an "incidence bit", but this is generated on demand;
|
||
|
<span class="extract"><span class="extract-syntax">nt_incidence_bit</span></span> is -1 until it is allocated, and is otherwise an integer in
|
||
|
which only one bit is set, and always in the lowest 32 bits (since we won't
|
||
|
assume integers are any larger than that).
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary">The lowest 6 bits are reserved — see <a href="4-ni.html#SP27" class="internal">NTI::give_nt_reserved_incidence_bit</a>
|
||
|
below — but bits 7 to 32 are free, and the following function cycles through
|
||
|
those 26 possibilities. Those 26 don't have any semantic significance; they
|
||
|
simply divide up the nonterminals into 26 different bins of roughly equal
|
||
|
sizes, in the same sort of way that keys are divided up in hash tables.
|
||
|
</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="identifier-syntax">no_req_bits</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
||
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">NTI::nt_incidence_bit</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">NTI::nt_incidence_bit</span></span>:<br/><a href="4-ni.html#SP3">§3</a>, <a href="4-ni.html#SP10">§10</a>, <a href="4-ni.html#SP28">§28</a><br/>Instrumentation - <a href="4-ins.html#SP8">§8</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">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_incidence_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">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_incidence_bit</span><span class="plain-syntax"> = (1 << </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">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_incidence_bit</span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax">}</span>
|
||
|
</pre>
|
||
|
<p class="commentary firstcommentary"><a id="SP3"></a><b>§3. The NTI of a word. </b>The vocabulary system provides an integer called the "nonterminal incidence",
|
||
|
or NTI, attached to each different word in our vocabulary. We can read this
|
||
|
with <a href="2-vcb.html#SP12" class="internal">Vocabulary::get_nti</a> and write it with <a href="2-vcb.html#SP12" class="internal">Vocabulary::set_nti</a>; if
|
||
|
we don't, it remains 0.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary">The NTI for a word will be a bitmap of the incidence bits for each NT whose
|
||
|
grammar includes that word.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary">So, for example, if the word "plus" appears in the grammar defining
|
||
|
<edwardian-trousers> and <arithmetic-operation>, but no others, then
|
||
|
its NTI would be the incidence bit for <edwardian-trousers> together
|
||
|
with that for <arithmetic-operation>.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary">To build that, we'll use the following:
|
||
|
</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">NTI::mark_vocabulary</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">NTI::mark_vocabulary</span></span>:<br/><a href="4-ni.html#SP4">§4</a>, <a href="4-ni.html#SP25_1">§25.1</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#SP12" class="function-link"><span class="function-syntax">Vocabulary::get_nti</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-ni.html#SP2" class="function-link"><span class="function-syntax">NTI::nt_incidence_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#SP12" class="function-link"><span class="function-syntax">Vocabulary::set_nti</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">NTI::test_vocabulary</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">NTI::test_vocabulary</span></span>:<br/><a href="4-ni.html#SP4">§4</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#SP12" class="function-link"><span class="function-syntax">Vocabulary::get_nti</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"> & (</span><a href="4-ni.html#SP2" class="function-link"><span class="function-syntax">NTI::nt_incidence_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="SP4"></a><b>§4. </b>Versions for words identified by their position in the lexer stream:
|
||
|
</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">NTI::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-ni.html#SP3" class="function-link"><span class="function-syntax">NTI::mark_vocabulary</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP20" 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">int</span><span class="plain-syntax"> </span><span class="function-syntax">NTI::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">return</span><span class="plain-syntax"> </span><a href="4-ni.html#SP3" class="function-link"><span class="function-syntax">NTI::test_vocabulary</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP20" 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>
|
||
|
</pre>
|
||
|
<p class="commentary firstcommentary"><a id="SP5"></a><b>§5. </b>It turns out to be fast to take a wording and to logical-or ("disjoin")
|
||
|
or logical-and ("conjoin") their NTI bitmaps together:
|
||
|
</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">NTI::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#SP12" class="function-link"><span class="function-syntax">Vocabulary::get_nti</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP20" 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">NTI::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#SP12" class="function-link"><span class="function-syntax">Vocabulary::get_nti</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP20" 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"> &= </span><a href="2-vcb.html#SP12" class="function-link"><span class="function-syntax">Vocabulary::get_nti</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP20" 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="SP6"></a><b>§6. Range requirements. </b>The NTI bitmaps for words are not easy to put together, but provided this
|
||
|
can be done correctly then we can benefit from systematic criteria to reject
|
||
|
doomed matches quickly when parsing. For example, suppose we have grammar:
|
||
|
</p>
|
||
|
|
||
|
<pre class="Preform-displayed-code all-displayed-code code-font">
|
||
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><recipe></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
|
||
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">pan-fried</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><fish></span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span>
|
||
|
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><fish></span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">veronique</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span>
|
||
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">battered</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><fish></span>
|
||
|
</pre>
|
||
|
<p class="commentary">and we are trying to match the text "galvanised zinc". The Optimiser has
|
||
|
already determined that the word "galvanised" is not used anywhere in the
|
||
|
grammar for <fish>, and similarly the word "zinc" — so neither word has
|
||
|
the incidence bit for <fish> in its NTI. But the Optimiser can also see that
|
||
|
each of the three productions involves <fish> somewhere — not always in
|
||
|
the same position, but somewhere. It therefore knows that for a wording to
|
||
|
match, one of the words must have the <fish> incidence bit. And since
|
||
|
neither "galvanised" nor "zinc" have it, the wording "galvanised zinc"
|
||
|
cannot be a match.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary firstcommentary"><a id="SP7"></a><b>§7. </b>That example was contrived, but when this idea is taken further in a
|
||
|
more systematic way it produces very large speed gains, because it allows
|
||
|
a few fast bitwise operations to avoid the need for slow parsing processes
|
||
|
to reach an inevitably doomed conclusion.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary">The above idea can be applied equally well to matching text against a
|
||
|
nonterminal, production or ptoken, so all three have a <a href="4-ni.html#SP7" class="internal">nti_constraint</a>
|
||
|
object. A NTIC encodes six rules, applying to a word range in three ways:
|
||
|
</p>
|
||
|
|
||
|
<ul class="items"><li>(a) D for "disjunction", or logical or. One of the words must satisfy this.
|
||
|
</li><li>(b) C for "conjunction", or logical and. All of the words must satisfy this.
|
||
|
</li><li>(c) F for "first". The first word must satisfy this.
|
||
|
</li></ul>
|
||
|
<p class="commentary">And a rule can apply to the NTI bits in two ways:
|
||
|
</p>
|
||
|
|
||
|
<ul class="items"><li>(i) W for "weak". A word passes if it has one of these NTI bits.
|
||
|
</li><li>(ii) S for "strong". A word passes if it has all of these NTI bits.
|
||
|
</li></ul>
|
||
|
<p class="commentary">That makes six combinations in all: DW, DS, CW, CS, FW, and FS.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary">For example, suppose a NTIC has <span class="extract"><span class="Preform-extract-syntax">DS_req</span></span> set to <span class="extract"><span class="Preform-extract-syntax">0x280</span></span> — i.e., to a bitmap
|
||
|
in which bits 7 and 9 are set (counting upwards from 0). This is then saying
|
||
|
that a word range such as "sense and prejudice" can only be a match if one
|
||
|
of the three words "sense", "and" or "prejudice" has both bits 7 and 9 set.
|
||
|
</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">nti_constraint</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">there_are_no_requirements</span><span class="plain-syntax">; </span><span class="comment-syntax"> if set, ignore all six bitmaps</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="comment-syntax"> one of the words has one of these bits</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="comment-syntax"> one of the words has all of these bits</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="comment-syntax"> all of the words have one of these bits</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="comment-syntax"> all of the words have all of these bits</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="comment-syntax"> the first word has one of these bits</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="comment-syntax"> the first word has all of these bits</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="comment-syntax"> this production has the same constraint as the previous one</span>
|
||
|
<span class="plain-syntax">} </span><span class="reserved-syntax">nti_constraint</span><span class="plain-syntax">;</span>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>The structure nti_constraint is accessed in 4/prf, 4/ins and here.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP8"></a><b>§8. </b>And the following applies the NTIC test. Speed is critical here: we perform
|
||
|
only those tests which can have any effect, where the bitmap is non-zero. Note
|
||
|
that a return value of <span class="extract"><span class="extract-syntax">TRUE</span></span> means that the wording does not match.
|
||
|
</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">NTI::nt_bitmap_violates</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">NTI::nt_bitmap_violates</span></span>:<br/>Preform - <a href="4-prf.html#SP1_2">§1.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">nti_constraint</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ntic</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">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">there_are_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="named-paragraph-container code-font"><a href="4-ni.html#SP8_1" class="named-paragraph-link"><span class="named-paragraph">Perform C, D and F tests on a single word</span><span class="named-paragraph-number">8.1</span></a></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">C_set</span><span class="plain-syntax"> = ((</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax">) | (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">) | (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">) | (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) && (</span><span class="identifier-syntax">D_set</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="4-ni.html#SP8_2" class="named-paragraph-link"><span class="named-paragraph">Perform C, D and F tests</span><span class="named-paragraph-number">8.2</span></a></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="named-paragraph-container code-font"><a href="4-ni.html#SP8_3" class="named-paragraph-link"><span class="named-paragraph">Perform C and F tests</span><span class="named-paragraph-number">8.3</span></a></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="named-paragraph-container code-font"><a href="4-ni.html#SP8_4" class="named-paragraph-link"><span class="named-paragraph">Perform D and F tests</span><span class="named-paragraph-number">8.4</span></a></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="named-paragraph-container code-font"><a href="4-ni.html#SP8_5" class="named-paragraph-link"><span class="named-paragraph">Perform F test</span><span class="named-paragraph-number">8.5</span></a></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="SP8_1"></a><b>§8.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Perform C, D and F tests on a single word</span><span class="named-paragraph-number">8.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">bm</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP12" class="function-link"><span class="function-syntax">Vocabulary::get_nti</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP20" 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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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="identifier-syntax">ntic</span><span class="plain-syntax">-></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>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP8">§8</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP8_2"></a><b>§8.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Perform C, D and F tests</span><span class="named-paragraph-number">8.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">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#SP12" class="function-link"><span class="function-syntax">Vocabulary::get_nti</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP20" 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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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="identifier-syntax">ntic</span><span class="plain-syntax">-></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">)) && (</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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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="identifier-syntax">ntic</span><span class="plain-syntax">-></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>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP8">§8</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP8_3"></a><b>§8.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Perform C and F tests</span><span class="named-paragraph-number">8.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="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#SP12" class="function-link"><span class="function-syntax">Vocabulary::get_nti</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP20" 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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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="identifier-syntax">ntic</span><span class="plain-syntax">-></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">)) && (</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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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="identifier-syntax">ntic</span><span class="plain-syntax">-></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>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP8">§8</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP8_4"></a><b>§8.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Perform D and F tests</span><span class="named-paragraph-number">8.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">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#SP12" class="function-link"><span class="function-syntax">Vocabulary::get_nti</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP20" 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">)) && (</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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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="identifier-syntax">ntic</span><span class="plain-syntax">-></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>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP8">§8</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP8_5"></a><b>§8.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Perform F test</span><span class="named-paragraph-number">8.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bm</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP12" class="function-link"><span class="function-syntax">Vocabulary::get_nti</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP20" 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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">) & (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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="identifier-syntax">ntic</span><span class="plain-syntax">-></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>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP8">§8</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP9"></a><b>§9. Basic range requirements. </b>Determining the NTIC for a given nonterminal, production or ptoken involves
|
||
|
some work, and we build them iteratively, starting from something simple.
|
||
|
This NTIC means "no restriction":
|
||
|
</p>
|
||
|
|
||
|
<pre class="displayed-code all-displayed-code code-font">
|
||
|
<span class="reserved-syntax">nti_constraint</span><span class="plain-syntax"> </span><span class="function-syntax">NTI::unconstrained</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">NTI::unconstrained</span></span>:<br/><a href="4-ni.html#SP25_2_1">§25.2.1</a><br/>The Optimiser - <a href="4-to.html#SP2">§2</a>, <a href="4-to.html#SP4">§4</a>, <a href="4-to.html#SP7">§7</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">nti_constraint</span><span class="plain-syntax"> </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">.</span><span class="element-syntax">there_are_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">ntic</span><span class="plain-syntax">.</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="identifier-syntax">ntic</span><span class="plain-syntax">.</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">ntic</span><span class="plain-syntax">.</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">ntic</span><span class="plain-syntax">.</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">ntic</span><span class="plain-syntax">.</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">ntic</span><span class="plain-syntax">.</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">ntic</span><span class="plain-syntax">.</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax">}</span>
|
||
|
</pre>
|
||
|
<p class="commentary firstcommentary"><a id="SP10"></a><b>§10. </b>And this "atomic" NTIC expresses the idea that every word must be flagged
|
||
|
with the incidence bit for a specific NT:
|
||
|
</p>
|
||
|
|
||
|
<pre class="displayed-code all-displayed-code code-font">
|
||
|
<span class="reserved-syntax">nti_constraint</span><span class="plain-syntax"> </span><span class="function-syntax">NTI::each_word_must_have</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">NTI::each_word_must_have</span></span>:<br/><a href="4-ni.html#SP25_2_1_1">§25.2.1.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="plain-syntax"> </span><span class="reserved-syntax">nti_constraint</span><span class="plain-syntax"> </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">.</span><span class="element-syntax">there_are_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">ntic</span><span class="plain-syntax">.</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP2" class="function-link"><span class="function-syntax">NTI::nt_incidence_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">ntic</span><span class="plain-syntax">.</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">ntic</span><span class="plain-syntax">.</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">ntic</span><span class="plain-syntax">.</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">ntic</span><span class="plain-syntax">.</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">ntic</span><span class="plain-syntax">.</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">ntic</span><span class="plain-syntax">.</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax">}</span>
|
||
|
</pre>
|
||
|
<p class="commentary firstcommentary"><a id="SP11"></a><b>§11. Concatenation of range requirements. </b>Suppose we are going to match some words X, then some more words Y.
|
||
|
The X words have to satisfy <span class="extract"><span class="extract-syntax">X_ntic</span></span> and the Y words <span class="extract"><span class="extract-syntax">Y_ntic</span></span>. The following
|
||
|
function alters <span class="extract"><span class="extract-syntax">X_ntic</span></span> so that it is now a requirement for "match X and
|
||
|
then Y", or XY for short.
|
||
|
</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">NTI::concatenate_rreq</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">NTI::concatenate_rreq</span></span>:<br/><a href="4-ni.html#SP25_2_1">§25.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nti_constraint</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">, </span><span class="reserved-syntax">nti_constraint</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">) {</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP12" class="function-link"><span class="function-syntax">NTI::concatenate_ds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP14" class="function-link"><span class="function-syntax">NTI::concatenate_dw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP13" class="function-link"><span class="function-syntax">NTI::concatenate_cs</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP15" class="function-link"><span class="function-syntax">NTI::concatenate_cw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP16" class="function-link"><span class="function-syntax">NTI::concatenate_fs</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP16" class="function-link"><span class="function-syntax">NTI::concatenate_fw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-></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="SP12"></a><b>§12. </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">NTI::concatenate_ds</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">NTI::concatenate_ds</span></span>:<br/><a href="4-ni.html#SP11">§11</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="SP13"></a><b>§13. </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">NTI::concatenate_cs</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">NTI::concatenate_cs</span></span>:<br/><a href="4-ni.html#SP11">§11</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="SP14"></a><b>§14. </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">NTI::concatenate_dw</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">NTI::concatenate_dw</span></span>:<br/><a href="4-ni.html#SP11">§11</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="SP15"></a><b>§15. </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">NTI::concatenate_cw</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">NTI::concatenate_cw</span></span>:<br/><a href="4-ni.html#SP11">§11</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="SP16"></a><b>§16. </b>The first word of XY is the first word of X, so these are much easier:
|
||
|
</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">NTI::concatenate_fs</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">NTI::concatenate_fs</span></span>:<br/><a href="4-ni.html#SP11">§11</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">NTI::concatenate_fw</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">NTI::concatenate_fw</span></span>:<br/><a href="4-ni.html#SP11">§11</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="SP17"></a><b>§17. Disjunction of range requirements. </b>The second operation is disjunction. Again we have words X with requirement
|
||
|
<span class="extract"><span class="extract-syntax">X_ntic</span></span> and Y with <span class="extract"><span class="extract-syntax">Y_ntic</span></span>, but this time we want to change <span class="extract"><span class="extract-syntax">X_ntic</span></span> so that
|
||
|
it is the requirement for "match either X or Y", or X/Y for short.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary">This 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">NTI::disjoin_rreq</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">NTI::disjoin_rreq</span></span>:<br/><a href="4-ni.html#SP25_2">§25.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nti_constraint</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">, </span><span class="reserved-syntax">nti_constraint</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">) {</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP18" class="function-link"><span class="function-syntax">NTI::disjoin_ds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP20" class="function-link"><span class="function-syntax">NTI::disjoin_dw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP19" class="function-link"><span class="function-syntax">NTI::disjoin_cs</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP21" class="function-link"><span class="function-syntax">NTI::disjoin_cw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP21" class="function-link"><span class="function-syntax">NTI::disjoin_fs</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP21" class="function-link"><span class="function-syntax">NTI::disjoin_fw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-></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="SP18"></a><b>§18. </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">NTI::disjoin_ds</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">NTI::disjoin_ds</span></span>:<br/><a href="4-ni.html#SP17">§17</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="SP19"></a><b>§19. </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">NTI::disjoin_cs</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">NTI::disjoin_cs</span></span>:<br/><a href="4-ni.html#SP17">§17</a>, <a href="4-ni.html#SP21">§21</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="SP20"></a><b>§20. </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">NTI::disjoin_dw</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">NTI::disjoin_dw</span></span>:<br/><a href="4-ni.html#SP17">§17</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="SP21"></a><b>§21. </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">NTI::disjoin_cw</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">NTI::disjoin_cw</span></span>:<br/><a href="4-ni.html#SP17">§17</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">NTI::disjoin_fw</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">NTI::disjoin_fw</span></span>:<br/><a href="4-ni.html#SP17">§17</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-ni.html#SP21" class="function-link"><span class="function-syntax">NTI::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">NTI::disjoin_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">NTI::disjoin_fs</span></span>:<br/><a href="4-ni.html#SP17">§17</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-ni.html#SP19" class="function-link"><span class="function-syntax">NTI::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>
|
||
|
</pre>
|
||
|
<p class="commentary firstcommentary"><a id="SP22"></a><b>§22. Range requirement simplification. </b>Once the bitmaps in all the necessary requirements have been made, the following
|
||
|
is used to simplify them — paring down any logical redundancy in them, so
|
||
|
that the simplest possible tests will be applied by <a href="4-ni.html#SP8" class="internal">NTI::nt_bitmap_violates</a>.
|
||
|
</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">NTI::simplify_requirement</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">NTI::simplify_requirement</span></span>:<br/><a href="4-ni.html#SP23">§23</a>, <a href="4-ni.html#SP24">§24</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nti_constraint</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">) {</span>
|
||
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-ni.html#SP22_1" class="named-paragraph-link"><span class="named-paragraph">Remove a disjunction test contained in a first-word test</span><span class="named-paragraph-number">22.1</span></a></span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-ni.html#SP22_2" class="named-paragraph-link"><span class="named-paragraph">Remove a first-word test contained in a conjunction test</span><span class="named-paragraph-number">22.2</span></a></span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-ni.html#SP22_3" class="named-paragraph-link"><span class="named-paragraph">Remove a disjunction test contained in a conjunction test</span><span class="named-paragraph-number">22.3</span></a></span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-ni.html#SP22_4" class="named-paragraph-link"><span class="named-paragraph">Remove any weak test which partially duplicates a strong one</span><span class="named-paragraph-number">22.4</span></a></span><span class="plain-syntax">;</span>
|
||
|
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="identifier-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="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="identifier-syntax">there_are_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">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="identifier-syntax">DW_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax">) ||</span>
|
||
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="identifier-syntax">FS_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax">))</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">there_are_no_requirements</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_1"></a><b>§22.1. </b>Suppose the NTIC says "one of these words has to have bit X", a disjunction
|
||
|
test, but also "the first word has to have bit X", a first word text. Then we
|
||
|
can get rid of the disjunction test — it is implied by the first word text,
|
||
|
and is both slower and weaker.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Remove a disjunction test contained in a first-word test</span><span class="named-paragraph-number">22.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">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax"> & </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax"> & </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP22">§22</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP22_2"></a><b>§22.2. </b>Suppose the NTIC says "every word has to have X" but also "the first word
|
||
|
has to have X". Then we get rid of the first word test, which is implied
|
||
|
and is weaker.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Remove a first-word test contained in a conjunction test</span><span class="named-paragraph-number">22.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">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax"> & </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax"> & </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP22">§22</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP22_3"></a><b>§22.3. </b>Now suppose we have both "one of these words has to have X" and also
|
||
|
"all of these words have to have X". We get rid of the "some of" test.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Remove a disjunction test contained in a conjunction test</span><span class="named-paragraph-number">22.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">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax"> & </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax"> & </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP22">§22</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP22_4"></a><b>§22.4. </b>Finally suppose we have "a word must have some bits from set A" and
|
||
|
also "a word must have all of the bits from set B", where B is a superset
|
||
|
of A. Then the first, weak, test can go, since it is implied by the strong one.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Remove any weak test which partially duplicates a strong one</span><span class="named-paragraph-number">22.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">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax"> & </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax"> & </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax"> & </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP22">§22</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP23"></a><b>§23. </b>The "ditto flag" on a requirement is used when there are two requirements,
|
||
|
here <span class="extract"><span class="extract-syntax">prev</span></span> then <span class="extract"><span class="extract-syntax">ntic</span></span>, representing alternatives for parsing the same text —
|
||
|
i.e., it must match either <span class="extract"><span class="extract-syntax">prev</span></span> or <span class="extract"><span class="extract-syntax">ntic</span></span>. If these two requirements are
|
||
|
the same, we needn't check the second one after the first has been checked.
|
||
|
So we give <span class="extract"><span class="extract-syntax">ntic</span></span> the ditto flag, to say "same as the one before".
|
||
|
</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">NTI::simplify_pair</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">NTI::simplify_pair</span></span>:<br/><a href="4-ni.html#SP24">§24</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nti_constraint</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">, </span><span class="reserved-syntax">nti_constraint</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prev</span><span class="plain-syntax">) {</span>
|
||
|
<span class="plain-syntax"> </span><a href="4-ni.html#SP22" class="function-link"><span class="function-syntax">NTI::simplify_requirement</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ntic</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">) &&</span>
|
||
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-></span><span class="element-syntax">DS_req</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-></span><span class="element-syntax">DW_req</span><span class="plain-syntax">) &&</span>
|
||
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-></span><span class="element-syntax">CS_req</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-></span><span class="element-syntax">CW_req</span><span class="plain-syntax">) &&</span>
|
||
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-></span><span class="element-syntax">FS_req</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-></span><span class="element-syntax">FW_req</span><span class="plain-syntax">))</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-></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="SP24"></a><b>§24. </b>Whence:
|
||
|
</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">NTI::simplify_nt</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">NTI::simplify_nt</span></span>:<br/>The Optimiser - <a href="4-to.html#SP7">§7</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">for</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="identifier-syntax">nt</span><span class="plain-syntax">-></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">-></span><span class="element-syntax">next_production_list</span><span class="plain-syntax">) {</span>
|
||
|
<span class="plain-syntax"> </span><span class="reserved-syntax">nti_constraint</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="reserved-syntax">production</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">-></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">-></span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
|
||
|
<span class="plain-syntax"> </span><a href="4-ni.html#SP23" class="function-link"><span class="function-syntax">NTI::simplify_pair</span></a><span class="plain-syntax">(&(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">pr_ntic</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"> = &(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">pr_ntic</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> }</span>
|
||
|
<span class="plain-syntax"> }</span>
|
||
|
<span class="plain-syntax"> </span><a href="4-ni.html#SP22" class="function-link"><span class="function-syntax">NTI::simplify_requirement</span></a><span class="plain-syntax">(&(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_ntic</span><span class="plain-syntax">));</span>
|
||
|
<span class="plain-syntax">}</span>
|
||
|
</pre>
|
||
|
<p class="commentary firstcommentary"><a id="SP25"></a><b>§25. Calculations. </b>We now have all the apparatus we need, so:
|
||
|
</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">NTI::calculate_constraint</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">NTI::calculate_constraint</span></span>:<br/>The Optimiser - <a href="4-to.html#SP8">§8</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="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="named-paragraph-container code-font"><a href="4-ni.html#SP25_1" class="named-paragraph-link"><span class="named-paragraph">Mark up fixed wording in the grammar for NT with the NT's incidence bit</span><span class="named-paragraph-number">25.1</span></a></span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-ni.html#SP25_2" class="named-paragraph-link"><span class="named-paragraph">Calculate requirement for NT</span><span class="named-paragraph-number">25.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">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>
|
||
|
</pre>
|
||
|
<p class="commentary firstcommentary"><a id="SP25_1"></a><b>§25.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Mark up fixed wording in the grammar for NT with the NT's incidence bit</span><span class="named-paragraph-number">25.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="reserved-syntax">production_list</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">-></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">-></span><span class="element-syntax">next_production_list</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">production</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">-></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">-></span><span class="element-syntax">next_production</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">ptoken</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">-></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">-></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">-></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">pt</span><span class="plain-syntax">-></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">for</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="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">-></span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax">)</span>
|
||
|
<span class="plain-syntax"> </span><a href="4-ni.html#SP3" class="function-link"><span class="function-syntax">NTI::mark_vocabulary</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">-></span><span class="element-syntax">ve_pt</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP25">§25</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP25_2"></a><b>§25.2. </b>The requirement for a NT is a disjunction of the requirements for the productions.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Calculate requirement for NT</span><span class="named-paragraph-number">25.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">nti_constraint</span><span class="plain-syntax"> </span><span class="identifier-syntax">nnt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">nt_ntic</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">first_production</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">production_list</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">-></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">-></span><span class="element-syntax">next_production_list</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">production</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">-></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">-></span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
|
||
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-ni.html#SP25_2_1" class="named-paragraph-link"><span class="named-paragraph">Calculate requirement for production</span><span class="named-paragraph-number">25.2.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">first_production</span><span class="plain-syntax">) </span><span class="identifier-syntax">nnt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">pr_ntic</span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="4-ni.html#SP17" class="function-link"><span class="function-syntax">NTI::disjoin_rreq</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">nnt</span><span class="plain-syntax">, &(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">pr_ntic</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="plain-syntax"> }</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_ntic</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nnt</span><span class="plain-syntax">;</span>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP25">§25</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP25_2_1"></a><b>§25.2.1. </b>The requirement for a production is a concatenation of the requirements for the
|
||
|
ptokens.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Calculate requirement for production</span><span class="named-paragraph-number">25.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">nti_constraint</span><span class="plain-syntax"> </span><span class="identifier-syntax">prt</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP9" class="function-link"><span class="function-syntax">NTI::unconstrained</span></a><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">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">for</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">pr</span><span class="plain-syntax">-></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">-></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">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">nti_constraint</span><span class="plain-syntax"> </span><span class="identifier-syntax">tok_ntic</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP9" class="function-link"><span class="function-syntax">NTI::unconstrained</span></a><span class="plain-syntax">();</span>
|
||
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-ni.html#SP25_2_1_1" class="named-paragraph-link"><span class="named-paragraph">Calculate requirement for ptoken</span><span class="named-paragraph-number">25.2.1.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">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="identifier-syntax">prt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">tok_ntic</span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="4-ni.html#SP11" class="function-link"><span class="function-syntax">NTI::concatenate_rreq</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">prt</span><span class="plain-syntax">, &</span><span class="identifier-syntax">tok_ntic</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="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">pr_ntic</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prt</span><span class="plain-syntax">;</span>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP25_2">§25.2</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP25_2_1_1"></a><b>§25.2.1.1. </b>We're down to atoms, now, and:
|
||
|
</p>
|
||
|
|
||
|
<ul class="items"><li>(a) We must ignore an empty ptoken, that is, one which matches text of width
|
||
|
0, as some positional internal NTs like <if-start-of-paragraph> do. Such a
|
||
|
ptoken can't constrain the wording of a match at all.
|
||
|
</li><li>(b) For a ptoken which is a non-negated word, the NTIC is that the word
|
||
|
matching it has to have the current NT's bit. In other words, if <span class="extract"><span class="extract-syntax">zephyr</span></span>
|
||
|
occurs in the grammar for the NT <wind>, then the atomic NTIC for this word
|
||
|
where it comes up is just a requirement that the word it matches against must
|
||
|
have the <wind> bit. (Which the word "zephyr" certainly does, because we
|
||
|
marked all the words in the <wind> grammar with the <wind> bit already.)
|
||
|
</li><li>(c) For a ptoken which is a non-negated use of another NT, the constraint
|
||
|
is just the constraint of that NT.
|
||
|
</li><li>(d) Nothing can be deduced from a negated ptoken: for example, all we know
|
||
|
about the ptoken <span class="extract"><span class="extract-syntax">^mistral</span></span> is that it matches something which is not the
|
||
|
word "mistral", and that tells us nothing about the bits that it has.
|
||
|
</li></ul>
|
||
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Calculate requirement for ptoken</span><span class="named-paragraph-number">25.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">pt</span><span class="plain-syntax">-></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="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_extremes</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</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="element-syntax">nt_pt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_extremes</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_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">-></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">pt</span><span class="plain-syntax">-></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">tok_ntic</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP10" class="function-link"><span class="function-syntax">NTI::each_word_must_have</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><span class="identifier-syntax">pt</span><span class="plain-syntax">-></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="identifier-syntax">pt</span><span class="plain-syntax">-></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><a href="4-to.html#SP8" class="function-link"><span class="function-syntax">Optimiser::optimise_nonterminal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">nt_pt</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tok_ntic</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_ntic</span><span class="plain-syntax">;</span>
|
||
|
<span class="plain-syntax"> }</span>
|
||
|
</pre>
|
||
|
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP25_2_1">§25.2.1</a>.</li></ul>
|
||
|
<p class="commentary firstcommentary"><a id="SP26"></a><b>§26. Customisation. </b>The above algorithm calculates sensible constraints for regular nonterminals,
|
||
|
but since it can't look inside the workings of internal nonterminals, those
|
||
|
currently have no constraints. Because of that, <a href="index.html" class="internal">words</a> provides for up to
|
||
|
two callback functions which have the opportunity to tweak the process:
|
||
|
</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">NTI::ask_parent_to_tweak</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">NTI::ask_parent_to_tweak</span></span>:<br/>The Optimiser - <a href="4-to.html#SP7">§7</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">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">FURTHER_PREFORM_OPTIMISER_WORDS_CALLBACK</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">FURTHER_PREFORM_OPTIMISER_WORDS_CALLBACK</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_WORDS_CALLBACK</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PREFORM_OPTIMISER_WORDS_CALLBACK</span><span class="plain-syntax">();</span>
|
||
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
|
||
|
<span class="plain-syntax">}</span>
|
||
|
</pre>
|
||
|
<p class="commentary firstcommentary"><a id="SP27"></a><b>§27. </b>Those callbacks should consist of calls to the following functions.
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary">As we've seen, each NT is assigned an NTI bit, and in general they are handed
|
||
|
out more or less at random, dividing the stock of NTs into about 26 roughly
|
||
|
equal subsets. But it turns out to be efficient to fix the NTI bits for some
|
||
|
internal NTs so that they are in common: for example, in Inform, making sure
|
||
|
<definite-article> and <indefinite-article> have the same NTI bit as each
|
||
|
other means that a single bit means "an article".
|
||
|
</p>
|
||
|
|
||
|
<p class="commentary">This is what the six reserved bits are for: the parent can use these in any
|
||
|
way it pleases, of course, but the names are meant to be suggestive of some
|
||
|
basic linguistic categories.
|
||
|
</p>
|
||
|
|
||
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">CARDINAL_RES_NT_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span>
|
||
|
<span class="definition-keyword">define</span> <span class="constant-syntax">ORDINAL_RES_NT_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
|
||
|
<span class="definition-keyword">define</span> <span class="constant-syntax">ARTICLE_RES_NT_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
|
||
|
<span class="definition-keyword">define</span> <span class="constant-syntax">ADJECTIVE_RES_NT_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
|
||
|
<span class="definition-keyword">define</span> <span class="constant-syntax">PROPER_NOUN_RES_NT_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span>
|
||
|
<span class="definition-keyword">define</span> <span class="constant-syntax">COMMON_NOUN_RES_NT_BIT</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">NTI::give_nt_reserved_incidence_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="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">b</span><span class="plain-syntax"> < </span><span class="constant-syntax">0</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">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"assigned bad bit"</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_incidence_bit</span><span class="plain-syntax"> = (1 << </span><span class="identifier-syntax">b</span><span class="plain-syntax">);</span>
|
||
|
<span class="plain-syntax">}</span>
|
||
|
</pre>
|
||
|
<p class="commentary firstcommentary"><a id="SP28"></a><b>§28. </b>The other thing which the parent can do is to add constraints of its own
|
||
|
on specific nonterminals. This is especially useful for internals, because
|
||
|
those would otherwise have no constraints.
|
||
|
</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">NTI::one_word_in_match_must_have_my_NTI_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="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_ntic</span><span class="plain-syntax">.</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> |= (</span><a href="4-ni.html#SP2" class="function-link"><span class="function-syntax">NTI::nt_incidence_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">NTI::first_word_in_match_must_have_my_NTI_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="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_ntic</span><span class="plain-syntax">.</span><span class="element-syntax">FS_req</span><span class="plain-syntax"> |= (</span><a href="4-ni.html#SP2" class="function-link"><span class="function-syntax">NTI::nt_incidence_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">NTI::every_word_in_match_must_have_my_NTI_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="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_ntic</span><span class="plain-syntax">.</span><span class="element-syntax">CS_req</span><span class="plain-syntax"> |= (</span><a href="4-ni.html#SP2" class="function-link"><span class="function-syntax">NTI::nt_incidence_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">NTI::every_word_in_match_must_have_my_NTI_bit_or_this_one</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">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_ntic</span><span class="plain-syntax">.</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> |= (</span><a href="4-ni.html#SP2" class="function-link"><span class="function-syntax">NTI::nt_incidence_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>
|
||
|
</pre>
|
||
|
<nav role="progress"><div class="progresscontainer">
|
||
|
<ul class="progressbar"><li class="progressprev"><a href="4-le.html">❮</a></li><li class="progresschapter"><a href="P-wtmd.html">P</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-ap.html">ap</a></li><li class="progresssection"><a href="4-nnt.html">nnt</a></li><li class="progresssection"><a href="4-lp.html">lp</a></li><li class="progresssection"><a href="4-to.html">to</a></li><li class="progresssection"><a href="4-le.html">le</a></li><li class="progresscurrent">ni</li><li class="progresssection"><a href="4-prf.html">prf</a></li><li class="progresssection"><a href="4-bn.html">bn</a></li><li class="progresssection"><a href="4-ins.html">ins</a></li><li class="progressnext"><a href="4-prf.html">❯</a></li></ul></div>
|
||
|
</nav><!--End of weave-->
|
||
|
|
||
|
</main>
|
||
|
</body>
|
||
|
</html>
|
||
|
|