1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-05-19 17:39:23 +03:00

Refactored Preform optimiser

This commit is contained in:
Graham Nelson 2020-05-19 11:46:13 +01:00
parent 9585c6bffc
commit 8494c465b6
84 changed files with 81273 additions and 13275 deletions

View file

@ -1,6 +1,6 @@
# Inform 7
v10.1.0-alpha.1+6Q48 'Krypton' (18 May 2020)
v10.1.0-alpha.1+6Q49 'Krypton' (19 May 2020)
## About Inform 7

View file

@ -1,3 +1,3 @@
Prerelease: alpha.1
Build Date: 18 May 2020
Build Number: 6Q48
Build Date: 19 May 2020
Build Number: 6Q49

View file

@ -331,7 +331,7 @@ logging:
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repositories</span><span class="plain-syntax">[</span><span class="identifier-syntax">step</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repository_argument</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><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">"no repository"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-ppl.html#SP5" class="function-link"><span class="function-syntax">CodeGen::Pipeline::prepare_to_run</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="comment-syntax"> CodeGen::Pipeline::lint(I);</span>
<span class="plain-syntax"> </span><a href="1-ppl.html#SP5" class="function-link"><span class="function-syntax">CodeGen::Pipeline::lint</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-ppl.html#SP2" class="function-link"><span class="function-syntax">CodeGen::Pipeline::clean_step</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">step</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">step</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">the_PP</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PP</span><span class="plain-syntax">;</span>

View file

@ -781,7 +781,7 @@ blind eye to singular vs plural.
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">int</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">which_N</span><span class="Preform-plain-syntax"> = -1; </span><span class="Preform-identifier-syntax">quantifier</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">quantifier_used</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">NULL</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">int</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">x1</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">Quantifiers::parse_against_text</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">, &amp;</span><span class="Preform-identifier-syntax">which_N</span><span class="Preform-plain-syntax">, &amp;</span><span class="Preform-identifier-syntax">quantifier_used</span><span class="Preform-plain-syntax">);</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">x1</span><span class="Preform-plain-syntax"> &gt;= </span><span class="Preform-constant-syntax">0</span><span class="Preform-plain-syntax">) {</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> ((</span><span class="Preform-identifier-syntax">x1</span><span class="Preform-plain-syntax">&lt;</span><span class="Preform-identifier-syntax">Wordings::last_wn</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">)) &amp;&amp; (</span><span class="Preform-identifier-syntax">Optimiser::test_word</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">x1</span><span class="Preform-plain-syntax">, </span><span class="Preform-function-syntax">&lt;article&gt;</span><span class="Preform-plain-syntax">))) </span><span class="Preform-identifier-syntax">x1</span><span class="Preform-plain-syntax">++;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> ((</span><span class="Preform-identifier-syntax">x1</span><span class="Preform-plain-syntax">&lt;</span><span class="Preform-identifier-syntax">Wordings::last_wn</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">)) &amp;&amp; (</span><span class="Preform-identifier-syntax">NTI::test_word</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">x1</span><span class="Preform-plain-syntax">, </span><span class="Preform-function-syntax">&lt;article&gt;</span><span class="Preform-plain-syntax">))) </span><span class="Preform-identifier-syntax">x1</span><span class="Preform-plain-syntax">++;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">parse_node</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">qp</span><span class="Preform-plain-syntax"> = </span><a href="14-sp.html#SP8" class="function-link"><span class="Preform-function-syntax">Specifications::new_UNKNOWN</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">Wordings::up_to</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">x1</span><span class="Preform-plain-syntax">-1));</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">Node::set_quant</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">qp</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">quantifier_used</span><span class="Preform-plain-syntax">);</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">Annotations::write_int</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">qp</span><span class="Preform-plain-syntax">, </span><span class="Preform-constant-syntax">quantification_parameter_ANNOT</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">which_N</span><span class="Preform-plain-syntax">);</span>

View file

@ -315,7 +315,7 @@ offer the new adjective around and see if anybody claims it.
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::mark_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;s-adjective&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;s-adjective&gt;</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">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>

View file

@ -287,7 +287,7 @@ whole thing into a <span class="extract"><span class="extract-syntax">specificat
<p class="commentary firstcommentary"><a id="SP7"></a><b>&#167;7. </b></p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PREFORM_ADAPTIVE_PERSON</span><span class="plain-syntax"> </span><a href="3-nl.html#SP5" class="function-link"><span class="function-syntax">NaturalLanguages::adaptive_person</span></a>
<span class="definition-keyword">define</span> <span class="constant-syntax">PREFORM_OPTIMISER</span><span class="plain-syntax"> </span><a href="4-its.html#SP8" class="function-link"><span class="function-syntax">Semantics::mark_preform_requirements</span></a>
<span class="definition-keyword">define</span> <span class="constant-syntax">PREFORM_OPTIMISER_WORDS_CALLBACK</span><span class="plain-syntax"> </span><a href="4-its.html#SP8" class="function-link"><span class="function-syntax">Semantics::mark_preform_requirements</span></a>
<span class="definition-keyword">define</span> <span class="constant-syntax">PREFORM_CIRCULARITY_BREAKER</span><span class="plain-syntax"> </span><a href="4-its.html#SP8" class="function-link"><span class="function-syntax">Semantics::break_preform_circularities</span></a>
<span class="definition-keyword">define</span> <span class="constant-syntax">INFLECTIONS_ERROR_HANDLER</span><span class="plain-syntax"> </span><a href="3-nl.html#SP7" class="function-link"><span class="function-syntax">NaturalLanguages::preform_error</span></a>
</pre>
@ -302,28 +302,28 @@ whole thing into a <span class="extract"><span class="extract-syntax">specificat
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;s-adjective&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">3</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;s-instance-name&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-kind&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-kind-of-kind&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-base-kind&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-kind-construction&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-kind-variable-texts&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-kind-variable&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-formal-kind-variable&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-irregular-kind-construction&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-variable-definition&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-single-material&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-optional-material&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-tupled-material&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-tuple-list&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;s-adjective&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">ADJECTIVE_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;s-instance-name&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">PROPER_NOUN_RES_NT_BIT</span><span class="plain-syntax"> /* </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax"> */ );</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-kind&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-kind-of-kind&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-base-kind&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-kind-construction&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-kind-variable-texts&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-kind-variable&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-formal-kind-variable&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-irregular-kind-construction&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-variable-definition&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-single-material&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-optional-material&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-tupled-material&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-tuple-list&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMMON_NOUN_RES_NT_BIT</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-its.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Semantics::mark_preform_requirements</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">Semantics::mark_preform_requirements</span></span>:<br/><a href="4-its.html#SP7">&#167;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">Optimiser::mark_nt_as_requiring_itself_conj</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;s-adjective&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::every_word_in_match_must_have_my_NTI_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;s-adjective&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-its.html#SP8" class="function-link"><span class="function-syntax">Semantics::mark_nt_as_requiring_itself_articled</span></a><span class="plain-syntax">(</span><span class="function-syntax">&lt;s-instance-name&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-its.html#SP8" class="function-link"><span class="function-syntax">Semantics::mark_nt_as_requiring_itself_articled</span></a><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-kind-variable&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-its.html#SP8" class="function-link"><span class="function-syntax">Semantics::mark_nt_as_requiring_itself_articled</span></a><span class="plain-syntax">(</span><span class="function-syntax">&lt;k-formal-kind-variable&gt;</span><span class="plain-syntax">);</span>
@ -337,7 +337,8 @@ whole thing into a <span class="extract"><span class="extract-syntax">specificat
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Semantics::mark_nt_as_requiring_itself_articled</span><span class="plain-syntax">(</span><span class="identifier-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">Optimiser::mark_nt_as_requiring_itself_augmented</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">Optimiser::nt_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;article&gt;</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::every_word_in_match_must_have_my_NTI_bit_or_this_one</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">NTI::nt_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;article&gt;</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">

View file

@ -0,0 +1,16 @@
div.download-container p {
text-align: center;
}
div.download-container button.download-button {
background-color: DodgerBlue;
border: none;
color: white;
padding: 10px 24px;
cursor: pointer;
font-size: 18px;
}
div.download-container button.download-button:hover {
background-color: RoyalBlue;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -120,7 +120,7 @@ only be allowed if K already existed.
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">FALSE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP5"></a><b>&#167;5. </b>And the following internal is in fact only &lt;k-kind&gt; but inside phrase
token parsing mode; it's used when parsing the kind to be decided by a
phrase (which, like phrase tokens, can involve the variables).
@ -136,7 +136,7 @@ phrase (which, like phrase tokens, can involve the variables).
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">FALSE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. </b>And here is that "name of kind..." construction, which is valid only in
phrase tokens.
</p>
@ -154,7 +154,7 @@ phrase tokens.
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-kind-of-kind&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-formal-kind-variable&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> Kinds::variable_construction(R[2], RP[1])</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-kind&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> RP[1]</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP7"></a><b>&#167;7. </b>So now we can begin properly. Every valid kind matches &lt;k-kind&gt;:
</p>
@ -167,7 +167,7 @@ phrase tokens.
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-irregular-kind-construction&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> RP[1]</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-kind-construction&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> RP[1]</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. </b>And, as a convenient shorthand:
</p>
@ -176,7 +176,7 @@ phrase tokens.
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;indefinite-article&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-kind&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> RP[2]</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-kind&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> RP[1]</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. </b>In phrase-token mode, kind variables are treated as formal symbols, not as
the kinds which are their current values:
</p>
@ -186,7 +186,7 @@ the kinds which are their current values:
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-formal-kind-variable&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> RP[1]</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-kind-of-kind&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">of</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">kind</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-formal-kind-variable&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> Kinds::variable_construction(R[2], RP[1])</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP10"></a><b>&#167;10. </b>Some base kinds with one-word names have that word flagged with a direct
pointer to the kind, for speed of parsing. Names of base kinds, such as
"number" or "vehicle", can be registered in two different ways (according
@ -219,7 +219,7 @@ make two further checks:
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">FALSE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP11"></a><b>&#167;11. </b>"Object based rulebook" has been on a voyage of unhyphenation: in the
early public beta of Inform 7, it was "object-based-rulebook" (at that
time, built-in kinds had to have one-word names); then it became "object-based
@ -246,7 +246,7 @@ And similarly for the others here, except "either/or property", which is a
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">action-based</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">rule</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> Kinds::binary_construction(CON_rule, K_action_name, K_nil); if (K_action_name == NULL) return FALSE;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">either-or</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">property</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> Kinds::unary_construction(CON_property, K_truth_state)</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;12. </b>This loop looks a little slow, but there are only about 10 proper constructors.
</p>
@ -263,7 +263,7 @@ And similarly for the others here, except "either/or property", which is a
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">FALSE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP12_1"></a><b>&#167;12.1. </b>So at this point we have a match of the fixed words in the constructor.
For example, we might have "list of ...", where the X excerpt represents
the "..." and the Y excerpt is empty; or "... based rule producing ...",
@ -356,7 +356,7 @@ be more varied.
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-single-material&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-tuple-list&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> Kinds::binary_construction(CON_TUPLE_ENTRY, RP[1], RP[2])</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-single-material&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> Kinds::binary_construction(CON_TUPLE_ENTRY, RP[1], K_nil)</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP14"></a><b>&#167;14. </b>The following looks at a word range and tries to find text making a kind
construction: if it does, it adjusts the word ranges to the kind(s) being
constructed on, and returns <span class="extract"><span class="Preform-extract-syntax">TRUE</span></span>; if it fails, it returns <span class="extract"><span class="Preform-extract-syntax">FALSE</span></span>. For
@ -450,7 +450,7 @@ or "list of texts" will fail.
<span class="Preform-function-syntax">&lt;k-kind-of-kind&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;k-kind&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> RP[1]; if (Kinds::Behaviour::is_kind_of_kind(RP[1]) == FALSE) return FALSE;</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP16"></a><b>&#167;16. Parsing kind variables. </b>As a small detour, here's how we deal with the pleasingly simple names A to Z
for kind variables, converting them to and from the numbers 1 to 26:
</p>
@ -505,7 +505,7 @@ parsed almost all of the time.
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">FALSE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP18"></a><b>&#167;18. </b>But we can also formally parse A to Z as their own abstract identities;
now they always parse, regardless of what might be stored in them, and
they aren't replaced with their values (which they may not even have).
@ -520,7 +520,7 @@ they aren't replaced with their values (which they may not even have).
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">FALSE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP19"></a><b>&#167;19. </b>And it's also convenient to have:
</p>
@ -533,7 +533,7 @@ they aren't replaced with their values (which they may not even have).
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">FALSE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP20"></a><b>&#167;20. </b>For efficiency's sake, we don't actually parse directly using this
nonterminal, but it's needed all the same because of Preform's optimisations.
</p>
@ -567,7 +567,7 @@ nonterminal, but it's needed all the same because of Preform's optimisations.
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">y/ys</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">z/zs</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP21"></a><b>&#167;21. Textual descriptions. </b>The following pretty-printer is inverse to the code which parses text and
turns it into a <span class="extract"><span class="Preform-extract-syntax">kind</span></span> structure, or very nearly so. We use common
code to handle all of the reasons why we might want to spell out a kind

View file

@ -1074,7 +1074,7 @@ concatenated with newlines dividing them, in a text stream.
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">length</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Vocabulary::set_flags</span><span class="plain-syntax">(</span><span class="identifier-syntax">array</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">], </span><span class="constant-syntax">KIND_SLOW_MC</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">array</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">], </span><span class="function-syntax">&lt;k-kind&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">array</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">], </span><span class="function-syntax">&lt;k-kind&gt;</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">con</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">group</span><span class="plain-syntax"> != </span><span class="constant-syntax">PROPER_CONSTRUCTOR_GRP</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> = </span><span class="identifier-syntax">WordAssemblages::hyphenated</span><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">stc</span><span class="plain-syntax">.</span><span class="element-syntax">vocabulary_argument</span><span class="plain-syntax">));</span>

View file

@ -769,7 +769,7 @@ as a kind whose name coincides with a property.
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">narrative</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">viewpoint</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">grammatical</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">case</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP33"></a><b>&#167;33. Creating new base kind constructors. </b>Inform's whole stock of constructors comes from two routes: this one, from the
source text, and another we shall see later, from the Kind Interpreter. The
following is called in response to sentences like:
@ -942,7 +942,7 @@ it is. There is no need for speed here.
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::mark_vocabulary_as_kind</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">Kinds::mark_vocabulary_as_kind</span></span>:<br/>Kind Interpreter - <a href="2-ki.html#SP28_4">&#167;28.4</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ve</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">means</span><span class="plain-syntax">.</span><span class="identifier-syntax">one_word_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Vocabulary::set_flags</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="constant-syntax">KIND_FAST_MC</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;k-kind&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;k-kind&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP36"></a><b>&#167;36. From context. </b>Sometimes we need to kmow the current values of the 26 kind variables, A

View file

@ -196,12 +196,18 @@ syntax tree.
initialises, it calls the following routine to improve its performance.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">FURTHER_PREFORM_OPTIMISER_WORDS_CALLBACK</span><span class="plain-syntax"> </span><a href="1-lm.html#SP5" class="function-link"><span class="function-syntax">LinguisticsModule::preform_optimiser</span></a>
</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">first_round_of_nt_optimisation_made</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LinguisticsModule::preform_optimiser</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-cao.html#SP3" class="function-link"><span class="function-syntax">Cardinals::preform_optimiser</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="4-vu.html#SP23" class="function-link"><span class="function-syntax">VerbUsages::preform_optimiser</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP11" class="function-link"><span class="function-syntax">Prepositions::preform_optimiser</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="3-daq.html#SP18" class="function-link"><span class="function-syntax">Quantifiers::make_built_in</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_round_of_nt_optimisation_made</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">first_round_of_nt_optimisation_made</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-daq.html#SP18" class="function-link"><span class="function-syntax">Quantifiers::make_built_in</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">

View file

@ -496,7 +496,7 @@ object "Gregory the Great".
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Logging meaning: $M with hash %08x\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">em</span><span class="plain-syntax">, </span><span class="identifier-syntax">em</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">excerpt_hash</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"# in registration of subset meaning"</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">Optimiser::test_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;article&gt;</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NTI::test_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;article&gt;</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="2-em.html#SP14" class="function-link"><span class="function-syntax">ExcerptMeanings::new_em_pnode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">em</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">v</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">means</span><span class="plain-syntax">.</span><span class="element-syntax">subset_list</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">means</span><span class="plain-syntax">.</span><span class="element-syntax">subset_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
@ -579,10 +579,10 @@ meanings.
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">meaning_code</span><span class="plain-syntax"> == </span><span class="constant-syntax">NOUN_MC</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">Optimiser::mark_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;s-instance-name&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;s-instance-name&gt;</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">meaning_code</span><span class="plain-syntax"> == </span><span class="identifier-syntax">KIND_SLOW_MC</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">Optimiser::mark_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;k-kind&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;k-kind&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">excerpt_meaning</span><span class="plain-syntax"> *</span><span class="identifier-syntax">em</span><span class="plain-syntax"> = </span><a href="2-em.html#SP7" class="function-link"><span class="function-syntax">ExcerptMeanings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">meaning_code</span><span class="plain-syntax">, </span><span class="identifier-syntax">data</span><span class="plain-syntax">);</span>
@ -615,7 +615,7 @@ text substitutions need to distinguish (for instance) "say [the X]" from
<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">meaning_code</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">PARAMETRISED_PARSING_BITMAP</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">Optimiser::test_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">), </span><span class="function-syntax">&lt;article&gt;</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">NTI::test_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">), </span><span class="function-syntax">&lt;article&gt;</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::trim_first_word</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">Wordings::empty</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">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"registered a meaning which was only an article"</span><span class="plain-syntax">);</span>

View file

@ -577,7 +577,7 @@ abbreviated form of an object name like "Chamber 11".
<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">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">v</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">v</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">"Unidentified word when parsing"</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">Optimiser::test_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;article&gt;</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NTI::test_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;article&gt;</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">v</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">means</span><span class="plain-syntax">.</span><span class="element-syntax">subset_list_length</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">SubsetFailed</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">v</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">means</span><span class="plain-syntax">.</span><span class="element-syntax">subset_list_length</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">j</span><span class="plain-syntax">) { </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="identifier-syntax">v</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">means</span><span class="plain-syntax">.</span><span class="element-syntax">subset_list_length</span><span class="plain-syntax">; </span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> }</span>

View file

@ -202,13 +202,11 @@ is never treated as a participle.
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">not</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. Marking for Preform efficiency. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Articles::mark_for_preform</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">Articles::mark_for_preform</span></span>:<br/>Linguistics Module - <a href="1-lm.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;article&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;definite-article&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;indefinite-article&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;article&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">ARTICLE_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;definite-article&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">ARTICLE_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;indefinite-article&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">ARTICLE_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">

View file

@ -155,7 +155,7 @@ distinct from its meaning, and this is it.
<span class="plain-syntax"> </span><a href="2-em.html#SP15" class="function-link"><span class="function-syntax">ExcerptMeanings::register</span></a><span class="plain-syntax">(</span><span class="constant-syntax">ADJECTIVE_MC</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">STORE_POINTER_adjectival_phrase</span><span class="plain-syntax">(</span><span class="identifier-syntax">aph</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">n</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">Optimiser::mark_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;adjective-name&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;adjective-name&gt;</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">ADJECTIVE_NAME_VETTING</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>

View file

@ -122,8 +122,8 @@ numbers.
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Cardinals::preform_optimiser</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">Cardinals::preform_optimiser</span></span>:<br/>Linguistics Module - <a href="1-lm.html#SP5">&#167;5</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">Optimiser::mark_nt_as_requiring_itself_conj</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;cardinal-number&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::mark_nt_as_requiring_itself_conj</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;ordinal-number&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::every_word_in_match_must_have_my_NTI_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;cardinal-number&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::every_word_in_match_must_have_my_NTI_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;ordinal-number&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">lexer_wordcount</span><span class="plain-syntax">; </span><span class="identifier-syntax">wn</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Vocabulary::test_flags</span><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="identifier-syntax">NUMBER_MC</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="3-cao.html#SP3" class="function-link"><span class="function-syntax">Cardinals::mark_as_cardinal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">));</span>
@ -133,22 +133,22 @@ numbers.
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Cardinals::mark_as_cardinal</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">Cardinals::mark_as_cardinal</span></span>:<br/>Excerpt Meanings - <a href="2-em.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::set_nt_incidence</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;cardinal-number&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;cardinal-number&gt;</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">Cardinals::mark_as_ordinal</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">Cardinals::mark_as_ordinal</span></span>:<br/>Excerpt Meanings - <a href="2-em.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::set_nt_incidence</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;ordinal-number&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;ordinal-number&gt;</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">Cardinals::enable_in_word_form</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">Cardinals::enable_in_word_form</span></span>:<br/>Linguistics Module - <a href="1-lm.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;cardinal-number&gt;</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">Optimiser::assign_bitmap_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;ordinal-number&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;cardinal-number&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">CARDINAL_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::give_nt_reserved_incidence_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;ordinal-number&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">ORDINAL_RES_NT_BIT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;cardinal-number-in-words&gt;-&gt;</span><span class="identifier-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">number_words_by_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="function-syntax">&lt;cardinal-number-in-words&gt;-&gt;</span><span class="identifier-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">flag_words_in_production</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NUMBER_MC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Nonterminals::make_numbering</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;cardinal-number-in-words&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Nonterminals::flag_words_with</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;cardinal-number-in-words&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">NUMBER_MC</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;ordinal-number-in-words&gt;-&gt;</span><span class="identifier-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">number_words_by_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="function-syntax">&lt;ordinal-number-in-words&gt;-&gt;</span><span class="identifier-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">flag_words_in_production</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ORDINAL_MC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Nonterminals::make_numbering</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;ordinal-number-in-words&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Nonterminals::flag_words_with</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;ordinal-number-in-words&gt;</span><span class="plain-syntax">, </span><span class="identifier-syntax">ORDINAL_MC</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. </b>Actual parsing is done here. We look at a single word to see if it's a

View file

@ -237,20 +237,20 @@ with a given "permitted verb".
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Prepositions::mark_for_preform</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">Prepositions::mark_for_preform</span></span>:<br/>Linguistics Module - <a href="1-lm.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;relative-clause-marker&gt;-&gt;</span><span class="identifier-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">flag_words_in_production</span><span class="plain-syntax"> = </span><span class="constant-syntax">PREPOSITION_MC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Nonterminals::flag_words_with</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;relative-clause-marker&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">PREPOSITION_MC</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">Prepositions::preform_optimiser</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">Prepositions::preform_optimiser</span></span>:<br/>Linguistics Module - <a href="1-lm.html#SP5">&#167;5</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">Optimiser::mark_nt_as_requiring_itself</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;preposition&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::mark_nt_as_requiring_itself</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;copular-preposition&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::mark_nt_as_requiring_itself</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;permitted-preposition&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::one_word_in_match_must_have_my_NTI_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;preposition&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::one_word_in_match_must_have_my_NTI_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;copular-preposition&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::one_word_in_match_must_have_my_NTI_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;permitted-preposition&gt;</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">Prepositions::mark_as_preposition</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">Prepositions::mark_as_preposition</span></span>:<br/><a href="4-prp.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Vocabulary::set_flags</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="constant-syntax">PREPOSITION_MC</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::set_nt_incidence</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;preposition&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::set_nt_incidence</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;copular-preposition&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::set_nt_incidence</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;permitted-preposition&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;preposition&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;copular-preposition&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;permitted-preposition&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">

View file

@ -751,21 +751,21 @@ or "the verb to be able to see" use these.
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">VerbUsages::mark_as_verb</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">VerbUsages::mark_as_verb</span></span>:<br/><a href="4-vu.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::set_nt_incidence</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;meaningful-nonimperative-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::set_nt_incidence</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;copular-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::set_nt_incidence</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;negated-noncopular-verb-present&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::set_nt_incidence</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;universal-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::set_nt_incidence</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;negated-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::set_nt_incidence</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;past-tense-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;meaningful-nonimperative-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;copular-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;negated-noncopular-verb-present&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;universal-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;negated-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::mark_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;past-tense-verb&gt;</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">VerbUsages::preform_optimiser</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">VerbUsages::preform_optimiser</span></span>:<br/>Linguistics Module - <a href="1-lm.html#SP5">&#167;5</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">Optimiser::mark_nt_as_requiring_itself_first</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;meaningful-nonimperative-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::mark_nt_as_requiring_itself_first</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;copular-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::mark_nt_as_requiring_itself_first</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;negated-noncopular-verb-present&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::mark_nt_as_requiring_itself_first</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;universal-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::mark_nt_as_requiring_itself_first</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;negated-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Optimiser::mark_nt_as_requiring_itself_first</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;past-tense-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::first_word_in_match_must_have_my_NTI_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;meaningful-nonimperative-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::first_word_in_match_must_have_my_NTI_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;copular-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::first_word_in_match_must_have_my_NTI_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;negated-noncopular-verb-present&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::first_word_in_match_must_have_my_NTI_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;universal-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::first_word_in_match_must_have_my_NTI_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;negated-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NTI::first_word_in_match_must_have_my_NTI_bit</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;past-tense-verb&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24"></a><b>&#167;24. Adaptive person. </b></p>

View file

@ -293,7 +293,7 @@ since non-zero-ness in the viability map is used only to speed up parsing.
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACKET_V</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACE_V</span><span class="plain-syntax">)) </span><span class="identifier-syntax">bl</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> - </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">VIABILITY_MAP_SIZE</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Optimiser::test_nt_incidence</span><span class="plain-syntax">(</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">), </span><span class="function-syntax">&lt;meaningful-nonimperative-verb&gt;</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">viable</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</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">NTI::test_vocabulary</span><span class="plain-syntax">(</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">), </span><span class="function-syntax">&lt;meaningful-nonimperative-verb&gt;</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">viable</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</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">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">viable</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">viable</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos_to</span><span class="plain-syntax"> = -(</span><span class="function-syntax">&lt;negated-noncopular-verb-present&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">)));</span>

View file

@ -551,7 +551,7 @@ and no documentation.
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">----</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">documentation</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">----</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> TRUE</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> FALSE</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_2_2"></a><b>&#167;7.2.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Break the extension's text into body and documentation</span><span class="named-paragraph-number">7.2.2</span></span><span class="Preform-comment-syntax"> =</span>
</p>

View file

@ -215,7 +215,7 @@ overlapping with this, and they need to match.
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">say</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> SAY_SIGF</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">now</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> NOW_SIGF</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP7"></a><b>&#167;7. </b>This is used to see if an "if" is being used with the comma notation:
</p>
@ -223,7 +223,7 @@ overlapping with this, and they need to match.
<span class="Preform-function-syntax">&lt;phrase-with-comma-notation&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">......</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">......</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. </b>This is used to see if an "if" is being used with the comma notation:
</p>
@ -232,7 +232,7 @@ overlapping with this, and they need to match.
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">instead</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">instead</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. </b>Finally, this is used to see if a control structure opens a block:
</p>
@ -240,7 +240,7 @@ overlapping with this, and they need to match.
<span class="Preform-function-syntax">&lt;phrase-beginning-block&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">begin</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP10"></a><b>&#167;10. </b>And some miscellaneous provisions:
</p>

View file

@ -439,7 +439,7 @@ allowed; they should probably be withdrawn.
<span class="Preform-function-syntax">&lt;extension-identifier&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">......</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">by</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">......</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-hdn.html#SP12_3" class="named-paragraph-link"><span class="named-paragraph">Set for-use-with extension identifier</span><span class="named-paragraph-number">12.3</span></a></span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP12_1"></a><b>&#167;12.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_UnknownLanguageElement problem</span><span class="named-paragraph-number">12.1</span></span><span class="Preform-comment-syntax"> =</span>
</p>
@ -493,7 +493,7 @@ otherwise.
<span class="Preform-plain-syntax"> }</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP14"></a><b>&#167;14. The heading tree. </b>Until <a href="6-hdn.html#SP14" class="internal">Headings::assemble_tree</a> runs, the <a href="6-hdn.html#SP6" class="internal">heading</a> nodes listed as belonging
to the heading tree are not in fact formed up into a tree structure.
</p>

View file

@ -167,7 +167,7 @@ word "Include", which might e.g. be "Locksmith by Emily Short".
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;quoted-text&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-inc.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Issue PM_IncludeExtQuoted problem</span><span class="named-paragraph-number">2.1</span></a></span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> 0; &lt;&lt;t1&gt;&gt; = Wordings::first_wn(W); &lt;&lt;t2&gt;&gt; = Wordings::last_wn(W)</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_1"></a><b>&#167;2.1. </b>Quite a popular mistake, this:
</p>
@ -191,7 +191,7 @@ word "Include", which might e.g. be "Locksmith by Emily Short".
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. </b></p>
<pre class="displayed-code all-displayed-code code-font">
@ -402,7 +402,7 @@ use an extension which is marked as not working on the current VM.
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;extension-title-and-version&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">by</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-inc.html#SP8_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem</span><span class="named-paragraph-number">8.1</span></a></span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_1"></a><b>&#167;8.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem</span><span class="named-paragraph-number">8.1</span></span><span class="Preform-comment-syntax"> =</span>
</p>
@ -446,7 +446,7 @@ the "begins here".
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">inclusions_errors_to</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="6-tof.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-sm.html">1</a></li><li class="progresschapter"><a href="2-gnr.html">2</a></li><li class="progresschapter"><a href="3-bg.html">3</a></li><li class="progresschapter"><a href="4-em.html">4</a></li><li class="progresschapter"><a href="5-es.html">5</a></li><li class="progresscurrentchapter">6</li><li class="progresssection"><a href="6-st.html">st</a></li><li class="progresssection"><a href="6-hdn.html">hdn</a></li><li class="progresssection"><a href="6-tbs.html">tbs</a></li><li class="progresssection"><a href="6-tof.html">tof</a></li><li class="progresscurrent">inc</li><li class="progresssection"><a href="6-cs.html">cs</a></li><li class="progresssection"><a href="6-vmg.html">vmg</a></li><li class="progresschapter"><a href="7-tm.html">7</a></li><li class="progressnext"><a href="6-cs.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->

View file

@ -316,7 +316,7 @@ and here goes:
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">begin/begins</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">here</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> -1; </span><span class="named-paragraph-container code-font"><a href="6-st.html#SP9_1" class="named-paragraph-link"><span class="named-paragraph">Check we can begin an extension here</span><span class="named-paragraph-number">9.1</span></a></span><span class="Preform-constant-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">end/ends</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">here</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> -2; </span><span class="named-paragraph-container code-font"><a href="6-st.html#SP9_2" class="named-paragraph-link"><span class="named-paragraph">Check we can end an extension here</span><span class="named-paragraph-number">9.2</span></a></span><span class="Preform-constant-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1"></a><b>&#167;9.1. </b>Note that the extension end markers are only read in extensions, so they can
never accidentally match in the main source text.
</p>
@ -359,7 +359,7 @@ never accidentally match in the main source text.
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">include</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">by</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> 0; sfsm-&gt;nt = INCLUDE_NT;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">include</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">(-</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> 0; sfsm-&gt;nt = INFORM6CODE_NT;</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP11"></a><b>&#167;11. </b>Rules are ordinarily detected by their colon, which divides the header from the
rest: colons are not otherwise legal in Inform. But there's an exception. If the
sentence consists of text matching the following grammar, followed by comma,
@ -379,7 +379,7 @@ sentence becomes a rule. For example:
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">after</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">when</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;12. </b>Properly speaking, despite the definition above, language modifying sentences
are nonstructural. So what are they doing here? The answer is that we need to
read them early on, because they affect the way that they parse all other
@ -391,7 +391,7 @@ sentences. Whereas other nonstructural sentences can wait, these can't.
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">include</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">(-</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">###</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">in</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">the</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">preform</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">grammar</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> -2; sfsm-&gt;nt = INFORM6CODE_NT;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">use</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">language</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">element/elements</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> -1</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP13"></a><b>&#167;13. </b>The following callback function is called by <a href="../syntax-module/index.html" class="internal">syntax</a> when it breaks a
sentence of type <span class="extract"><span class="Preform-extract-syntax">BEGINHERE_NT</span></span> or <span class="extract"><span class="Preform-extract-syntax">ENDHERE_NT</span></span> &mdash; i.e., the beginning or end
of an extension.

View file

@ -109,7 +109,7 @@ to declare the title and author.
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{&lt;quoted-text-without-subs&gt;}</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">by</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> TRUE</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{&lt;quoted-text-without-subs&gt;}</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> FALSE</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_2"></a><b>&#167;1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Extract title and author name wording</span><span class="named-paragraph-number">1.2</span></span><span class="Preform-comment-syntax"> =</span>
</p>

View file

@ -98,7 +98,7 @@ unyielding the user's views, it's not allowed to write:
<span class="Preform-function-syntax">&lt;use-option-sentence-shape&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">use</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">.</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b>There is just one options file, so no need to load it more than once.
</p>

View file

@ -84,7 +84,7 @@ to give it permanency.
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">result</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b>The following nonterminal matches any valid description of a virtual machine,
with result <span class="extract"><span class="Preform-extract-syntax">TRUE</span></span> if the current target VM matches that description and
<span class="extract"><span class="Preform-extract-syntax">FALSE</span></span> if not.
@ -99,7 +99,7 @@ with result <span class="extract"><span class="Preform-extract-syntax">TRUE</spa
<span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">XP</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">NULL</span><span class="Preform-plain-syntax">; </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">FALSE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="6-cs.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-sm.html">1</a></li><li class="progresschapter"><a href="2-gnr.html">2</a></li><li class="progresschapter"><a href="3-bg.html">3</a></li><li class="progresschapter"><a href="4-em.html">4</a></li><li class="progresschapter"><a href="5-es.html">5</a></li><li class="progresscurrentchapter">6</li><li class="progresssection"><a href="6-st.html">st</a></li><li class="progresssection"><a href="6-hdn.html">hdn</a></li><li class="progresssection"><a href="6-tbs.html">tbs</a></li><li class="progresssection"><a href="6-tof.html">tof</a></li><li class="progresssection"><a href="6-inc.html">inc</a></li><li class="progresssection"><a href="6-cs.html">cs</a></li><li class="progresscurrent">vmg</li><li class="progresschapter"><a href="7-tm.html">7</a></li><li class="progressnext"><a href="7-tm.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->

View file

@ -115,7 +115,7 @@ possible meaning as a literal integer, we cache the result: for instance,
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure vocabulary_entry is accessed in 4/to and here.</li></ul>
<ul class="endnotetexts"><li>The structure vocabulary_entry is accessed in 4/nnt and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b>Some standard punctuation marks:
</p>
@ -345,14 +345,15 @@ and so on:
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;12. </b>Also:
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;12. </b>We also leave space for a bitmap used by <a href="4-to.html" class="internal">The Optimiser</a>: in particular,
see <a href="4-ni.html#SP3" class="internal">NTI::mark_vocabulary</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">Vocabulary::set_ntb</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">Vocabulary::set_ntb</span></span>:<br/>The Optimiser - <a href="4-to.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Vocabulary::set_nti</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">Vocabulary::set_nti</span></span>:<br/>Nonterminal Incidences - <a href="4-ni.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ve</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_incidence</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">Vocabulary::get_ntb</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">Vocabulary::get_ntb</span></span>:<br/>The Optimiser - <a href="4-to.html#SP3">&#167;3</a>, <a href="4-to.html#SP4">&#167;4</a>, <a href="4-to.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Vocabulary::get_nti</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">Vocabulary::get_nti</span></span>:<br/>Nonterminal Incidences - <a href="4-ni.html#SP3">&#167;3</a>, <a href="4-ni.html#SP5">&#167;5</a>, <a href="4-ni.html#SP8_1">&#167;8.1</a>, <a href="4-ni.html#SP8_2">&#167;8.2</a>, <a href="4-ni.html#SP8_3">&#167;8.3</a>, <a href="4-ni.html#SP8_4">&#167;8.4</a>, <a href="4-ni.html#SP8_5">&#167;8.5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ve</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_incidence</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>

View file

@ -497,7 +497,7 @@ distinguished. We'll do this with the letters <span class="extract"><span class=
<p class="commentary firstcommentary"><a id="SP20"></a><b>&#167;20. Access functions. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="function-syntax">Lexer::word</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">Lexer::word</span></span>:<br/>Vocabulary - <a href="2-vcb.html#SP6">&#167;6</a>, <a href="2-vcb.html#SP10">&#167;10</a>, <a href="2-vcb.html#SP11">&#167;11</a>, <a href="2-vcb.html#SP16">&#167;16</a><br/>Word Assemblages - <a href="2-wa.html#SP4">&#167;4</a>, <a href="2-wa.html#SP9">&#167;9</a>, <a href="2-wa.html#SP10">&#167;10</a>, <a href="2-wa.html#SP11">&#167;11</a><br/>Numbered Words - <a href="2-nw.html#SP1">&#167;1</a><br/>Wordings - <a href="3-wrd.html#SP8">&#167;8</a>, <a href="3-wrd.html#SP18">&#167;18</a>, <a href="3-wrd.html#SP19">&#167;19</a>, <a href="3-wrd.html#SP20">&#167;20</a><br/>Text From Files - <a href="3-tff.html#SP4">&#167;4</a><br/>Loading Preform - <a href="4-lp.html#SP7">&#167;7</a>, <a href="4-lp.html#SP7_2">&#167;7.2</a>, <a href="4-lp.html#SP7_3">&#167;7.3</a>, <a href="4-lp.html#SP14_1_1">&#167;14.1.1</a>, <a href="4-lp.html#SP14_1_1_1">&#167;14.1.1.1</a>, <a href="4-lp.html#SP14_1_3">&#167;14.1.3</a>, <a href="4-lp.html#SP15_2">&#167;15.2</a><br/>The Optimiser - <a href="4-to.html#SP4">&#167;4</a>, <a href="4-to.html#SP5">&#167;5</a><br/>Preform - <a href="4-prf.html#SP1_2_1_2_3_3_3">&#167;1.2.1.2.3.3.3</a>, <a href="4-prf.html#SP3">&#167;3</a><br/>Basic Nonterminals - <a href="4-bn.html#SP1">&#167;1</a>, <a href="4-bn.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="function-syntax">Lexer::word</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">Lexer::word</span></span>:<br/>Vocabulary - <a href="2-vcb.html#SP6">&#167;6</a>, <a href="2-vcb.html#SP10">&#167;10</a>, <a href="2-vcb.html#SP11">&#167;11</a>, <a href="2-vcb.html#SP16">&#167;16</a><br/>Word Assemblages - <a href="2-wa.html#SP4">&#167;4</a>, <a href="2-wa.html#SP9">&#167;9</a>, <a href="2-wa.html#SP10">&#167;10</a>, <a href="2-wa.html#SP11">&#167;11</a><br/>Numbered Words - <a href="2-nw.html#SP1">&#167;1</a><br/>Wordings - <a href="3-wrd.html#SP8">&#167;8</a>, <a href="3-wrd.html#SP18">&#167;18</a>, <a href="3-wrd.html#SP19">&#167;19</a>, <a href="3-wrd.html#SP20">&#167;20</a><br/>Text From Files - <a href="3-tff.html#SP4">&#167;4</a><br/>Loading Preform - <a href="4-lp.html#SP7">&#167;7</a>, <a href="4-lp.html#SP7_2">&#167;7.2</a>, <a href="4-lp.html#SP7_3">&#167;7.3</a>, <a href="4-lp.html#SP14_1_1">&#167;14.1.1</a>, <a href="4-lp.html#SP14_1_1_1">&#167;14.1.1.1</a>, <a href="4-lp.html#SP14_1_3">&#167;14.1.3</a>, <a href="4-lp.html#SP15_2">&#167;15.2</a><br/>Nonterminal Incidences - <a href="4-ni.html#SP4">&#167;4</a>, <a href="4-ni.html#SP5">&#167;5</a>, <a href="4-ni.html#SP8_1">&#167;8.1</a>, <a href="4-ni.html#SP8_2">&#167;8.2</a>, <a href="4-ni.html#SP8_3">&#167;8.3</a>, <a href="4-ni.html#SP8_4">&#167;8.4</a>, <a href="4-ni.html#SP8_5">&#167;8.5</a><br/>Preform - <a href="4-prf.html#SP1_2_1_2_3_3_3">&#167;1.2.1.2.3.3.3</a>, <a href="4-prf.html#SP3">&#167;3</a><br/>Basic Nonterminals - <a href="4-bn.html#SP1">&#167;1</a>, <a href="4-bn.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lw_array</span><span class="plain-syntax">[</span><span class="identifier-syntax">wn</span><span class="plain-syntax">].</span><span class="element-syntax">lw_identity</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

View file

@ -145,7 +145,7 @@ by moving <span class="extract"><span class="extract-syntax">A</span></span> pas
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. Reading. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Wordings::length</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">Wordings::length</span></span>:<br/><a href="3-wrd.html#SP9">&#167;9</a>, <a href="3-wrd.html#SP14">&#167;14</a>, <a href="3-wrd.html#SP21">&#167;21</a><br/>Word Assemblages - <a href="2-wa.html#SP4">&#167;4</a>, <a href="2-wa.html#SP10">&#167;10</a>, <a href="2-wa.html#SP11">&#167;11</a><br/>Lexer - <a href="3-lxr.html#SP30">&#167;30</a><br/>Loading Preform - <a href="4-lp.html#SP15_2">&#167;15.2</a><br/>The Optimiser - <a href="4-to.html#SP5">&#167;5</a><br/>Preform - <a href="4-prf.html#SP1">&#167;1</a><br/>Instrumentation - <a href="4-ins.html#SP6">&#167;6</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">int</span><span class="plain-syntax"> </span><span class="function-syntax">Wordings::length</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">Wordings::length</span></span>:<br/><a href="3-wrd.html#SP9">&#167;9</a>, <a href="3-wrd.html#SP14">&#167;14</a>, <a href="3-wrd.html#SP21">&#167;21</a><br/>Word Assemblages - <a href="2-wa.html#SP4">&#167;4</a>, <a href="2-wa.html#SP10">&#167;10</a>, <a href="2-wa.html#SP11">&#167;11</a><br/>Lexer - <a href="3-lxr.html#SP30">&#167;30</a><br/>Loading Preform - <a href="4-lp.html#SP15_2">&#167;15.2</a><br/>Nonterminal Incidences - <a href="4-ni.html#SP8">&#167;8</a><br/>Preform - <a href="4-prf.html#SP1">&#167;1</a><br/>Instrumentation - <a href="4-ins.html#SP6">&#167;6</a>, <a href="4-ins.html#SP10">&#167;10</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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-wrd.html#SP12" class="function-link"><span class="function-syntax">Wordings::empty</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</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">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">word_B</span><span class="plain-syntax"> - </span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="element-syntax">word_A</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
@ -161,7 +161,7 @@ by moving <span class="extract"><span class="extract-syntax">A</span></span> pas
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</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">Wordings::first_wn</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">Wordings::first_wn</span></span>:<br/><a href="3-wrd.html#SP18">&#167;18</a>, <a href="3-wrd.html#SP21">&#167;21</a>, <a href="3-wrd.html#SP22_3">&#167;22.3</a>, <a href="3-wrd.html#SP22_4">&#167;22.4</a><br/>Vocabulary - <a href="2-vcb.html#SP16">&#167;16</a><br/>Word Assemblages - <a href="2-wa.html#SP9">&#167;9</a>, <a href="2-wa.html#SP10">&#167;10</a>, <a href="2-wa.html#SP11">&#167;11</a><br/>Lexer - <a href="3-lxr.html#SP26">&#167;26</a>, <a href="3-lxr.html#SP30">&#167;30</a><br/>Loading Preform - <a href="4-lp.html#SP15_2">&#167;15.2</a><br/>The Optimiser - <a href="4-to.html#SP4">&#167;4</a>, <a href="4-to.html#SP5">&#167;5</a><br/>Preform - <a href="4-prf.html#SP1_2">&#167;1.2</a>, <a href="4-prf.html#SP1_2_1_2_2">&#167;1.2.1.2.2</a>, <a href="4-prf.html#SP1_2_1_2_3_1">&#167;1.2.1.2.3.1</a>, <a href="4-prf.html#SP1_2_1_2_3_3">&#167;1.2.1.2.3.3</a>, <a href="4-prf.html#SP1_2_1_2_3_3_3_1">&#167;1.2.1.2.3.3.3.1</a><br/>Basic Nonterminals - <a href="4-bn.html#SP1">&#167;1</a>, <a href="4-bn.html#SP2">&#167;2</a>, <a href="4-bn.html#SP3">&#167;3</a>, <a href="4-bn.html#SP6">&#167;6</a>, <a href="4-bn.html#SP7">&#167;7</a>, <a href="4-bn.html#SP8">&#167;8</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">int</span><span class="plain-syntax"> </span><span class="function-syntax">Wordings::first_wn</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">Wordings::first_wn</span></span>:<br/><a href="3-wrd.html#SP18">&#167;18</a>, <a href="3-wrd.html#SP21">&#167;21</a>, <a href="3-wrd.html#SP22_3">&#167;22.3</a>, <a href="3-wrd.html#SP22_4">&#167;22.4</a><br/>Vocabulary - <a href="2-vcb.html#SP16">&#167;16</a><br/>Word Assemblages - <a href="2-wa.html#SP9">&#167;9</a>, <a href="2-wa.html#SP10">&#167;10</a>, <a href="2-wa.html#SP11">&#167;11</a><br/>Lexer - <a href="3-lxr.html#SP26">&#167;26</a>, <a href="3-lxr.html#SP30">&#167;30</a><br/>Loading Preform - <a href="4-lp.html#SP15_2">&#167;15.2</a><br/>Nonterminal Incidences - <a href="4-ni.html#SP5">&#167;5</a>, <a href="4-ni.html#SP8_1">&#167;8.1</a>, <a href="4-ni.html#SP8_2">&#167;8.2</a>, <a href="4-ni.html#SP8_3">&#167;8.3</a>, <a href="4-ni.html#SP8_4">&#167;8.4</a>, <a href="4-ni.html#SP8_5">&#167;8.5</a><br/>Preform - <a href="4-prf.html#SP1_2">&#167;1.2</a>, <a href="4-prf.html#SP1_2_1_2_2">&#167;1.2.1.2.2</a>, <a href="4-prf.html#SP1_2_1_2_3_1">&#167;1.2.1.2.3.1</a>, <a href="4-prf.html#SP1_2_1_2_3_3">&#167;1.2.1.2.3.3</a>, <a href="4-prf.html#SP1_2_1_2_3_3_3_1">&#167;1.2.1.2.3.3.3.1</a><br/>Basic Nonterminals - <a href="4-bn.html#SP1">&#167;1</a>, <a href="4-bn.html#SP2">&#167;2</a>, <a href="4-bn.html#SP3">&#167;3</a>, <a href="4-bn.html#SP6">&#167;6</a>, <a href="4-bn.html#SP7">&#167;7</a>, <a href="4-bn.html#SP8">&#167;8</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="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="element-syntax">word_A</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
@ -246,7 +246,7 @@ wordings.
<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">int</span><span class="plain-syntax"> </span><span class="function-syntax">Wordings::nonempty</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">Wordings::nonempty</span></span>:<br/><a href="3-wrd.html#SP11">&#167;11</a>, <a href="3-wrd.html#SP14">&#167;14</a><br/>Word Assemblages - <a href="2-wa.html#SP11">&#167;11</a><br/>Identifiers - <a href="3-idn.html#SP3">&#167;3</a><br/>Loading Preform - <a href="4-lp.html#SP15_2">&#167;15.2</a><br/>Basic Nonterminals - <a href="4-bn.html#SP7">&#167;7</a>, <a href="4-bn.html#SP8">&#167;8</a><br/>Instrumentation - <a href="4-ins.html#SP9">&#167;9</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">int</span><span class="plain-syntax"> </span><span class="function-syntax">Wordings::nonempty</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">Wordings::nonempty</span></span>:<br/><a href="3-wrd.html#SP11">&#167;11</a>, <a href="3-wrd.html#SP14">&#167;14</a><br/>Word Assemblages - <a href="2-wa.html#SP11">&#167;11</a><br/>Identifiers - <a href="3-idn.html#SP3">&#167;3</a><br/>Loading Preform - <a href="4-lp.html#SP15_2">&#167;15.2</a><br/>Basic Nonterminals - <a href="4-bn.html#SP7">&#167;7</a>, <a href="4-bn.html#SP8">&#167;8</a><br/>Instrumentation - <a href="4-ins.html#SP10">&#167;10</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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">word_A</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">word_B</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="element-syntax">word_A</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>

View file

@ -393,7 +393,7 @@ colour.
</p>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="3-idn.html">&#10094;</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="progresscurrent">ap</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-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-nnt.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="3-idn.html">&#10094;</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="progresscurrent">ap</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="progresssection"><a href="4-ni.html">ni</a></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-nnt.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -183,7 +183,7 @@ of text <span class="extract"><span class="Preform-extract-syntax">""</span></sp
</pre>
<ul class="endnotetexts"><li>This is <a href="4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-prf.html">&#10094;</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-prf.html">prf</a></li><li class="progresscurrent">bn</li><li class="progresssection"><a href="4-ins.html">ins</a></li><li class="progressnext"><a href="4-ins.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="4-prf.html">&#10094;</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="progresssection"><a href="4-ni.html">ni</a></li><li class="progresssection"><a href="4-prf.html">prf</a></li><li class="progresscurrent">bn</li><li class="progresssection"><a href="4-ins.html">ins</a></li><li class="progressnext"><a href="4-ins.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -173,52 +173,107 @@ matches it.)
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">detailed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%d/%d: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">nonterminal_matches</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">nonterminal_tries</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%V: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP16" class="function-link"><span class="function-syntax">Optimiser::log_range_requirement</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP8" class="function-link"><span class="function-syntax">Instrumentation::log_nt</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">internal_definition</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" (internal)\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="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">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_production_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">, </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" min %d, max %d\n\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Instrumentation::log_nt</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">detailed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%V "</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">marked_internal</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"internal "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">nonterminal_tries</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"hits %d/%d "</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">nonterminal_matches</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">nonterminal_tries</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"nti "</span><span class="plain-syntax">); </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_bit</span></a><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">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" constraint "</span><span class="plain-syntax">); </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_ntic</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</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><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" extremes "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_extremes</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</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="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</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">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP10" class="function-link"><span class="function-syntax">Instrumentation::log_production_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">, </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Instrumentation::log_production_list</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">Instrumentation::log_production_list</span></span>:<br/><a href="4-ins.html#SP8">&#167;8</a></span></button><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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" %J:\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">definition_language</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">); </span><a href="4-ins.html#SP10" class="function-link"><span class="function-syntax">Instrumentation::log_production</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" %d/%d: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">production_matches</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">production_tries</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-wrd.html#SP12" class="function-link"><span class="function-syntax">Wordings::nonempty</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">sample_text</span><span class="plain-syntax">)) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;%W&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">sample_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" ==&gt; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP16" class="function-link"><span class="function-syntax">Optimiser::log_range_requirement</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">production_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Instrumentation::log_ntic</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">Instrumentation::log_ntic</span></span>:<br/><a href="4-ins.html#SP8">&#167;8</a>, <a href="4-ins.html#SP10">&#167;10</a><br/>Preform - <a href="4-prf.html#SP1_2">&#167;1.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">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">c</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">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) { </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">++ &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" &amp; "</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"DW = "</span><span class="plain-syntax">); </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_bitmap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) { </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">++ &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" &amp; "</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"DS = "</span><span class="plain-syntax">); </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_bitmap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">) { </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">++ &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" &amp; "</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"CW = "</span><span class="plain-syntax">); </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_bitmap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">) { </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">++ &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" &amp; "</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"CS = "</span><span class="plain-syntax">); </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_bitmap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">) { </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">++ &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" &amp; "</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"FW = "</span><span class="plain-syntax">); </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_bitmap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) { </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">++ &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" &amp; "</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"FS = "</span><span class="plain-syntax">); </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_bitmap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"(none)"</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">Instrumentation::log_bitmap</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>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"{"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;32; </span><span class="identifier-syntax">i</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><span class="constant-syntax">1</span><span class="plain-syntax"> &lt;&lt; </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bm</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">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">c</span><span class="plain-syntax">++ &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">b</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"}"</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">Instrumentation::log_bit</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">Instrumentation::log_bit</span></span>:<br/><a href="4-ins.html#SP8">&#167;8</a></span></button><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">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;32; </span><span class="identifier-syntax">i</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"> == (1 &lt;&lt; </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">i</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">RESERVED_NT_BITS</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"r"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%d"</span><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">void</span><span class="plain-syntax"> </span><span class="function-syntax">Instrumentation::log_extremes</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">Instrumentation::log_extremes</span></span>:<br/><a href="4-ins.html#SP8">&#167;8</a>, <a href="4-ins.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"[%d, "</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">min_words</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">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_words</span><span class="plain-syntax"> == </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"infinity)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%d]"</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">max_words</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10"></a><b>&#167;10. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Instrumentation::log_production</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">Instrumentation::log_production</span></span>:<br/><a href="4-ins.html#SP9">&#167;9</a><br/>Preform - <a href="4-prf.html#SP1_2">&#167;1.2</a>, <a href="4-prf.html#SP1_2_1">&#167;1.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;empty-production&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP11" class="function-link"><span class="function-syntax">Instrumentation::log_ptoken</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">);</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Instrumentation::log_production_list</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">Instrumentation::log_production_list</span></span>:<br/><a href="4-ins.html#SP8">&#167;8</a></span></button><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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%J:\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">definition_language</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</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">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP11" class="function-link"><span class="function-syntax">Instrumentation::log_production</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">production_tries</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"(hits %d/%d) "</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">production_matches</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">production_tries</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-wrd.html#SP12" class="function-link"><span class="function-syntax">Wordings::nonempty</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">sample_text</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">sample_text</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">8</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"(matched long text) "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"(matched: '%W') "</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">.</span><span class="element-syntax">sample_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"constraint "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_ntic</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</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">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" extremes "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_extremes</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">pr_extremes</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11"></a><b>&#167;11. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Instrumentation::log_ptoken</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">Instrumentation::log_ptoken</span></span>:<br/><a href="4-ins.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Instrumentation::log_production</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">Instrumentation::log_production</span></span>:<br/><a href="4-ins.html#SP10">&#167;10</a><br/>Preform - <a href="4-prf.html#SP1_2">&#167;1.2</a>, <a href="4-prf.html#SP1_2_1">&#167;1.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;empty-production&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">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">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP12" class="function-link"><span class="function-syntax">Instrumentation::log_ptoken</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;12. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Instrumentation::log_ptoken</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">Instrumentation::log_ptoken</span></span>:<br/><a href="4-ins.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"(@%d)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">ptoken_position</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">strut_number</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
@ -228,8 +283,7 @@ matches it.)
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"{"</span><span class="plain-syntax">); </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%d:"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">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">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%V"</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">detailed</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"=%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_index</span><span class="plain-syntax">);</span>
@ -243,7 +297,7 @@ matches it.)
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;12. </b>A less detailed form used in linguistic problem messages:
<p class="commentary firstcommentary"><a id="SP13"></a><b>&#167;13. </b>A less detailed form used in linguistic problem messages:
</p>
<pre class="displayed-code all-displayed-code code-font">
@ -251,8 +305,7 @@ matches it.)
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">disallow_unexpected_upper</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"^"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"{"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">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">-&gt;</span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%V"</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
@ -264,7 +317,7 @@ matches it.)
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-bn.html">&#10094;</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-prf.html">prf</a></li><li class="progresssection"><a href="4-bn.html">bn</a></li><li class="progresscurrent">ins</li><li class="progressnextoff">&#10095;</li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="4-bn.html">&#10094;</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="progresssection"><a href="4-ni.html">ni</a></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="progresscurrent">ins</li><li class="progressnextoff">&#10095;</li></ul></div>
</nav><!--End of weave-->
</main>

217
docs/words-module/4-le.html Normal file
View file

@ -0,0 +1,217 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Length Extremes</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">
</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 'Length Extremes' 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>Length Extremes</b></li></ul></div>
<p class="purpose">To precalculate data which enables rapid parsing of source text against a Preform grammar.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>The "length extremes" system provides one of two optimisations enabling
the Preform parser quickly to reject non-matches, the other being
<a href="4-ni.html" class="internal">Nonterminal Incidences</a>, which is harder 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 &mdash; see <a href="../inform7/M-pm.html" class="internal">Performance Metrics (in inform7)</a>.
</p>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b>The "extremes" of something to be matched against are the minimum and maximum
number of words in a successful match; with <span class="extract"><span class="extract-syntax">INFINITE_WORD_COUNT</span></span> as maximum
where the number is unlimited.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax"> </span><span class="constant-syntax">1000000000</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">min_words</span><span class="plain-syntax">, </span><span class="identifier-syntax">max_words</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure length_extremes is accessed in 4/to, 4/ni, 4/prf, 4/ins and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="function-syntax">LengthExtremes::new</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">LengthExtremes::new</span></span>:<br/>Nonterminals - <a href="4-nnt.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">min</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">max</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">; </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">min</span><span class="plain-syntax">; </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">max</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. </b>Four useful special cases:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="function-syntax">LengthExtremes::no_words_at_all</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">LengthExtremes::no_words_at_all</span></span>:<br/><a href="4-le.html#SP8">&#167;8</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">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">; </span><span class="identifier-syntax">E</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">E</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="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="function-syntax">LengthExtremes::any_number_of_words</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">LengthExtremes::any_number_of_words</span></span>:<br/><a href="4-le.html#SP9">&#167;9</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">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">; </span><span class="identifier-syntax">E</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">E</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="function-syntax">LengthExtremes::at_least_one_word</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">LengthExtremes::at_least_one_word</span></span>:<br/><a href="4-le.html#SP9">&#167;9</a><br/>The Optimiser - <a href="4-to.html#SP2">&#167;2</a>, <a href="4-to.html#SP4">&#167;4</a>, <a href="4-to.html#SP7">&#167;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">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">; </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="function-syntax">LengthExtremes::exactly_one_word</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">LengthExtremes::exactly_one_word</span></span>:<br/><a href="4-le.html#SP9">&#167;9</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">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">; </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5"></a><b>&#167;5. </b>Testing:
</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">LengthExtremes::in_bounds</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">LengthExtremes::in_bounds</span></span>:<br/>Preform - <a href="4-prf.html#SP1">&#167;1</a>, <a href="4-prf.html#SP1_2_1">&#167;1.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">match_length</span><span class="plain-syntax">, </span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</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">match_length</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">match_length</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</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">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="SP6"></a><b>&#167;6. </b>Concatenation produces the length extremes for the text X followed by the
text Y:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="function-syntax">LengthExtremes::concatenate</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">LengthExtremes::concatenate</span></span>:<br/><a href="4-le.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E_X</span><span class="plain-syntax">, </span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E_Y</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">E_X</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</span><span class="plain-syntax"> += </span><span class="identifier-syntax">E_Y</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</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">E</span><span class="plain-syntax">.</span><span class="identifier-syntax">min_words</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">) </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</span><span class="plain-syntax"> += </span><span class="identifier-syntax">E_Y</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</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">E</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">) </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</span><span class="plain-syntax"> = </span><span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7"></a><b>&#167;7. </b>The union provides the wider bounds, whichever they are:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="function-syntax">LengthExtremes::union</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">LengthExtremes::union</span></span>:<br/><a href="4-le.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E_X</span><span class="plain-syntax">, </span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E_Y</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">E_X</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">E_Y</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</span><span class="plain-syntax">) </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">E_Y</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</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">E_Y</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</span><span class="plain-syntax">) </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">E_Y</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_words</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">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. </b>The minimum matched text length for a nonterminal is the smallest of the
minima for its possible productions; for a production, it's the sum of the
minimum match lengths of its tokens.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="function-syntax">LengthExtremes::calculate_for_nt</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">LengthExtremes::calculate_for_nt</span></span>:<br/>The Optimiser - <a href="4-to.html#SP8">&#167;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">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="4-le.html#SP4" class="function-link"><span class="function-syntax">LengthExtremes::no_words_at_all</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">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">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">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">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">pr_extremes</span><span class="plain-syntax"> = </span><a href="4-le.html#SP8" class="function-link"><span class="function-syntax">LengthExtremes::calculate_for_pr</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first</span><span class="plain-syntax">) { </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">pr_extremes</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="reserved-syntax">else</span><span class="plain-syntax"> { </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="4-le.html#SP7" class="function-link"><span class="function-syntax">LengthExtremes::union</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">pr_extremes</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">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="function-syntax">LengthExtremes::calculate_for_pr</span><span class="plain-syntax">(</span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="4-le.html#SP4" class="function-link"><span class="function-syntax">LengthExtremes::no_words_at_all</span></a><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">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="4-le.html#SP6" class="function-link"><span class="function-syntax">LengthExtremes::concatenate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><a href="4-le.html#SP9" class="function-link"><span class="function-syntax">LengthExtremes::calculate_for_pt</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. </b>An interesting point here is that the negation of a ptoken can in principle
have any length, except that we specified <span class="extract"><span class="extract-syntax">^ example</span></span> to match only a single
word &mdash; any word other than "example". So the extremes for <span class="extract"><span class="extract-syntax">^ example</span></span> are
1 and 1, whereas for <span class="extract"><span class="extract-syntax">^ &lt;sample-nonterminal&gt;</span></span> they would have to be 0 and
infinity.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="function-syntax">LengthExtremes::calculate_for_pt</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">LengthExtremes::calculate_for_pt</span></span>:<br/><a href="4-le.html#SP8">&#167;8</a><br/>The Optimiser - <a href="4-to.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="4-le.html#SP4" class="function-link"><span class="function-syntax">LengthExtremes::exactly_one_word</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> != </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="4-le.html#SP4" class="function-link"><span class="function-syntax">LengthExtremes::any_number_of_words</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NONTERMINAL_PTC:</span>
<span class="plain-syntax"> </span><a href="4-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">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">); </span><span class="comment-syntax"> recurse as needed</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_extremes</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MULTIPLE_WILDCARD_PTC:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="4-le.html#SP4" class="function-link"><span class="function-syntax">LengthExtremes::at_least_one_word</span></a><span class="plain-syntax">(); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">POSSIBLY_EMPTY_WILDCARD_PTC:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="4-le.html#SP4" class="function-link"><span class="function-syntax">LengthExtremes::any_number_of_words</span></a><span class="plain-syntax">(); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</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-to.html">&#10094;</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="progresscurrent">le</li><li class="progresssection"><a href="4-ni.html">ni</a></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-ni.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>

View file

@ -196,7 +196,7 @@ has already removed any such.
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"syntax error in Preform declarations"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP1" class="function-link"><span class="function-syntax">Optimiser::optimise_counts</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP7" class="function-link"><span class="function-syntax">Optimiser::optimise_counts</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">declarations</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
@ -293,7 +293,7 @@ independent <a href="4-lp.html#SP8" class="internal">production_list</a> object.
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">production_list</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure production_list is accessed in 4/to, 4/prf, 4/ins and here.</li></ul>
<ul class="endnotetexts"><li>The structure production_list is accessed in 4/to, 4/le, 4/ni, 4/prf, 4/ins and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. </b></p>
<pre class="displayed-code all-displayed-code code-font">
@ -356,7 +356,7 @@ part of them.
<p class="commentary"><a href="4-to.html" class="internal">The Optimiser</a> calculates data on productions just as it does on nonterminals.
For example, it can see that the above can only match a text if it has exactly
3 words, so it sets both <span class="extract"><span class="Preform-extract-syntax">min_pr_words</span></span> and <span class="extract"><span class="Preform-extract-syntax">max_pr_words</span></span> to 3. For the meaning
3 words, so it sets both <span class="extract"><span class="Preform-extract-syntax">pr_extremes.min_words</span></span> and <span class="extract"><span class="Preform-extract-syntax">pr_extremes.max_words</span></span> to 3. For the meaning
of the remaining data, and for what "struts" are, see <a href="4-to.html" class="internal">The Optimiser</a>: it
only confuses the picture here.
</p>
@ -377,7 +377,7 @@ only confuses the picture here.
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">production</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure production is accessed in 4/nnt, 4/to, 4/prf, 4/ins and here.</li></ul>
<ul class="endnotetexts"><li>The structure production is accessed in 4/nnt, 4/to, 4/le, 4/ni, 4/prf, 4/ins and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;12. </b>And at the bottom of God's great chain, the lowly ptoken. Even this can spawn
another list, though: the token <span class="extract"><span class="extract-syntax">fried/green/tomatoes</span></span> is a list of three ptokens
joined by the <span class="extract"><span class="extract-syntax">alternative_ptoken</span></span> links.
@ -419,7 +419,7 @@ the <span class="extract"><span class="extract-syntax">balanced_wildcard</span><
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure ptoken is accessed in 4/nnt, 4/to, 4/prf, 4/ins and here.</li></ul>
<ul class="endnotetexts"><li>The structure ptoken is accessed in 4/nnt, 4/to, 4/le, 4/ni, 4/prf, 4/ins and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP13"></a><b>&#167;13. </b>Each ptoken has a <span class="extract"><span class="extract-syntax">range_starts</span></span> and <span class="extract"><span class="extract-syntax">range_ends</span></span> number. This is either -1,
or marks that the ptoken occurs as the first or last in a range (or both). For
example, in the production
@ -446,7 +446,7 @@ and so on.
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_ranges</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="comment-syntax"> so that they count from 1; range 0 is unused</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP1" class="function-link"><span class="function-syntax">Optimiser::initialise_production_data</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP4" class="function-link"><span class="function-syntax">Optimiser::initialise_production_data</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP5" class="function-link"><span class="function-syntax">Instrumentation::initialise_production_data</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">head</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">tail</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
@ -715,7 +715,7 @@ becomes a fixed word; otherwise it could be any of the five categories.
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">result_index</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_starts</span><span class="plain-syntax"> = -1; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_ends</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP1" class="function-link"><span class="function-syntax">Optimiser::initialise_ptoken_data</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP6" class="function-link"><span class="function-syntax">Optimiser::initialise_ptoken_data</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP7" class="function-link"><span class="function-syntax">Instrumentation::initialise_ptoken_data</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP16">&#167;16</a>.</li></ul>
@ -746,11 +746,11 @@ never returns <span class="extract"><span class="extract-syntax">NULL</span></sp
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> == </span><span class="identifier-syntax">THREEHASHES_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">SINGLE_WILDCARD_PTC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> == </span><span class="identifier-syntax">THREEASTERISKS_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">POSSIBLY_EMPTY_WILDCARD_PTC</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">) </span><a href="4-to.html#SP19" class="function-link"><span class="function-syntax">Optimiser::flag_words</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pc</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">) </span><a href="4-nnt.html#SP13" class="function-link"><span class="function-syntax">Nonterminals::note_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pc</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP16">&#167;16</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-nnt.html">&#10094;</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="progresscurrent">lp</li><li class="progresssection"><a href="4-to.html">to</a></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-to.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="4-nnt.html">&#10094;</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="progresscurrent">lp</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="progresssection"><a href="4-ni.html">ni</a></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-to.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

790
docs/words-module/4-ni.html Normal file
View file

@ -0,0 +1,790 @@
<!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">&#167;1. Introduction</a></li><li><a href="4-ni.html#SP2">&#167;2. Incidence bits</a></li><li><a href="4-ni.html#SP3">&#167;3. The NTI of a word</a></li><li><a href="4-ni.html#SP6">&#167;6. Range requirements</a></li><li><a href="4-ni.html#SP9">&#167;9. Basic range requirements</a></li><li><a href="4-ni.html#SP11">&#167;11. Concatenation of range requirements</a></li><li><a href="4-ni.html#SP17">&#167;17. Disjunction of range requirements</a></li><li><a href="4-ni.html#SP22">&#167;22. Range requirement simplification</a></li><li><a href="4-ni.html#SP25">&#167;25. Calculations</a></li><li><a href="4-ni.html#SP26">&#167;26. Customisation</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;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 &mdash; see <a href="../inform7/M-pm.html" class="internal">Performance Metrics (in inform7)</a>.
</p>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;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 &mdash; see <a href="4-ni.html#SP27" class="internal">NTI::give_nt_reserved_incidence_bit</a>
below &mdash; 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">&#167;3</a>, <a href="4-ni.html#SP10">&#167;10</a>, <a href="4-ni.html#SP28">&#167;28</a><br/>Instrumentation - <a href="4-ins.html#SP8">&#167;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">-&gt;</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">-&gt;</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 &lt;&lt; </span><span class="identifier-syntax">b</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">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>&#167;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
&lt;edwardian-trousers&gt; and &lt;arithmetic-operation&gt;, but no others, then
its NTI would be the incidence bit for &lt;edwardian-trousers&gt; together
with that for &lt;arithmetic-operation&gt;.
</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">&#167;4</a>, <a href="4-ni.html#SP25_1">&#167;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">&#167;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"> &amp; (</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>&#167;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>&#167;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"> &amp;= </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>&#167;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">&lt;recipe&gt;</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">&lt;fish&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;fish&gt;</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">&lt;fish&gt;</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 &lt;fish&gt;, and similarly the word "zinc" &mdash; so neither word has
the incidence bit for &lt;fish&gt; in its NTI. But the Optimiser can also see that
each of the three productions involves &lt;fish&gt; somewhere &mdash; not always in
the same position, but somewhere. It therefore knows that for a wording to
match, one of the words must have the &lt;fish&gt; 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>&#167;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> &mdash; 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>&#167;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">&#167;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">-&gt;</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">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">) | (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">D_set</span><span class="plain-syntax"> = ((</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) | (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">F_set</span><span class="plain-syntax"> = ((</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) | (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">C_set</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">D_set</span><span class="plain-syntax">)) </span><span class="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>&#167;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">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_2"></a><b>&#167;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">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">F_set</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">disj</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">disj</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_3"></a><b>&#167;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">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">F_set</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_4"></a><b>&#167;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">)) &amp;&amp; (</span><span class="identifier-syntax">F_set</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">disj</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">disj</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_5"></a><b>&#167;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">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) != (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((((</span><span class="identifier-syntax">bm</span><span class="plain-syntax">) &amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;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">&#167;25.2.1</a><br/>The Optimiser - <a href="4-to.html#SP2">&#167;2</a>, <a href="4-to.html#SP4">&#167;4</a>, <a href="4-to.html#SP7">&#167;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>&#167;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">&#167;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>&#167;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">&#167;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">-&gt;</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">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-&gt;</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">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-&gt;</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">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-&gt;</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">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-&gt;</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">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-&gt;</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">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;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">&#167;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>&#167;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">&#167;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"> &amp; </span><span class="identifier-syntax">m2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14"></a><b>&#167;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">&#167;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>&#167;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">&#167;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>&#167;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">&#167;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">&#167;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>&#167;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">&#167;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">-&gt;</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">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-&gt;</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">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-&gt;</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">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-&gt;</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">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-&gt;</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">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">X_ntic</span><span class="plain-syntax">-&gt;</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">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y_ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18"></a><b>&#167;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">&#167;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"> &amp; </span><span class="identifier-syntax">m2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19"></a><b>&#167;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">&#167;17</a>, <a href="4-ni.html#SP21">&#167;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"> &amp; </span><span class="identifier-syntax">m2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20"></a><b>&#167;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">&#167;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>&#167;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">&#167;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">&#167;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">&#167;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>&#167;22. Range requirement simplification. </b>Once the bitmaps in all the necessary requirements have been made, the following
is used to simplify them &mdash; 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">&#167;23</a>, <a href="4-ni.html#SP24">&#167;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">-&gt;</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">-&gt;</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">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">DW_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">FS_req</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</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>&#167;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 &mdash; 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">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP22">&#167;22</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP22_2"></a><b>&#167;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">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP22">&#167;22</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP22_3"></a><b>&#167;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">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP22">&#167;22</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP22_4"></a><b>&#167;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">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">) </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP22">&#167;22</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP23"></a><b>&#167;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 &mdash;
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">&#167;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">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DS_req</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">DW_req</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CS_req</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">CW_req</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FS_req</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">FW_req</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ntic</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ditto_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24"></a><b>&#167;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">&#167;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">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">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">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-ni.html#SP23" class="function-link"><span class="function-syntax">NTI::simplify_pair</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</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"> = &amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</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">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</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>&#167;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">&#167;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>&#167;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">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">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">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">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">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">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">-&gt;</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">-&gt;</span><span class="element-syntax">ve_pt</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ni.html#SP25">&#167;25</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP25_2"></a><b>&#167;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">-&gt;</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">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">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">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="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">-&gt;</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">(&amp;</span><span class="identifier-syntax">nnt</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</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">-&gt;</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">&#167;25</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP25_2_1"></a><b>&#167;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">-&gt;</span><span class="element-syntax">first_ptoken</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_ptoken</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">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">(&amp;</span><span class="identifier-syntax">prt</span><span class="plain-syntax">, &amp;</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">-&gt;</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">&#167;25.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP25_2_1_1"></a><b>&#167;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 &lt;if-start-of-paragraph&gt; 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 &lt;wind&gt;, then the atomic NTIC for this word
where it comes up is just a requirement that the word it matches against must
have the &lt;wind&gt; bit. (Which the word "zephyr" certainly does, because we
marked all the words in the &lt;wind&gt; grammar with the &lt;wind&gt; 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">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">NONTERMINAL_PTC</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">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">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">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">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="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">-&gt;</span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">NONTERMINAL_PTC</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><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">-&gt;</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">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</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">&#167;25.2.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26"></a><b>&#167;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">&#167;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>&#167;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
&lt;definite-article&gt; and &lt;indefinite-article&gt; 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"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">b</span><span class="plain-syntax"> &gt;= </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">-&gt;</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 &lt;&lt; </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>&#167;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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&#10094;</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">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>

View file

@ -67,7 +67,7 @@ function togglePopup(material_id) {
<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>Nonterminals</b></li></ul></div>
<p class="purpose">The angle-bracketed terms appearing in Preform grammar.</p>
<ul class="toc"><li><a href="4-nnt.html#SP1">&#167;1. How nonterminals are stored</a></li><li><a href="4-nnt.html#SP9">&#167;9. Word ranges in a nonterminal</a></li><li><a href="4-nnt.html#SP10">&#167;10. Other results</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="4-nnt.html#SP1">&#167;1. How nonterminals are stored</a></li><li><a href="4-nnt.html#SP9">&#167;9. Word ranges in a nonterminal</a></li><li><a href="4-nnt.html#SP10">&#167;10. Other results</a></li><li><a href="4-nnt.html#SP11">&#167;11. Flagging and numbering</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. How nonterminals are stored. </b>Each different nonterminal defined in the <span class="extract"><span class="extract-syntax">Syntax.preform</span></span> code read in,
such as &lt;any-integer&gt;, is going to correspond to a global variable in the
@ -177,10 +177,9 @@ calculate those bounds for itself. <span class="extract"><span class="extract-sy
use the constant <span class="extract"><span class="extract-syntax">INFINITE_WORD_COUNT</span></span> for it.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">INFINITE_WORD_COUNT</span><span class="plain-syntax"> </span><span class="constant-syntax">1000000000</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">INTERNAL_NONTERMINAL</span><span class="plain-syntax">(</span><span class="identifier-syntax">quotedname</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">min</span><span class="plain-syntax">, </span><span class="identifier-syntax">max</span><span class="plain-syntax">)</span>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">INTERNAL_NONTERMINAL</span><span class="plain-syntax">(</span><span class="identifier-syntax">quotedname</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">min</span><span class="plain-syntax">, </span><span class="identifier-syntax">max</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><a href="4-nnt.html#SP8" class="function-link"><span class="function-syntax">Nonterminals::find</span></a><span class="plain-syntax">(</span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">quotedname</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">min</span><span class="plain-syntax">; </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax"> = </span><span class="identifier-syntax">max</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_extremes</span><span class="plain-syntax"> = </span><a href="4-le.html#SP3" class="function-link"><span class="function-syntax">LengthExtremes::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">min</span><span class="plain-syntax">, </span><span class="identifier-syntax">max</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">internal_definition</span><span class="plain-syntax"> = </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">##</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">marked_internal</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
@ -203,6 +202,8 @@ textual name is referred to as an "ID".
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="comment-syntax"> if not internal, this defines it</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">compositor_fn</span><span class="plain-syntax">)(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">r</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> **</span><span class="identifier-syntax">rp</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i_s</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> **</span><span class="identifier-syntax">i_ps</span><span class="plain-syntax">, </span><span class="reserved-syntax">wording</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i_W</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">multiplicitous</span><span class="plain-syntax">; </span><span class="comment-syntax"> if true, matches are alternative syntax tree readings</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">number_words_by_production</span><span class="plain-syntax">; </span><span class="comment-syntax"> this parses names for numbers, like "huit" or "zwei"</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">flag_words_in_production</span><span class="plain-syntax">; </span><span class="comment-syntax"> all words in the production should get these flags</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Storage for most recent correct match</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">range_result</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_RANGES_PER_PRODUCTION</span><span class="plain-syntax">]; </span><span class="comment-syntax"> storage for word ranges matched</span>
@ -213,7 +214,7 @@ textual name is referred to as an "ID".
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure nonterminal is accessed in 4/lp, 4/to, 4/prf, 4/ins and here.</li></ul>
<ul class="endnotetexts"><li>The structure nonterminal is accessed in 4/lp, 4/to, 4/le, 4/ni, 4/prf, 4/ins and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. </b>A few notes on this are in order:
</p>
@ -231,7 +232,9 @@ them up as alternative possible readings of the same text. Ordinarily, the
result of parsing text against a nonterminal is that the first grammar line
matching that text determines the meaning, but for a multiplicitous nonterminal,
every line matching the text determines one of perhaps many possible meanings.
</li><li>(d) The optimisation data helps the parser to reject non-matching text quickly.
</li><li>(d) For numbering and flagging on regular NTs, see <a href="4-nnt.html#SP11" class="internal">Nonterminals::make_numbering</a>
below.
</li><li>(e) The optimisation data helps the parser to reject non-matching text quickly.
For example, if the optimiser can determine that &lt;competitor&gt; only ever matches
texts of between 3 and 7 words in length, it can quickly reject any run of
words outside that range. (However: note that a maximum of 0 means that the
@ -269,11 +272,13 @@ when Preform grammar is parsed, not when Inform text is parsed.
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">compositor_fn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">multiplicitous</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_words_by_production</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> i.e., don't</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">flag_words_in_production</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> i.e., apply no flags</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_RANGES_PER_PRODUCTION</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">range_result</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="constant-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP1" class="function-link"><span class="function-syntax">Optimiser::initialise_nonterminal_data</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP2" class="function-link"><span class="function-syntax">Optimiser::initialise_nonterminal_data</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP2" class="function-link"><span class="function-syntax">Instrumentation::initialise_nonterminal_data</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ins</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>
@ -322,8 +327,48 @@ any single NT.
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">most_recent_result</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> the variable which </span><span class="extract"><span class="extract-syntax">inweb</span></span><span class="comment-syntax"> writes </span><span class="extract"><span class="extract-syntax">&lt;&lt;r&gt;&gt;</span></span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">most_recent_result_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> the variable which </span><span class="extract"><span class="extract-syntax">inweb</span></span><span class="comment-syntax"> writes </span><span class="extract"><span class="extract-syntax">&lt;&lt;rp&gt;&gt;</span></span>
</pre>
<p class="commentary firstcommentary"><a id="SP11"></a><b>&#167;11. Flagging and numbering. </b>The following mechanism arranges for words used in the grammar for a NT to
be given properties just because of that &mdash; either flags or numerical values.
For example, if we wanted the numbers from Stoppard's play "Dogg's Hamlet",
we might have:
</p>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;dogg-numbers&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">sun</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">dock</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">trog</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">slack</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</span>
</pre>
<p class="commentary">And if &lt;dogg-numbers&gt; were made a "numbering" NT, the effect would be that
these five words would pick up the numerical values 1, 2, 3, 4, 5, because
they occur in production number 1, 2, 3, 4, 5 for the NT.
</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">Nonterminals::make_numbering</span><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_words_by_production</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="SP12"></a><b>&#167;12. </b>Similarly, we could flag this NT with <span class="extract"><span class="extract-syntax">NUMBER_MC</span></span>, and then the five words
sun, dock, trog, slack, pan would all pick up the <span class="extract"><span class="extract-syntax">NUMBER_MC</span></span> flag
automatically.
</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">Nonterminals::flag_words_with</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">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">flags</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">flag_words_in_production</span><span class="plain-syntax"> = </span><span class="identifier-syntax">flags</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13"></a><b>&#167;13. </b>This is all done by the following function, which is called when a word <span class="extract"><span class="extract-syntax">ve</span></span>
is read as part of a production with match number <span class="extract"><span class="extract-syntax">pc</span></span> for the nonterminal <span class="extract"><span class="extract-syntax">nt</span></span>:
</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">Nonterminals::note_word</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">Nonterminals::note_word</span></span>:<br/>Loading Preform - <a href="4-lp.html#SP16_3">&#167;16.3</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ve</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">flags</span><span class="plain-syntax"> |= (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">flag_words_in_production</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_words_by_production</span><span class="plain-syntax">) </span><span class="identifier-syntax">ve</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">literal_number_value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-ap.html">&#10094;</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="progresscurrent">nnt</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-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-lp.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="4-ap.html">&#10094;</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="progresscurrent">nnt</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="progresssection"><a href="4-ni.html">ni</a></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-lp.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -110,8 +110,8 @@ only about 6\% of its time here.
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">input_length</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">input_length</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">input_length</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">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><a href="4-le.html#SP5" class="function-link"><span class="function-syntax">LengthExtremes::in_bounds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">input_length</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</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="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP1_2" class="named-paragraph-link"><span class="named-paragraph">Try to match the input text to the nonterminal</span><span class="named-paragraph-number">1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP1_1" class="named-paragraph-link"><span class="named-paragraph">The nonterminal has failed to parse</span><span class="named-paragraph-number">1.1</span></a></span><span class="plain-syntax">;</span>
@ -161,7 +161,7 @@ an internal NT, or try all possible productions for an external one.
<span class="plain-syntax"> </span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">internal_definition</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">voracious</span><span class="plain-syntax">) </span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax">) || (</span><a href="4-to.html#SP5" class="function-link"><span class="function-syntax">Optimiser::nt_bitmap_violates</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax">) || (</span><a href="4-ni.html#SP8" class="function-link"><span class="function-syntax">NTI::nt_bitmap_violates</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_ntic</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">r</span><span class="plain-syntax">, </span><span class="identifier-syntax">Q</span><span class="plain-syntax">; </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">QP</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">r</span><span class="plain-syntax"> = (*(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">internal_definition</span><span class="plain-syntax">))(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">Q</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">QP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> { </span><span class="identifier-syntax">r</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="identifier-syntax">Q</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; }</span>
@ -173,12 +173,12 @@ an internal NT, or try all possible productions for an external one.
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%V: &lt;%W&gt; violates "</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP16" class="function-link"><span class="function-syntax">Optimiser::log_range_requirement</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_ntic</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</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><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax">) || (</span><a href="4-to.html#SP5" class="function-link"><span class="function-syntax">Optimiser::nt_bitmap_violates</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax">) || (</span><a href="4-ni.html#SP8" class="function-link"><span class="function-syntax">NTI::nt_bitmap_violates</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_ntic</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">acc_result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production_list</span><span class="plain-syntax">) {</span>
@ -189,8 +189,8 @@ an internal NT, or try all possible productions for an external one.
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_production</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_production</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">violates</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">unoptimised</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">production_req</span><span class="plain-syntax">.</span><span class="element-syntax">ditto_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">violates</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last_v</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">violates</span><span class="plain-syntax"> = </span><a href="4-to.html#SP5" class="function-link"><span class="function-syntax">Optimiser::nt_bitmap_violates</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">production_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">pr</span><span class="plain-syntax">-&gt;</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="element-syntax">ditto_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">violates</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last_v</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">violates</span><span class="plain-syntax"> = </span><a href="4-ni.html#SP8" class="function-link"><span class="function-syntax">NTI::nt_bitmap_violates</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">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">last_v</span><span class="plain-syntax"> = </span><span class="identifier-syntax">violates</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">violates</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
@ -198,9 +198,9 @@ an internal NT, or try all possible productions for an external one.
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"production in %V: "</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP10" class="function-link"><span class="function-syntax">Instrumentation::log_production</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP11" class="function-link"><span class="function-syntax">Instrumentation::log_production</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">": &lt;%W&gt; violates "</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP16" class="function-link"><span class="function-syntax">Optimiser::log_range_requirement</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">production_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_ntic</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</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">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
@ -214,7 +214,7 @@ an internal NT, or try all possible productions for an external one.
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%V: &lt;%W&gt; violates "</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nonterminal_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-to.html#SP16" class="function-link"><span class="function-syntax">Optimiser::log_range_requirement</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nonterminal_req</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP9" class="function-link"><span class="function-syntax">Instrumentation::log_ntic</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-&gt;</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><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
@ -232,13 +232,13 @@ text against a production.
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ptraci</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP1_2_1_1" class="named-paragraph-link"><span class="named-paragraph">Log the production match number</span><span class="named-paragraph-number">1.2.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP10" class="function-link"><span class="function-syntax">Instrumentation::log_production</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP11" class="function-link"><span class="function-syntax">Instrumentation::log_production</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">slow_scan_needed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">added_to_result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">input_length</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">min_pr_words</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">input_length</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_pr_words</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-le.html#SP5" class="function-link"><span class="function-syntax">LengthExtremes::in_bounds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">input_length</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">pr_extremes</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q</span><span class="plain-syntax">; </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">QP</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP1_2_1_2" class="named-paragraph-link"><span class="named-paragraph">Actually parse the given production, going to Fail if we can't</span><span class="named-paragraph-number">1.2.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-ins.html#SP6" class="function-link"><span class="function-syntax">Instrumentation::note_production_match</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
@ -562,11 +562,11 @@ quick no.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> &gt; </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> &gt; </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">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"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">voracious</span><span class="plain-syntax">) </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">min_nt_words</span><span class="plain-syntax"> == </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> + </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">min_nt_words</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">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"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">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="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">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="plain-syntax"> </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> + </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-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">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prf.html#SP1_2_1_2_3_3_3_1" class="named-paragraph-link"><span class="named-paragraph">Calculate how much to stretch this elastic ptoken</span><span class="named-paragraph-number">1.2.1.2.3.3.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">backtrack_token</span><span class="plain-syntax">) {</span>
@ -592,7 +592,7 @@ quick no.
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax">) </span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><span class="identifier-syntax">q</span><span class="plain-syntax">?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">q</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">FailThisStrutPosition</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wt</span><span class="plain-syntax">+1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">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"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wt</span><span class="plain-syntax">+1;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prf.html#SP1_2_1_2_3_3">&#167;1.2.1.2.3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_2_1_2_3_3_3_1"></a><b>&#167;1.2.1.2.3.3.3.1. </b>How much text from the input should this ptoken match? We feed it as much
@ -628,7 +628,7 @@ probably gives the wrong answer.)
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lookahead</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">strut_number</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spos</span><span class="plain-syntax">[</span><span class="identifier-syntax">lookahead</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">strut_number</span><span class="plain-syntax">]-1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lookahead</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> &amp;&amp; (</span><a href="4-to.html#SP17" class="function-link"><span class="function-syntax">Optimiser::ptoken_width</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">) == </span><span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> &amp;&amp; (</span><a href="4-to.html#SP9" class="function-link"><span class="function-syntax">Optimiser::ptoken_width</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">) == </span><span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wt</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">target</span><span class="plain-syntax"> = </span><span class="identifier-syntax">lookahead</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">save_preform_lookahead_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax">;</span>
@ -674,10 +674,10 @@ last word in the input text.
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><a href="4-prf.html#SP1" class="function-link"><span class="function-syntax">Preform::parse_nt_against_word_range</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">+</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax">-1),</span>
<span class="plain-syntax"> </span><a href="3-wrd.html#SP6" class="function-link"><span class="function-syntax">Wordings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">+</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="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">-1),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax">) </span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><span class="identifier-syntax">q</span><span class="plain-syntax">?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">q</span><span class="plain-syntax">) </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> += </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="identifier-syntax">max_nt_words</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">q</span><span class="plain-syntax">) </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> += </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nt_pt</span><span class="plain-syntax">-&gt;</span><span class="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="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pos</span><span class="plain-syntax">-</span><span class="identifier-syntax">from</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">len</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax">;</span>
@ -703,7 +703,7 @@ last word in the input text.
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-to.html">&#10094;</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="progresscurrent">prf</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-bn.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="4-ni.html">&#10094;</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="progresssection"><a href="4-ni.html">ni</a></li><li class="progresscurrent">prf</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-bn.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

File diff suppressed because it is too large Load diff

View file

@ -114,7 +114,10 @@ would be
following alphabetical list has references to fuller explanations:
</p>
<ul class="items"><li>&#9679; <span class="extract"><span class="extract-syntax">PROBLEM_WORDS_CALLBACK</span></span> is called when a lexical error is found, and can
<ul class="items"><li>&#9679; <span class="extract"><span class="extract-syntax">PREFORM_OPTIMISER_WORDS_CALLBACK</span></span> and <span class="extract"><span class="extract-syntax">FURTHER_PREFORM_OPTIMISER_WORDS_CALLBACK</span></span>
have the opportunity to flag certain Preform nonterminals in ways which will
help <a href="4-to.html" class="internal">The Optimiser</a>.
</li><li>&#9679; <span class="extract"><span class="extract-syntax">PROBLEM_WORDS_CALLBACK</span></span> is called when a lexical error is found, and can
prevent this from being issued to the terminal as an error message: see
<a href="3-lxr.html#SP31" class="internal">Lexer::lexer_problem_handler</a>.
</li></ul>

View file

@ -162,6 +162,16 @@
<spon class="sectiontitle">The Optimiser</span></a> -
<span class="sectionpurpose">To precalculate data which enables rapid parsing of source text against a Preform grammar.</span></p>
</li>
<li>
<p class="sectionentry"><a href="4-le.html">
<spon class="sectiontitle">Length Extremes</span></a> -
<span class="sectionpurpose">To precalculate data which enables rapid parsing of source text against a Preform grammar.</span></p>
</li>
<li>
<p class="sectionentry"><a href="4-ni.html">
<spon class="sectiontitle">Nonterminal Incidences</span></a> -
<span class="sectionpurpose">To work out bitmaps of nonterminal incidences in grammar.</span></p>
</li>
<li>
<p class="sectionentry"><a href="4-prf.html">
<spon class="sectiontitle">Preform</span></a> -

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,28 +1,28 @@
Total memory consumption was 252346K = 246 MB
Total memory consumption was 253146K = 247 MB
61.8% was used for 1313637 objects, in 260355 frames in 195 x 800K = 156000K = 152 MB:
61.9% was used for 1324040 objects, in 262769 frames in 196 x 800K = 156800K = 153 MB:
10.0% inter_tree_node_array 36 x 8192 = 294912 objects, 25953408 bytes
5.6% text_stream_array 2587 x 100 = 258700 objects, 14569984 bytes
3.9% parse_node 127935 objects, 10234800 bytes
4.0% parse_node 130338 objects, 10427040 bytes
2.8% verb_conjugation 160 objects, 7425280 bytes
2.7% parse_node_annotation_array 439 x 500 = 219500 objects, 7038048 bytes
2.7% parse_node_annotation_array 445 x 500 = 222500 objects, 7134240 bytes
2.4% inter_symbol_array 70 x 1024 = 71680 objects, 6310080 bytes
1.4% map_data 778 objects, 3690832 bytes
1.2% pcalc_prop_array 23 x 1000 = 23000 objects, 3312736 bytes
0.9% kind_array 62 x 1000 = 62000 objects, 2481984 bytes
1.3% pcalc_prop_array 24 x 1000 = 24000 objects, 3456768 bytes
1.0% kind_array 65 x 1000 = 65000 objects, 2602080 bytes
0.8% linked_list 3897 objects, 2182320 bytes
0.8% inter_schema_token 14554 objects, 2095776 bytes
0.6% vocabulary_entry_array 161 x 100 = 16100 objects, 1808352 bytes
0.5% match_trie_array 10 x 1000 = 10000 objects, 1360320 bytes
0.4% phrase 940 objects, 1233280 bytes
0.4% ptoken 8318 objects, 1131248 bytes
0.3% adjective_meaning 202 objects, 1001920 bytes
0.3% excerpt_meaning 3161 objects, 986232 bytes
0.3% inter_name_array 20 x 1000 = 20000 objects, 960640 bytes
0.3% inter_package 13201 objects, 950472 bytes
0.3% inter_schema_node 9518 objects, 913728 bytes
0.3% production 3896 objects, 903872 bytes
0.3% ptoken 8318 objects, 865072 bytes
0.3% inter_symbols_table 13201 objects, 844864 bytes
0.3% dictionary 16345 objects, 784560 bytes
0.2% dict_entry_array 236 x 100 = 23600 objects, 762752 bytes
@ -45,7 +45,7 @@ Total memory consumption was 252346K = 246 MB
---- action_pattern_array 6 x 100 = 600 objects, 144192 bytes
---- lexicon_entry 395 objects, 142200 bytes
---- nonterminal 743 objects, 136712 bytes
---- adjective_usage_array 7 x 1000 = 7000 objects, 112224 bytes
---- adjective_usage_array 8 x 1000 = 8000 objects, 128256 bytes
---- documentation_ref 1275 objects, 112200 bytes
---- hierarchy_location 731 objects, 105264 bytes
---- preposition_identity 273 objects, 82992 bytes
@ -202,15 +202,15 @@ Total memory consumption was 252346K = 246 MB
---- kind_template_definition 1 object, 40 bytes
---- parse_name_notice 1 object, 40 bytes
38.1% was used for memory not allocated for objects:
38.0% was used for memory not allocated for objects:
16.2% text stream storage 42036196 bytes in 265087 claims
16.2% text stream storage 42036304 bytes in 265091 claims
3.5% dictionary storage 9265152 bytes in 16345 claims
---- sorting 1240 bytes in 3 claims
---- sorting 1112 bytes in 3 claims
2.7% source text 7200000 bytes in 3 claims
4.1% source text details 10800000 bytes in 2 claims
0.8% inter symbols storage 2276992 bytes in 13911 claims
6.5% inter bytecode storage 16802820 bytes in 14 claims
6.4% inter bytecode storage 16802820 bytes in 14 claims
3.3% inter links storage 8750208 bytes in 246 claims
0.5% instance-of-kind counting 1464100 bytes in 1 claim
---- lists for type-checking invocations 16000 bytes in 1 claim
@ -219,5 +219,5 @@ Total memory consumption was 252346K = 246 MB
---- emitter array storage 14368 bytes in 8 claims
---- code generation workspace for objects 9200 bytes in 9 claims
19.9% was overhead - 51626568 bytes = 50416K = 49 MB
20.1% was overhead - 52143352 bytes = 50921K = 49 MB

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,25 @@
<s-literal> hits 2097/23834 nti 23 constraint (none) extremes [1, infinity)
English:
(@1)<cardinal-number>=1
(hits 171/289) (matched: '100') constraint CS = {r0} extremes [1, 1]
(@1)minus (@2)<cardinal-number>=1
(hits 0/4155) constraint DS = {23} extremes [2, 2]
(@1)<quoted-text>=1 (@2)( (@3)<response-letter>=2 (@4))
(hits 273/4155) (matched: '"[current item from the multiple object list]: [run paragraph on]" ( a )') constraint DS = {23} extremes [4, 4]
(@1)<quoted-text>=1
(hits 1564/11473) (matched: 'Represents geographical locations, both indoor
and outdoor, which are not necessarily areas in a building. A player in one
room is mostly unable to sense, or interact with, anything in a different room.
Rooms are arranged in a map.') constraint (none) extremes [1, 1]
<s-literal-real-number>=1
(hits 11/9909) (matched: 'plus infinity') constraint (none) extremes [1, infinity)
(@1)<s-literal-truth-state>=1
(hits 78/456) (matched: 'false') constraint CS = {17} extremes [1, 1]
<s-literal-list>=1
(hits 0/3430) constraint DS = {19} extremes [2, infinity)
(@1)unicode <s-unicode-character>=1
(hits 0/3878) constraint DS = {23} extremes [2, infinity)
<s-literal-time>=1
(hits 0/4357) constraint DW = {20, 21, 22} extremes [2, 5]
<s-literal-unit-notation>=1
(hits 0/9820) constraint (none) extremes [1, infinity)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,13 @@
100.0% in inform7 run
73.1% in compilation to Inter
28.5% in //Phrases::Manager::compile_first_block//
9.6% in //Phrases::Manager::compile_as_needed//
7.5% in //Strings::compile_responses//
6.9% in //World::Compile::compile//
3.4% in //Assertions::Traverse::traverse1//
3.0% in //Sentences::VPs::traverse//
2.3% in //Phrases::Manager::RulePrintingRule_routine//
2.1% in //Phrases::Manager::rulebooks_array//
67.2% in compilation to Inter
26.7% in //Phrases::Manager::compile_first_block//
8.6% in //Phrases::Manager::compile_as_needed//
6.8% in //Strings::compile_responses//
6.2% in //World::Compile::compile//
3.3% in //Assertions::Traverse::traverse1//
2.9% in //Sentences::VPs::traverse//
2.0% in //Phrases::Manager::RulePrintingRule_routine//
1.8% in //Phrases::Manager::rulebooks_array//
1.1% in //NewVerbs::ConjugateVerb//
0.7% in //Phrases::Manager::traverse//
0.5% in //Phrases::Manager::parse_rule_parameters//
@ -20,18 +20,18 @@
0.1% in //Sentences::RuleSubtrees::register_recently_lexed_phrases//
0.1% in //Task::load_types//
0.1% in //World::complete//
4.6% not specifically accounted for
24.3% in running Inter pipeline
10.8% in inter step 2/12: link
9.4% in inter step 12/12: generate inform6 -> auto.inf
4.1% not specifically accounted for
30.5% in running Inter pipeline
9.9% in step preparation
9.7% in inter step 2/12: link
6.9% in inter step 12/12: generate inform6 -> auto.inf
0.3% in inter step 9/12: make-identifiers-unique
0.1% in inter step 10/12: reconcile-verbs
0.1% in inter step 11/12: eliminate-redundant-labels
0.1% in inter step 4/12: parse-linked-matter
0.1% in inter step 5/12: resolve-conditional-compilation
0.1% in inter step 6/12: assimilate
0.1% in inter step 7/12: resolve-external-symbols
0.1% in inter step 8/12: inspect-plugs
2.3% not specifically accounted for
2.3% in supervisor
2.4% not specifically accounted for
2.0% in supervisor
0.2% not specifically accounted for

View file

@ -24,3 +24,27 @@ Entries with a dash instead of a percentage are negligible, in that they
represent less than 1/1000th of the total.
= (undisplayed text from Figures/memory-diagnostics.txt)
@h Preform grammar.
The full annotated description of the Preform grammar (see //words: About Preform//),
with optimisation details and hit/miss statistics added, is also long: it's
roughly 10,000 lines of text, so we won't quote it in full here. This is a
sample, showing the nonterminal used to parse literals in Inform 7 source text:
= (undisplayed text from Figures/preform-summary.txt)
The unabridged grammar is here:
= (download preform-diagnostics.txt "Preform diagnostics file")
@h Syntax tree.
A full printout of the syntax tree (see //syntax: What This Module Does//)
is a roughly 20,000-line text file, and again is too long to quote in full.
This is a summary, showing just the portion of tree from the main source text,
that is, with extensions and with the content of |ROUTINE_NT| nodes omitted:
= (undisplayed text from Figures/syntax-summary.txt)
The unabridged tree is here:
= (download syntax-diagnostics.txt "Complete syntax tree")

View file

@ -141,8 +141,12 @@ they can be rather lengthy.
I"memory-diagnostics.txt", &Memory::log_statistics);
CoreMain::write_diagnostics(
I"syntax-diagnostics.txt", &CoreMain::log_task_syntax_tree);
CoreMain::write_diagnostics(
I"syntax-summary.txt", &CoreMain::log_task_syntax_summary);
CoreMain::write_diagnostics(
I"preform-diagnostics.txt", &Instrumentation::log);
CoreMain::write_diagnostics(
I"preform-summary.txt", &CoreMain::log_preform_summary);
CoreMain::write_diagnostics(
I"documentation-diagnostics.txt", &Index::DocReferences::log_statistics);
CoreMain::write_diagnostics(
@ -174,6 +178,14 @@ void CoreMain::log_task_syntax_tree(void) {
Node::log_tree(DL, Task::syntax_tree()->root_node);
}
void CoreMain::log_preform_summary(void) {
Instrumentation::log_nt(<s-literal>, TRUE);
}
void CoreMain::log_task_syntax_summary(void) {
Node::summarise_tree(DL, Task::syntax_tree()->root_node);
}
void CoreMain::log_stopwatch(void) {
Time::log_timing(inform7_timer, inform7_timer->time_taken);
}

View file

@ -609,7 +609,7 @@ blind eye to singular vs plural.
int which_N = -1; quantifier *quantifier_used = NULL;
int x1 = Quantifiers::parse_against_text(W, &which_N, &quantifier_used);
if (x1 >= 0) {
if ((x1<Wordings::last_wn(W)) && (Optimiser::test_word(x1, <article>))) x1++;
if ((x1<Wordings::last_wn(W)) && (NTI::test_word(x1, <article>))) x1++;
parse_node *qp = Specifications::new_UNKNOWN(Wordings::up_to(W, x1-1));
Node::set_quant(qp, quantifier_used);
Annotations::write_int(qp, quantification_parameter_ANNOT, which_N);

View file

@ -209,7 +209,7 @@ int Phrases::Adjectives::vet_name(wording W) {
return FALSE;
}
LOOP_THROUGH_WORDING(n, W)
Optimiser::mark_word(n, <s-adjective>);
NTI::mark_word(n, <s-adjective>);
return TRUE;
}

View file

@ -213,25 +213,25 @@ void Semantics::read_preform(inform_language *L) {
}
@<Mark certain nonterminals to have their vocabularies numbered and flagged@> =
Optimiser::give_nt_reserved_incidence_bit(<s-adjective>, 3);
Optimiser::give_nt_reserved_incidence_bit(<s-instance-name>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-kind>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-kind-of-kind>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-base-kind>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-kind-construction>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-kind-variable-texts>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-kind-variable>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-formal-kind-variable>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-irregular-kind-construction>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-variable-definition>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-single-material>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-optional-material>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-tupled-material>, 5);
Optimiser::give_nt_reserved_incidence_bit(<k-tuple-list>, 5);
NTI::give_nt_reserved_incidence_bit(<s-adjective>, ADJECTIVE_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<s-instance-name>, PROPER_NOUN_RES_NT_BIT /* COMMON_NOUN_RES_NT_BIT */ );
NTI::give_nt_reserved_incidence_bit(<k-kind>, COMMON_NOUN_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<k-kind-of-kind>, COMMON_NOUN_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<k-base-kind>, COMMON_NOUN_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<k-kind-construction>, COMMON_NOUN_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<k-kind-variable-texts>, COMMON_NOUN_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<k-kind-variable>, COMMON_NOUN_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<k-formal-kind-variable>, COMMON_NOUN_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<k-irregular-kind-construction>, COMMON_NOUN_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<k-variable-definition>, COMMON_NOUN_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<k-single-material>, COMMON_NOUN_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<k-optional-material>, COMMON_NOUN_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<k-tupled-material>, COMMON_NOUN_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<k-tuple-list>, COMMON_NOUN_RES_NT_BIT);
@ =
void Semantics::mark_preform_requirements(void) {
Optimiser::mark_nt_as_requiring_itself_conj(<s-adjective>);
NTI::every_word_in_match_must_have_my_NTI_bit(<s-adjective>);
Semantics::mark_nt_as_requiring_itself_articled(<s-instance-name>);
Semantics::mark_nt_as_requiring_itself_articled(<k-kind-variable>);
Semantics::mark_nt_as_requiring_itself_articled(<k-formal-kind-variable>);
@ -245,5 +245,6 @@ void Semantics::break_preform_circularities(nonterminal *nt) {
}
void Semantics::mark_nt_as_requiring_itself_articled(nonterminal *nt) {
Optimiser::mark_nt_as_requiring_itself_augmented(nt, Optimiser::nt_incidence_bit(<article>));
NTI::every_word_in_match_must_have_my_NTI_bit_or_this_one(nt,
NTI::nt_incidence_bit(<article>));
}

View file

@ -410,13 +410,19 @@ int ParseTreeUsage::allow_in_assertions(parse_node *p) {
@
@d PARSE_TREE_LOGGER ParseTreeUsage::log_node
@d PARSE_TREE_LOGGER_SYNTAX_CALLBACK ParseTreeUsage::log_node
=
void ParseTreeUsage::log_node(OUTPUT_STREAM, parse_node *pn) {
if (Node::get_meaning(pn)) WRITE("$M", Node::get_meaning(pn));
else WRITE("$N", pn->node_type);
if (Wordings::nonempty(Node::get_text(pn))) WRITE("'%W'", Node::get_text(pn));
if (Wordings::nonempty(Node::get_text(pn))) {
TEMPORARY_TEXT(text);
WRITE_TO(text, "%W", Node::get_text(pn));
Str::truncate(text, 60);
WRITE("'%S'", text);
DISCARD_TEXT(text);
}
if ((pn->node_type >= UNKNOWN_NT) && (pn->node_type <= TEST_VALUE_NT))
@<Log annotations of specification nodes@>

View file

@ -874,7 +874,7 @@ void Kinds::Interpreter::apply_kind_command(parse_node_tree *T, single_kind_comm
int i;
for (i=0; i<length; i++) {
Vocabulary::set_flags(array[i], KIND_SLOW_MC);
Optimiser::mark_vocabulary(array[i], <k-kind>);
NTI::mark_vocabulary(array[i], <k-kind>);
}
if (con->group != PROPER_CONSTRUCTOR_GRP) {
vocabulary_entry *ve = WordAssemblages::hyphenated(&(stc.vocabulary_argument));

View file

@ -790,7 +790,7 @@ kind *Kinds::read_kind_marking_from_vocabulary(vocabulary_entry *ve) {
void Kinds::mark_vocabulary_as_kind(vocabulary_entry *ve, kind *K) {
ve->means.one_word_kind = K;
Vocabulary::set_flags(ve, KIND_FAST_MC);
Optimiser::mark_vocabulary(ve, <k-kind>);
NTI::mark_vocabulary(ve, <k-kind>);
}
@h From context.

View file

@ -124,9 +124,13 @@ initialises, it calls the following routine to improve its performance.
@d FURTHER_PREFORM_OPTIMISER_WORDS_CALLBACK LinguisticsModule::preform_optimiser
=
int first_round_of_nt_optimisation_made = FALSE;
void LinguisticsModule::preform_optimiser(void) {
Cardinals::preform_optimiser();
VerbUsages::preform_optimiser();
Prepositions::preform_optimiser();
Quantifiers::make_built_in();
if (first_round_of_nt_optimisation_made == FALSE) {
first_round_of_nt_optimisation_made = TRUE;
Quantifiers::make_built_in();
}
}

View file

@ -375,7 +375,7 @@ object "Gregory the Great".
LOG("Logging meaning: $M with hash %08x\n", em, em->excerpt_hash);
internal_error("# in registration of subset meaning");
}
if (Optimiser::test_vocabulary(v, <article>)) continue;
if (NTI::test_vocabulary(v, <article>)) continue;
parse_node *p = ExcerptMeanings::new_em_pnode(em);
p->next_alternative = v->means.subset_list;
v->means.subset_list = p;
@ -437,10 +437,10 @@ excerpt_meaning *ExcerptMeanings::register(
#ifdef CORE_MODULE
if (meaning_code == NOUN_MC)
LOOP_THROUGH_WORDING(i, W)
Optimiser::mark_word(i, <s-instance-name>);
NTI::mark_word(i, <s-instance-name>);
if (meaning_code == KIND_SLOW_MC)
LOOP_THROUGH_WORDING(i, W)
Optimiser::mark_word(i, <k-kind>);
NTI::mark_word(i, <k-kind>);
#endif
excerpt_meaning *em = ExcerptMeanings::new(meaning_code, data);
@ -469,7 +469,7 @@ text substitutions need to distinguish (for instance) "say [the X]" from
@<Unless this is parametrised, skip any initial article@> =
if ((meaning_code & PARAMETRISED_PARSING_BITMAP) == 0)
if (Optimiser::test_word(Wordings::first_wn(W), <article>)) {
if (NTI::test_word(Wordings::first_wn(W), <article>)) {
W = Wordings::trim_first_word(W);
if (Wordings::empty(W))
internal_error("registered a meaning which was only an article");

View file

@ -431,7 +431,7 @@ abbreviated form of an object name like "Chamber 11".
LOOP_THROUGH_WORDING(i, W) {
vocabulary_entry *v = Lexer::word(i);
if (v == NULL) internal_error("Unidentified word when parsing");
if (Optimiser::test_vocabulary(v, <article>)) continue;
if (NTI::test_vocabulary(v, <article>)) continue;
if (v->means.subset_list_length == 0) goto SubsetFailed;
if (v->means.subset_list_length > j) { j = v->means.subset_list_length; k = i; }
}

View file

@ -78,7 +78,7 @@ adjectival_phrase *Adjectives::from_word_range(wording W, NATURAL_LANGUAGE_WORDS
ExcerptMeanings::register(ADJECTIVE_MC,
W, STORE_POINTER_adjectival_phrase(aph));
LOOP_THROUGH_WORDING(n, W)
Optimiser::mark_word(n, <adjective-name>);
NTI::mark_word(n, <adjective-name>);
#ifdef ADJECTIVE_NAME_VETTING
}
#endif

View file

@ -125,9 +125,10 @@ is never treated as a participle.
@h Marking for Preform efficiency.
=
void Articles::mark_for_preform(void) {
Optimiser::give_nt_reserved_incidence_bit(<article>, 2);
Optimiser::give_nt_reserved_incidence_bit(<definite-article>, 2);
Optimiser::give_nt_reserved_incidence_bit(<indefinite-article>, 2);
NTI::give_nt_reserved_incidence_bit(<article>, ARTICLE_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<definite-article>, ARTICLE_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<indefinite-article>, ARTICLE_RES_NT_BIT);
}

View file

@ -50,8 +50,8 @@ numbers.
=
void Cardinals::preform_optimiser(void) {
Optimiser::mark_nt_as_requiring_itself_conj(<cardinal-number>);
Optimiser::mark_nt_as_requiring_itself_conj(<ordinal-number>);
NTI::every_word_in_match_must_have_my_NTI_bit(<cardinal-number>);
NTI::every_word_in_match_must_have_my_NTI_bit(<ordinal-number>);
for (int wn = 0; wn < lexer_wordcount; wn++) {
if (Vocabulary::test_flags(wn, NUMBER_MC))
Cardinals::mark_as_cardinal(Lexer::word(wn));
@ -61,22 +61,22 @@ void Cardinals::preform_optimiser(void) {
}
void Cardinals::mark_as_cardinal(vocabulary_entry *ve) {
Optimiser::mark_vocabulary(ve, <cardinal-number>);
NTI::mark_vocabulary(ve, <cardinal-number>);
}
void Cardinals::mark_as_ordinal(vocabulary_entry *ve) {
Optimiser::mark_vocabulary(ve, <ordinal-number>);
NTI::mark_vocabulary(ve, <ordinal-number>);
}
void Cardinals::enable_in_word_form(void) {
Optimiser::give_nt_reserved_incidence_bit(<cardinal-number>, 0);
Optimiser::give_nt_reserved_incidence_bit(<ordinal-number>, 1);
NTI::give_nt_reserved_incidence_bit(<cardinal-number>, CARDINAL_RES_NT_BIT);
NTI::give_nt_reserved_incidence_bit(<ordinal-number>, ORDINAL_RES_NT_BIT);
<cardinal-number-in-words>->opt.number_words_by_production = TRUE;
<cardinal-number-in-words>->opt.flag_words_in_production = NUMBER_MC;
Nonterminals::make_numbering(<cardinal-number-in-words>);
Nonterminals::flag_words_with(<cardinal-number-in-words>, NUMBER_MC);
<ordinal-number-in-words>->opt.number_words_by_production = TRUE;
<ordinal-number-in-words>->opt.flag_words_in_production = ORDINAL_MC;
Nonterminals::make_numbering(<ordinal-number-in-words>);
Nonterminals::flag_words_with(<ordinal-number-in-words>, ORDINAL_MC);
}
@ Actual parsing is done here. We look at a single word to see if it's a

View file

@ -156,18 +156,18 @@ with a given "permitted verb".
@ =
void Prepositions::mark_for_preform(void) {
<relative-clause-marker>->opt.flag_words_in_production = PREPOSITION_MC;
Nonterminals::flag_words_with(<relative-clause-marker>, PREPOSITION_MC);
}
void Prepositions::preform_optimiser(void) {
Optimiser::mark_nt_as_requiring_itself(<preposition>);
Optimiser::mark_nt_as_requiring_itself(<copular-preposition>);
Optimiser::mark_nt_as_requiring_itself(<permitted-preposition>);
NTI::one_word_in_match_must_have_my_NTI_bit(<preposition>);
NTI::one_word_in_match_must_have_my_NTI_bit(<copular-preposition>);
NTI::one_word_in_match_must_have_my_NTI_bit(<permitted-preposition>);
}
void Prepositions::mark_as_preposition(vocabulary_entry *ve) {
Vocabulary::set_flags(ve, PREPOSITION_MC);
Optimiser::mark_vocabulary(ve, <preposition>);
Optimiser::mark_vocabulary(ve, <copular-preposition>);
Optimiser::mark_vocabulary(ve, <permitted-preposition>);
NTI::mark_vocabulary(ve, <preposition>);
NTI::mark_vocabulary(ve, <copular-preposition>);
NTI::mark_vocabulary(ve, <permitted-preposition>);
}

View file

@ -600,21 +600,21 @@ or "the verb to be able to see" use these.
=
void VerbUsages::mark_as_verb(vocabulary_entry *ve) {
Optimiser::mark_vocabulary(ve, <meaningful-nonimperative-verb>);
Optimiser::mark_vocabulary(ve, <copular-verb>);
Optimiser::mark_vocabulary(ve, <negated-noncopular-verb-present>);
Optimiser::mark_vocabulary(ve, <universal-verb>);
Optimiser::mark_vocabulary(ve, <negated-verb>);
Optimiser::mark_vocabulary(ve, <past-tense-verb>);
NTI::mark_vocabulary(ve, <meaningful-nonimperative-verb>);
NTI::mark_vocabulary(ve, <copular-verb>);
NTI::mark_vocabulary(ve, <negated-noncopular-verb-present>);
NTI::mark_vocabulary(ve, <universal-verb>);
NTI::mark_vocabulary(ve, <negated-verb>);
NTI::mark_vocabulary(ve, <past-tense-verb>);
}
void VerbUsages::preform_optimiser(void) {
Optimiser::mark_nt_as_requiring_itself_first(<meaningful-nonimperative-verb>);
Optimiser::mark_nt_as_requiring_itself_first(<copular-verb>);
Optimiser::mark_nt_as_requiring_itself_first(<negated-noncopular-verb-present>);
Optimiser::mark_nt_as_requiring_itself_first(<universal-verb>);
Optimiser::mark_nt_as_requiring_itself_first(<negated-verb>);
Optimiser::mark_nt_as_requiring_itself_first(<past-tense-verb>);
NTI::first_word_in_match_must_have_my_NTI_bit(<meaningful-nonimperative-verb>);
NTI::first_word_in_match_must_have_my_NTI_bit(<copular-verb>);
NTI::first_word_in_match_must_have_my_NTI_bit(<negated-noncopular-verb-present>);
NTI::first_word_in_match_must_have_my_NTI_bit(<universal-verb>);
NTI::first_word_in_match_must_have_my_NTI_bit(<negated-verb>);
NTI::first_word_in_match_must_have_my_NTI_bit(<past-tense-verb>);
}
@h Adaptive person.

View file

@ -183,7 +183,7 @@ since non-zero-ness in the viability map is used only to speed up parsing.
if ((Lexer::word(pos) == CLOSEBRACKET_V) || (Lexer::word(pos) == CLOSEBRACE_V)) bl--;
int i = pos - Wordings::first_wn(W);
if (i >= VIABILITY_MAP_SIZE) break;
if (Optimiser::test_vocabulary(Lexer::word(pos), <meaningful-nonimperative-verb>) == FALSE) viable[i] = 0;
if (NTI::test_vocabulary(Lexer::word(pos), <meaningful-nonimperative-verb>) == FALSE) viable[i] = 0;
else {
if (bl == 0) viable[i] = 1; else viable[i] = 2;
int pos_to = -(<negated-noncopular-verb-present>(Wordings::from(W, pos)));

View file

@ -262,7 +262,7 @@ void CodeGen::Pipeline::run(pathname *P, codegen_pipeline *S, linked_list *PP,
inter_tree *I = S->repositories[step->repository_argument];
if (I == NULL) internal_error("no repository");
CodeGen::Pipeline::prepare_to_run(I);
// CodeGen::Pipeline::lint(I);
CodeGen::Pipeline::lint(I);
CodeGen::Pipeline::clean_step(step);
step->the_PP = PP;

View file

@ -418,6 +418,10 @@ docs/units.html: docs-src/units.inweb docs-src/navu.html
forceprepages:
rm -f docs/*.html
$(INTESTX) inform7 GenerateDiagnostics-G
cp -f inform7/Figures/syntax-diagnostics.txt inform7/Downloads/syntax-diagnostics.txt
rm -f inform7/Figures/syntax-diagnostics.txt
cp -f inform7/Figures/preform-diagnostics.txt inform7/Downloads/preform-diagnostics.txt
rm -f inform7/Figures/preform-diagnostics.txt
$(INWEBX) -colony $(COLONY) -member overview -weave
$(INWEBX) -colony $(COLONY) -member compiler -weave
$(INWEBX) -colony $(COLONY) -member extensions -weave

View file

@ -231,7 +231,15 @@ logging is a diagnostic tool, we want it to work even when Inform is sick.
void Node::log_tree(OUTPUT_STREAM, void *vpn) {
parse_node *pn = (parse_node *) vpn;
if (pn == NULL) { WRITE("<null-meaning-list>\n"); return; }
Node::log_subtree_recursively(OUT, pn, 0, 0, 1, SyntaxTree::new_traverse_token());
Node::log_subtree_recursively(OUT, pn, 0, 0, 1, FALSE,
SyntaxTree::new_traverse_token());
}
void Node::summarise_tree(OUTPUT_STREAM, void *vpn) {
parse_node *pn = (parse_node *) vpn;
if (pn == NULL) { WRITE("<null-meaning-list>\n"); return; }
Node::log_subtree_recursively(OUT, pn, 0, 0, 1, TRUE,
SyntaxTree::new_traverse_token());
}
void Node::log_subtree(OUTPUT_STREAM, void *vpn) {
@ -240,7 +248,8 @@ void Node::log_subtree(OUTPUT_STREAM, void *vpn) {
WRITE("$P\n", pn);
if (pn->down) {
LOG_INDENT;
Node::log_subtree_recursively(OUT, pn->down, 0, 0, 1, ++pn_log_token);
Node::log_subtree_recursively(OUT, pn->down, 0, 0, 1, FALSE,
SyntaxTree::new_traverse_token());
LOG_OUTDENT;
}
}
@ -251,7 +260,8 @@ sentences or so will exceed the typical stack size Inform has to run in.
=
void Node::log_subtree_recursively(OUTPUT_STREAM, parse_node *pn, int num,
int of, int gen, int traverse_token) {
int of, int gen, int summarise, int traverse_token) {
int active = TRUE;
while (pn) {
if (pn->last_seen_on_traverse == traverse_token) {
WRITE("*** Not a tree: %W ***\n", Node::get_text(pn)); return;
@ -260,18 +270,33 @@ void Node::log_subtree_recursively(OUTPUT_STREAM, parse_node *pn, int num,
@<Calculate num and of such that this is [num/of] if they aren't already supplied@>;
if (pn == NULL) { WRITE("<null-parse-node>\n"); return; }
if (of > 1) {
WRITE("[%d/%d] ", num, of);
if (Node::get_score(pn) != 0) WRITE("(score %d) ", Node::get_score(pn));
if (summarise) {
if (Node::is(pn, ENDHERE_NT)) active = TRUE;
}
WRITE("$P\n", pn);
if (pn->down) {
LOG_INDENT;
Node::log_subtree_recursively(OUT, pn->down, 0, 0, gen+1, traverse_token);
LOG_OUTDENT;
if (active) {
if (of > 1) {
WRITE("[%d/%d] ", num, of);
if (Node::get_score(pn) != 0) WRITE("(score %d) ", Node::get_score(pn));
}
WRITE("$P\n", pn);
if (pn->down) {
LOG_INDENT;
int recurse = TRUE;
if ((summarise) && (Node::is(pn, ROUTINE_NT))) recurse = FALSE;
if (recurse)
Node::log_subtree_recursively(OUT,
pn->down, 0, 0, gen+1, summarise, traverse_token);
LOG_OUTDENT;
}
if (pn->next_alternative) Node::log_subtree_recursively(OUT,
pn->next_alternative, num+1, of, gen+1, summarise, traverse_token);
}
if (summarise) {
if (Node::is(pn, BEGINHERE_NT)) {
active = FALSE;
LOG("...\n");
}
}
if (pn->next_alternative) Node::log_subtree_recursively(OUT,
pn->next_alternative, num+1, of, gen+1, traverse_token);
pn = pn->next; num = 0; of = 0; gen++;
}
@ -298,11 +323,17 @@ text in the debugging log.
void Node::log_node(OUTPUT_STREAM, void *vpn) {
parse_node *pn = (parse_node *) vpn;
if (pn == NULL) { WRITE("<null-parse-node>\n"); return; }
#ifdef PARSE_TREE_LOGGER
PARSE_TREE_LOGGER(OUT, pn);
#ifdef PARSE_TREE_LOGGER_SYNTAX_CALLBACK
PARSE_TREE_LOGGER_SYNTAX_CALLBACK(OUT, pn);
#else
NodeType::log(OUT, (int) pn->node_type);
if (Wordings::nonempty(Node::get_text(pn))) WRITE("'%W'", Node::get_text(pn));
if (Wordings::nonempty(Node::get_text(pn))) {
TEMPORARY_TEXT(text);
WRITE_TO(text, "%W", Node::get_text(pn));
Str::truncate(text, 60);
WRITE("'%S'", text);
DISCARD_TEXT(text);
}
#ifdef LINGUISTICS_MODULE
Diagrams::log_node(OUT, pn);
#endif

View file

@ -91,26 +91,6 @@ pop the bud stack until we're beneath a heading node superior to Parts.
T->bud_parent_sp = i;
}
@ In earlier times Inform had a mechanism for dumping whole syntax trees to a
file, for testing purposes. This is no longer used, but the code remains in
this function in case ever needed again. (We go through a shabby trick to make
that file temporarily the debugging log stream |DL|.)
=
void SyntaxTree::write_to_file(parse_node_tree *T, filename *F) {
text_stream parse_tree_file;
if (STREAM_OPEN_TO_FILE(&parse_tree_file, F, ISO_ENC) == FALSE)
internal_error("can't open file to write parse tree");
text_stream *save_DL = DL;
DL = &parse_tree_file;
Streams::enable_debugging(DL);
Node::log_tree(DL, T->root_node);
DL = save_DL;
STREAM_CLOSE(&parse_tree_file);
}
@ Syntax trees for Inform source text have a tendency to be wide. If a source
text is basically a list of 5000 sentences, then there may be a node with 5000
children, even though the maximum depth of the tree might be as low as 10.

View file

@ -101,6 +101,9 @@ which nodes in a syntax tree can be parents of which other nodes: see
and |EVEN_MORE_PARENTAGE_PERMISSIONS_SYNTAX_CALLBACK| adds permissions for nodes
to be parents of each other: see //NodeType::make_parentage_allowed_table//.
(*) |PARSE_TREE_LOGGER_SYNTAX_CALLBACK| provides an alternative way to log
an individual node, i.e., to the debugging log.
(*) |PROBLEM_SYNTAX_CALLBACK| is called when a syntax error is found, and can
prevent this from being issued to the terminal as an error message: see
//Sentences::syntax_problem//.

View file

@ -259,7 +259,7 @@ unsigned int Vocabulary::disjunction_of_flags(wording W) {
}
@ We also leave space for a bitmap used by //The Optimiser//: in particular,
see //Optimiser::mark_vocabulary//.
see //NTI::mark_vocabulary//.
=
void Vocabulary::set_nti(vocabulary_entry *ve, int R) {

View file

@ -94,39 +94,92 @@ void Instrumentation::log(void) {
int detailed = FALSE;
nonterminal *nt;
LOOP_OVER(nt, nonterminal) {
LOG("%d/%d: ", nt->ins.nonterminal_matches, nt->ins.nonterminal_tries);
LOG("%V: ", nt->nonterminal_id);
Optimiser::log_range_requirement(&(nt->opt.nonterminal_req));
Instrumentation::log_nt(nt, detailed);
LOG("\n");
if (nt->internal_definition)
LOG(" (internal)\n");
else
for (production_list *pl = nt->first_production_list; pl;
pl = pl->next_production_list)
Instrumentation::log_production_list(pl, detailed);
LOG(" min %d, max %d\n\n", nt->opt.min_nt_words, nt->opt.max_nt_words);
}
}
void Instrumentation::log_nt(nonterminal *nt, int detailed) {
LOG("%V ", nt->nonterminal_id);
if (nt->marked_internal) LOG("internal ");
if (nt->ins.nonterminal_tries > 0)
LOG("hits %d/%d ", nt->ins.nonterminal_matches, nt->ins.nonterminal_tries);
LOG("nti "); Instrumentation::log_bit(NTI::nt_incidence_bit(nt));
LOG(" constraint "); Instrumentation::log_ntic(&(nt->opt.nt_ntic));
LOG(" extremes ");
Instrumentation::log_extremes(&(nt->opt.nt_extremes));
LOG("\n");
LOG_INDENT;
for (production_list *pl = nt->first_production_list; pl;
pl = pl->next_production_list)
Instrumentation::log_production_list(pl, detailed);
LOG_OUTDENT;
}
@ =
void Instrumentation::log_ntic(nti_constraint *ntic) {
int c = 0;
if (ntic->DW_req) { if (c++ > 0) LOG(" & "); LOG("DW = "); Instrumentation::log_bitmap(ntic->DW_req); }
if (ntic->DS_req) { if (c++ > 0) LOG(" & "); LOG("DS = "); Instrumentation::log_bitmap(ntic->DS_req); }
if (ntic->CW_req) { if (c++ > 0) LOG(" & "); LOG("CW = "); Instrumentation::log_bitmap(ntic->CW_req); }
if (ntic->CS_req) { if (c++ > 0) LOG(" & "); LOG("CS = "); Instrumentation::log_bitmap(ntic->CS_req); }
if (ntic->FW_req) { if (c++ > 0) LOG(" & "); LOG("FW = "); Instrumentation::log_bitmap(ntic->FW_req); }
if (ntic->FS_req) { if (c++ > 0) LOG(" & "); LOG("FS = "); Instrumentation::log_bitmap(ntic->FS_req); }
if (c == 0) LOG("(none)");
}
void Instrumentation::log_bitmap(int bm) {
LOG("{");
int c = 0;
for (int i=0; i<32; i++) {
int b = 1 << i;
if (bm & b) {
if (c++ > 0) LOG(", ");
Instrumentation::log_bit(b);
}
}
LOG("}");
}
void Instrumentation::log_bit(int b) {
for (int i=0; i<32; i++) if (b == (1 << i)) {
if (i < RESERVED_NT_BITS) LOG("r");
LOG("%d", i);
}
}
void Instrumentation::log_extremes(length_extremes *E) {
LOG("[%d, ", E->min_words);
if (E->max_words == INFINITE_WORD_COUNT) LOG("infinity)");
else LOG("%d]", E->max_words);
}
@ =
void Instrumentation::log_production_list(production_list *pl, int detailed) {
LOG(" %J:\n", pl->definition_language);
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
LOG(" "); Instrumentation::log_production(pr, detailed);
LOG(" %d/%d: ", pr->ins.production_matches, pr->ins.production_tries);
if (Wordings::nonempty(pr->ins.sample_text)) LOG("<%W>", pr->ins.sample_text);
LOG(" ==> ");
Optimiser::log_range_requirement(&(pr->opt.production_req));
LOG("%J:\n", pl->definition_language);
LOG_INDENT;
for (production *pr = pl->first_production; pr; pr = pr->next_production) {
Instrumentation::log_production(pr, detailed);
LOG("\n ");
if (pr->ins.production_tries > 0)
LOG("(hits %d/%d) ", pr->ins.production_matches, pr->ins.production_tries);
if (Wordings::nonempty(pr->ins.sample_text)) {
if (Wordings::length(pr->ins.sample_text) > 8) LOG("(matched long text) ");
else LOG("(matched: '%W') ", pr->ins.sample_text);
}
LOG("constraint ");
Instrumentation::log_ntic(&(pr->opt.pr_ntic));
LOG(" extremes ");
Instrumentation::log_extremes(&(pr->opt.pr_extremes));
LOG("\n");
}
LOG_OUTDENT;
}
@ =
void Instrumentation::log_production(production *pr, int detailed) {
if (pr->first_ptoken == NULL) LOG("<empty-production>");
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
for (ptoken *pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
Instrumentation::log_ptoken(pt, detailed);
LOG(" ");
}
@ -143,8 +196,7 @@ void Instrumentation::log_ptoken(ptoken *pt, int detailed) {
if (pt->range_starts >= 0) {
LOG("{"); if (detailed) LOG("%d:", pt->range_starts);
}
ptoken *alt;
for (alt = pt; alt; alt = alt->alternative_ptoken) {
for (ptoken *alt = pt; alt; alt = alt->alternative_ptoken) {
if (alt->nt_pt) {
LOG("%V", alt->nt_pt->nonterminal_id);
if (detailed) LOG("=%d", alt->result_index);
@ -165,8 +217,7 @@ void Instrumentation::write_ptoken(OUTPUT_STREAM, ptoken *pt) {
if (pt->disallow_unexpected_upper) WRITE("_");
if (pt->negated_ptoken) WRITE("^");
if (pt->range_starts >= 0) WRITE("{");
ptoken *alt;
for (alt = pt; alt; alt = alt->alternative_ptoken) {
for (ptoken *alt = pt; alt; alt = alt->alternative_ptoken) {
if (alt->nt_pt) {
WRITE("%V", alt->nt_pt->nonterminal_id);
} else {

View file

@ -0,0 +1,133 @@
[LengthExtremes::] Length Extremes.
To precalculate data which enables rapid parsing of source text against a
Preform grammar.
@ The "length extremes" system provides one of two optimisations enabling
the Preform parser quickly to reject non-matches, the other being
//Nonterminal Incidences//, which is harder to understand.
It may elucidate both to see the actual optimisation data for nonterminals
as used in a typical run of Inform 7 -- see //inform7: Performance Metrics//.
@ The "extremes" of something to be matched against are the minimum and maximum
number of words in a successful match; with |INFINITE_WORD_COUNT| as maximum
where the number is unlimited.
@d INFINITE_WORD_COUNT 1000000000
=
typedef struct length_extremes {
int min_words, max_words;
} length_extremes;
@ =
length_extremes LengthExtremes::new(int min, int max) {
length_extremes E; E.min_words = min; E.max_words = max;
return E;
}
@ Four useful special cases:
=
length_extremes LengthExtremes::no_words_at_all(void) {
length_extremes E; E.min_words = 0; E.max_words = 0;
return E;
}
length_extremes LengthExtremes::any_number_of_words(void) {
length_extremes E; E.min_words = 0; E.max_words = INFINITE_WORD_COUNT;
return E;
}
length_extremes LengthExtremes::at_least_one_word(void) {
length_extremes E; E.min_words = 1; E.max_words = INFINITE_WORD_COUNT;
return E;
}
length_extremes LengthExtremes::exactly_one_word(void) {
length_extremes E; E.min_words = 1; E.max_words = 1;
return E;
}
@ Testing:
=
int LengthExtremes::in_bounds(int match_length, length_extremes E) {
if ((match_length >= E.min_words) && (match_length <= E.max_words))
return TRUE;
return FALSE;
}
@ Concatenation produces the length extremes for the text X followed by the
text Y:
=
length_extremes LengthExtremes::concatenate(length_extremes E_X, length_extremes E_Y) {
length_extremes E = E_X;
E.min_words += E_Y.min_words;
if (E.min_words > INFINITE_WORD_COUNT) E.min_words = INFINITE_WORD_COUNT;
E.max_words += E_Y.max_words;
if (E.max_words > INFINITE_WORD_COUNT) E.max_words = INFINITE_WORD_COUNT;
return E;
}
@ The union provides the wider bounds, whichever they are:
=
length_extremes LengthExtremes::union(length_extremes E_X, length_extremes E_Y) {
length_extremes E = E_X;
if (E_Y.min_words < E.min_words) E.min_words = E_Y.min_words;
if (E_Y.max_words > E.max_words) E.max_words = E_Y.max_words;
return E;
}
@ The minimum matched text length for a nonterminal is the smallest of the
minima for its possible productions; for a production, it's the sum of the
minimum match lengths of its tokens.
=
length_extremes LengthExtremes::calculate_for_nt(nonterminal *nt) {
length_extremes E = LengthExtremes::no_words_at_all();
int first = TRUE;
for (production_list *pl = nt->first_production_list; pl; pl = pl->next_production_list)
for (production *pr = pl->first_production; pr; pr = pr->next_production) {
pr->opt.pr_extremes = LengthExtremes::calculate_for_pr(pr);
if (first) { E = pr->opt.pr_extremes; first = FALSE; }
else { E = LengthExtremes::union(E, pr->opt.pr_extremes); }
}
return E;
}
length_extremes LengthExtremes::calculate_for_pr(production *pr) {
length_extremes E = LengthExtremes::no_words_at_all();
for (ptoken *pt = pr->first_ptoken; pt; pt = pt->next_ptoken)
E = LengthExtremes::concatenate(E, LengthExtremes::calculate_for_pt(pt));
return E;
}
@ An interesting point here is that the negation of a ptoken can in principle
have any length, except that we specified |^ example| to match only a single
word -- any word other than "example". So the extremes for |^ example| are
1 and 1, whereas for |^ <sample-nonterminal>| they would have to be 0 and
infinity.
=
length_extremes LengthExtremes::calculate_for_pt(ptoken *pt) {
length_extremes E = LengthExtremes::exactly_one_word();
if (pt->negated_ptoken) {
if (pt->ptoken_category != FIXED_WORD_PTC)
E = LengthExtremes::any_number_of_words();
} else {
switch (pt->ptoken_category) {
case NONTERMINAL_PTC:
Optimiser::optimise_nonterminal(pt->nt_pt); /* recurse as needed */
E = pt->nt_pt->opt.nt_extremes; break;
case MULTIPLE_WILDCARD_PTC:
E = LengthExtremes::at_least_one_word(); break;
case POSSIBLY_EMPTY_WILDCARD_PTC:
E = LengthExtremes::any_number_of_words(); break;
}
}
return E;
}

View file

@ -256,7 +256,7 @@ part of them.
//The Optimiser// calculates data on productions just as it does on nonterminals.
For example, it can see that the above can only match a text if it has exactly
3 words, so it sets both |min_pr_words| and |max_pr_words| to 3. For the meaning
3 words, so it sets both |pr_extremes.min_words| and |pr_extremes.max_words| to 3. For the meaning
of the remaining data, and for what "struts" are, see //The Optimiser//: it
only confuses the picture here.
@ -578,4 +578,4 @@ never returns |NULL|.
if (ve == THREEHASHES_V) pt->ptoken_category = SINGLE_WILDCARD_PTC;
if (ve == THREEASTERISKS_V) pt->ptoken_category = POSSIBLY_EMPTY_WILDCARD_PTC;
}
if (pt->ptoken_category == FIXED_WORD_PTC) Optimiser::flag_words(ve, nt, pc);
if (pt->ptoken_category == FIXED_WORD_PTC) Nonterminals::note_word(ve, nt, pc);

View file

@ -0,0 +1,621 @@
[NTI::] Nonterminal Incidences.
To work out bitmaps of nonterminal incidences in grammar.
@h Introduction.
The "nonterminal incidences" system provides one of two optimisations enabling
the Preform parser quickly to reject non-matches, the other being
//Length Extremes//, which is easier to understand.
It may elucidate both to see the actual optimisation data for nonterminals
as used in a typical run of Inform 7 -- see //inform7: Performance Metrics//.
@h Incidence bits.
Each NT is assigned an "incidence bit", but this is generated on demand;
|nt_incidence_bit| 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).
The lowest 6 bits are reserved -- see //NTI::give_nt_reserved_incidence_bit//
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.
@d RESERVED_NT_BITS 6
=
int no_req_bits = 0;
int NTI::nt_incidence_bit(nonterminal *nt) {
if (nt->opt.nt_incidence_bit == -1) {
int b = RESERVED_NT_BITS + ((no_req_bits++)%(32-RESERVED_NT_BITS));
nt->opt.nt_incidence_bit = (1 << b);
}
return nt->opt.nt_incidence_bit;
}
@h The NTI of a word.
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 //Vocabulary::get_nti// and write it with //Vocabulary::set_nti//; if
we don't, it remains 0.
The NTI for a word will be a bitmap of the incidence bits for each NT whose
grammar includes that word.
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>.
To build that, we'll use the following:
=
void NTI::mark_vocabulary(vocabulary_entry *ve, nonterminal *nt) {
int R = Vocabulary::get_nti(ve);
R |= (NTI::nt_incidence_bit(nt));
Vocabulary::set_nti(ve, R);
}
int NTI::test_vocabulary(vocabulary_entry *ve, nonterminal *nt) {
int R = Vocabulary::get_nti(ve);
if (R & (NTI::nt_incidence_bit(nt))) return TRUE;
return FALSE;
}
@ Versions for words identified by their position in the lexer stream:
=
void NTI::mark_word(int wn, nonterminal *nt) {
NTI::mark_vocabulary(Lexer::word(wn), nt);
}
int NTI::test_word(int wn, nonterminal *nt) {
return NTI::test_vocabulary(Lexer::word(wn), nt);
}
@ It turns out to be fast to take a wording and to logical-or ("disjoin")
or logical-and ("conjoin") their NTI bitmaps together:
=
int NTI::get_range_disjunction(wording W) {
int R = 0;
LOOP_THROUGH_WORDING(i, W)
R |= Vocabulary::get_nti(Lexer::word(i));
return R;
}
int NTI::get_range_conjunction(wording W) {
int R = 0;
LOOP_THROUGH_WORDING(i, W) {
if (i == Wordings::first_wn(W)) R = Vocabulary::get_nti(Lexer::word(i));
else R &= Vocabulary::get_nti(Lexer::word(i));
}
return R;
}
@h Range requirements.
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:
= (text as Preform)
<recipe> ::=
pan-fried <fish> |
<fish> veronique |
battered <fish>
=
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.
@ 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.
The above idea can be applied equally well to matching text against a
nonterminal, production or ptoken, so all three have a //nti_constraint//
object. A NTIC encodes six rules, applying to a word range in three ways:
(a) D for "disjunction", or logical or. One of the words must satisfy this.
(b) C for "conjunction", or logical and. All of the words must satisfy this.
(c) F for "first". The first word must satisfy this.
And a rule can apply to the NTI bits in two ways:
(i) W for "weak". A word passes if it has one of these NTI bits.
(ii) S for "strong". A word passes if it has all of these NTI bits.
That makes six combinations in all: DW, DS, CW, CS, FW, and FS.
For example, suppose a NTIC has |DS_req| set to |0x280| -- 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.
=
typedef struct nti_constraint {
int there_are_no_requirements; /* if set, ignore all six bitmaps */
int DW_req; /* one of the words has one of these bits */
int DS_req; /* one of the words has all of these bits */
int CW_req; /* all of the words have one of these bits */
int CS_req; /* all of the words have all of these bits */
int FW_req; /* the first word has one of these bits */
int FS_req; /* the first word has all of these bits */
int ditto_flag; /* this production has the same constraint as the previous one */
} nti_constraint;
@ 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 |TRUE| means that the wording does not match.
=
int NTI::nt_bitmap_violates(wording W, nti_constraint *ntic) {
if (ntic->there_are_no_requirements) return FALSE;
if (Wordings::length(W) == 1) @<Perform C, D and F tests on a single word@>
else {
int C_set = ((ntic->CS_req) | (ntic->CW_req));
int D_set = ((ntic->DS_req) | (ntic->DW_req));
int F_set = ((ntic->FS_req) | (ntic->FW_req));
if ((C_set) && (D_set)) @<Perform C, D and F tests@>
else if (C_set) @<Perform C and F tests@>
else if (D_set) @<Perform D and F tests@>
else if (F_set) @<Perform F test@>;
}
return FALSE;
}
@<Perform C, D and F tests on a single word@> =
int bm = Vocabulary::get_nti(Lexer::word(Wordings::first_wn(W)));
if (((bm) & (ntic->FS_req)) != (ntic->FS_req)) return TRUE;
if ((((bm) & (ntic->FW_req)) == 0) && (ntic->FW_req)) return TRUE;
if (((bm) & (ntic->DS_req)) != (ntic->DS_req)) return TRUE;
if ((((bm) & (ntic->DW_req)) == 0) && (ntic->DW_req)) return TRUE;
if (((bm) & (ntic->CS_req)) != (ntic->CS_req)) return TRUE;
if ((((bm) & (ntic->CW_req)) == 0) && (ntic->CW_req)) return TRUE;
@<Perform C, D and F tests@> =
int disj = 0;
LOOP_THROUGH_WORDING(i, W) {
int bm = Vocabulary::get_nti(Lexer::word(i));
disj |= bm;
if (((bm) & (ntic->CS_req)) != (ntic->CS_req)) return TRUE;
if ((((bm) & (ntic->CW_req)) == 0) && (ntic->CW_req)) return TRUE;
if ((i == Wordings::first_wn(W)) && (F_set)) {
if (((bm) & (ntic->FS_req)) != (ntic->FS_req)) return TRUE;
if ((((bm) & (ntic->FW_req)) == 0) && (ntic->FW_req)) return TRUE;
}
}
if (((disj) & (ntic->DS_req)) != (ntic->DS_req)) return TRUE;
if ((((disj) & (ntic->DW_req)) == 0) && (ntic->DW_req)) return TRUE;
@<Perform C and F tests@> =
LOOP_THROUGH_WORDING(i, W) {
int bm = Vocabulary::get_nti(Lexer::word(i));
if (((bm) & (ntic->CS_req)) != (ntic->CS_req)) return TRUE;
if ((((bm) & (ntic->CW_req)) == 0) && (ntic->CW_req)) return TRUE;
if ((i == Wordings::first_wn(W)) && (F_set)) {
if (((bm) & (ntic->FS_req)) != (ntic->FS_req)) return TRUE;
if ((((bm) & (ntic->FW_req)) == 0) && (ntic->FW_req)) return TRUE;
}
}
@<Perform D and F tests@> =
int disj = 0;
LOOP_THROUGH_WORDING(i, W) {
int bm = Vocabulary::get_nti(Lexer::word(i));
disj |= bm;
if ((i == Wordings::first_wn(W)) && (F_set)) {
if (((bm) & (ntic->FS_req)) != (ntic->FS_req)) return TRUE;
if ((((bm) & (ntic->FW_req)) == 0) && (ntic->FW_req)) return TRUE;
}
}
if (((disj) & (ntic->DS_req)) != (ntic->DS_req)) return TRUE;
if ((((disj) & (ntic->DW_req)) == 0) && (ntic->DW_req)) return TRUE;
@<Perform F test@> =
int bm = Vocabulary::get_nti(Lexer::word(Wordings::first_wn(W)));
if (((bm) & (ntic->FS_req)) != (ntic->FS_req)) return TRUE;
if ((((bm) & (ntic->FW_req)) == 0) && (ntic->FW_req)) return TRUE;
@h Basic range requirements.
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":
=
nti_constraint NTI::unconstrained(void) {
nti_constraint ntic;
ntic.there_are_no_requirements = FALSE;
ntic.ditto_flag = FALSE;
ntic.DS_req = 0; ntic.DW_req = 0;
ntic.CS_req = 0; ntic.CW_req = 0;
ntic.FS_req = 0; ntic.FW_req = 0;
return ntic;
}
@ And this "atomic" NTIC expresses the idea that every word must be flagged
with the incidence bit for a specific NT:
=
nti_constraint NTI::each_word_must_have(nonterminal *nt) {
nti_constraint ntic;
ntic.there_are_no_requirements = FALSE;
ntic.ditto_flag = FALSE;
int b = NTI::nt_incidence_bit(nt);
ntic.DS_req = b; ntic.DW_req = b;
ntic.CS_req = b; ntic.CW_req = b;
ntic.FS_req = 0; ntic.FW_req = 0;
return ntic;
}
@h Concatenation of range requirements.
Suppose we are going to match some words X, then some more words Y.
The X words have to satisfy |X_ntic| and the Y words |Y_ntic|. The following
function alters |X_ntic| so that it is now a requirement for "match X and
then Y", or XY for short.
=
void NTI::concatenate_rreq(nti_constraint *X_ntic, nti_constraint *Y_ntic) {
X_ntic->DS_req = NTI::concatenate_ds(X_ntic->DS_req, Y_ntic->DS_req);
X_ntic->DW_req = NTI::concatenate_dw(X_ntic->DW_req, Y_ntic->DW_req);
X_ntic->CS_req = NTI::concatenate_cs(X_ntic->CS_req, Y_ntic->CS_req);
X_ntic->CW_req = NTI::concatenate_cw(X_ntic->CW_req, Y_ntic->CW_req);
X_ntic->FS_req = NTI::concatenate_fs(X_ntic->FS_req, Y_ntic->FS_req);
X_ntic->FW_req = NTI::concatenate_fw(X_ntic->FW_req, Y_ntic->FW_req);
}
@ The strong requirements are well-defined. Suppose all of the bits of |m1|
are found in X, and all of the bits of |m2| 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:
=
int NTI::concatenate_ds(int m1, int m2) {
return m1 | m2;
}
@ Similarly, suppose all of the bits of |m1| are found in every word of X,
and all of those of |m2| are in every word of Y. The most which can be said
about every word of XY is to take the intersection, so:
=
int NTI::concatenate_cs(int m1, int m2) {
return m1 & m2;
}
@ Now suppose that at least one bit of |m1| can be found in X, and one bit
of |m2| 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 |m1| and
say that one bit of |m1| can be found in XY. In principle we ought to choose
the rarest for best effect, but that's too much work.
=
int NTI::concatenate_dw(int m1, int m2) {
if (m1 == 0) return m2; /* the case where we have no information about X */
if (m2 == 0) return m1; /* and about Y */
return m1; /* the general case discussed above */
}
@ Now suppose that each word of X matches at least one bit of |m1|, and
similarly for Y and |m2|. Then each word of XY matches at least one bit of
the union, so:
=
int NTI::concatenate_cw(int m1, int m2) {
if (m1 == 0) return 0; /* the case where we have no information about X */
if (m2 == 0) return 0; /* and about Y */
return m1 | m2; /* the general case discussed above */
}
@ The first word of XY is the first word of X, so these are much easier:
=
int NTI::concatenate_fs(int m1, int m2) {
return m1;
}
int NTI::concatenate_fw(int m1, int m2) {
return m1;
}
@h Disjunction of range requirements.
The second operation is disjunction. Again we have words X with requirement
|X_ntic| and Y with |Y_ntic|, but this time we want to change |X_ntic| so that
it is the requirement for "match either X or Y", or X/Y for short.
This amounts to a disguised form of de Morgan's laws.
=
void NTI::disjoin_rreq(nti_constraint *X_ntic, nti_constraint *Y_ntic) {
X_ntic->DS_req = NTI::disjoin_ds(X_ntic->DS_req, Y_ntic->DS_req);
X_ntic->DW_req = NTI::disjoin_dw(X_ntic->DW_req, Y_ntic->DW_req);
X_ntic->CS_req = NTI::disjoin_cs(X_ntic->CS_req, Y_ntic->CS_req);
X_ntic->CW_req = NTI::disjoin_cw(X_ntic->CW_req, Y_ntic->CW_req);
X_ntic->FS_req = NTI::disjoin_fs(X_ntic->FS_req, Y_ntic->FS_req);
X_ntic->FW_req = NTI::disjoin_fw(X_ntic->FW_req, Y_ntic->FW_req);
}
@ Suppose all of the bits of |m1| are found in X, and all of the bits of |m2|
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.)
=
int NTI::disjoin_ds(int m1, int m2) {
return m1 & m2;
}
@ Similarly, suppose all of the bits of |m1| are found in every word of X,
and all of those of |m2| are in every word of Y. The most which can be said
about every word of XY is to take the intersection, so:
=
int NTI::disjoin_cs(int m1, int m2) {
return m1 & m2;
}
@ Now suppose that at least one bit of |m1| can be found in X, and one bit
of |m2| can be found in Y. All we can say is that one of these various bits
must be found in X/Y, so:
=
int NTI::disjoin_dw(int m1, int m2) {
if (m1 == 0) return 0; /* the case where we have no information about X */
if (m2 == 0) return 0; /* and about Y */
return m1 | m2; /* the general case discussed above */
}
@ And exactly the same is true for conjunctions:
=
int NTI::disjoin_cw(int m1, int m2) {
if (m1 == 0) return 0; /* the case where we have no information about X */
if (m2 == 0) return 0; /* and about Y */
return m1 | m2; /* the general case discussed above */
}
int NTI::disjoin_fw(int m1, int m2) {
return NTI::disjoin_cw(m1, m2);
}
int NTI::disjoin_fs(int m1, int m2) {
return NTI::disjoin_cs(m1, m2);
}
@h Range requirement simplification.
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 //NTI::nt_bitmap_violates//.
=
void NTI::simplify_requirement(nti_constraint *ntic) {
@<Remove a disjunction test contained in a first-word test@>;
@<Remove a first-word test contained in a conjunction test@>;
@<Remove a disjunction test contained in a conjunction test@>;
@<Remove any weak test which partially duplicates a strong one@>;
ntic->ditto_flag = FALSE;
ntic->there_are_no_requirements = TRUE;
if ((ntic->DS_req) || (ntic->DW_req) || (ntic->CS_req) ||
(ntic->CW_req) || (ntic->FS_req) || (ntic->FW_req))
ntic->there_are_no_requirements = FALSE;
}
@ 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.
@<Remove a disjunction test contained in a first-word test@> =
if ((ntic->DS_req & ntic->FS_req) == ntic->DS_req) ntic->DS_req = 0;
if ((ntic->DW_req & ntic->FW_req) == ntic->DW_req) ntic->DW_req = 0;
@ 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.
@<Remove a first-word test contained in a conjunction test@> =
if ((ntic->CS_req & ntic->FS_req) == ntic->FS_req) ntic->FS_req = 0;
if ((ntic->CW_req & ntic->FW_req) == ntic->FW_req) ntic->FW_req = 0;
@ 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.
@<Remove a disjunction test contained in a conjunction test@> =
if ((ntic->CS_req & ntic->DS_req) == ntic->DS_req) ntic->DS_req = 0;
if ((ntic->CW_req & ntic->DW_req) == ntic->DW_req) ntic->DW_req = 0;
@ 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.
@<Remove any weak test which partially duplicates a strong one@> =
if ((ntic->FW_req & ntic->FS_req) == ntic->FW_req) ntic->FW_req = 0;
if ((ntic->DW_req & ntic->DS_req) == ntic->DW_req) ntic->DW_req = 0;
if ((ntic->CW_req & ntic->CS_req) == ntic->CW_req) ntic->CW_req = 0;
@ The "ditto flag" on a requirement is used when there are two requirements,
here |prev| then |ntic|, representing alternatives for parsing the same text --
i.e., it must match either |prev| or |ntic|. If these two requirements are
the same, we needn't check the second one after the first has been checked.
So we give |ntic| the ditto flag, to say "same as the one before".
=
void NTI::simplify_pair(nti_constraint *ntic, nti_constraint *prev) {
NTI::simplify_requirement(ntic);
if ((prev) &&
(ntic->DS_req == prev->DS_req) && (ntic->DW_req == prev->DW_req) &&
(ntic->CS_req == prev->CS_req) && (ntic->CW_req == prev->CW_req) &&
(ntic->FS_req == prev->FS_req) && (ntic->FW_req == prev->FW_req))
ntic->ditto_flag = TRUE;
}
@ Whence:
=
void NTI::simplify_nt(nonterminal *nt) {
for (production_list *pl = nt->first_production_list; pl; pl = pl->next_production_list) {
nti_constraint *prev_req = NULL;
for (production *pr = pl->first_production; pr; pr = pr->next_production) {
NTI::simplify_pair(&(pr->opt.pr_ntic), prev_req);
prev_req = &(pr->opt.pr_ntic);
}
}
NTI::simplify_requirement(&(nt->opt.nt_ntic));
}
@h Calculations.
We now have all the apparatus we need, so:
=
void NTI::calculate_constraint(nonterminal *nt) {
#ifdef PREFORM_CIRCULARITY_BREAKER
PREFORM_CIRCULARITY_BREAKER(nt);
#endif
@<Mark up fixed wording in the grammar for NT with the NT's incidence bit@>;
@<Calculate requirement for NT@>;
#ifdef PREFORM_CIRCULARITY_BREAKER
PREFORM_CIRCULARITY_BREAKER(nt);
#endif
}
@<Mark up fixed wording in the grammar for NT with the NT's incidence bit@> =
for (production_list *pl = nt->first_production_list; pl; pl = pl->next_production_list)
for (production *pr = pl->first_production; pr; pr = pr->next_production)
for (ptoken *pt = pr->first_ptoken; pt; pt = pt->next_ptoken)
if ((pt->ptoken_category == FIXED_WORD_PTC) && (pt->negated_ptoken == FALSE))
for (ptoken *alt = pt; alt; alt = alt->alternative_ptoken)
NTI::mark_vocabulary(alt->ve_pt, nt);
@ The requirement for a NT is a disjunction of the requirements for the productions.
@<Calculate requirement for NT@> =
nti_constraint nnt = nt->opt.nt_ntic;
int first_production = TRUE;
for (production_list *pl = nt->first_production_list; pl; pl = pl->next_production_list) {
for (production *pr = pl->first_production; pr; pr = pr->next_production) {
@<Calculate requirement for production@>;
if (first_production) nnt = pr->opt.pr_ntic;
else NTI::disjoin_rreq(&nnt, &(pr->opt.pr_ntic));
first_production = FALSE;
}
}
nt->opt.nt_ntic = nnt;
@ The requirement for a production is a concatenation of the requirements for the
ptokens.
@<Calculate requirement for production@> =
nti_constraint prt = NTI::unconstrained();
int first = TRUE;
for (ptoken *pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
int empty = FALSE;
nti_constraint tok_ntic = NTI::unconstrained();
@<Calculate requirement for ptoken@>;
if (empty == FALSE) {
if (first) prt = tok_ntic;
else NTI::concatenate_rreq(&prt, &tok_ntic);
first = FALSE;
}
}
pr->opt.pr_ntic = prt;
@ We're down to atoms, now, and:
(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.
(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 |zephyr|
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.)
(c) For a ptoken which is a non-negated use of another NT, the constraint
is just the constraint of that NT.
(d) Nothing can be deduced from a negated ptoken: for example, all we know
about the ptoken |^mistral| is that it matches something which is not the
word "mistral", and that tells us nothing about the bits that it has.
@<Calculate requirement for ptoken@> =
if ((pt->ptoken_category == NONTERMINAL_PTC) &&
(pt->nt_pt->opt.nt_extremes.min_words == 0) && (pt->nt_pt->opt.nt_extremes.max_words == 0))
empty = TRUE; /* even if negated, notice */
if ((pt->ptoken_category == FIXED_WORD_PTC) && (pt->negated_ptoken == FALSE))
tok_ntic = NTI::each_word_must_have(nt);
if ((pt->ptoken_category == NONTERMINAL_PTC) && (pt->negated_ptoken == FALSE)) {
Optimiser::optimise_nonterminal(pt->nt_pt);
tok_ntic = pt->nt_pt->opt.nt_ntic;
}
@h Customisation.
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, //words// provides for up to
two callback functions which have the opportunity to tweak the process:
=
void NTI::ask_parent_to_tweak(void) {
#ifdef FURTHER_PREFORM_OPTIMISER_WORDS_CALLBACK
FURTHER_PREFORM_OPTIMISER_WORDS_CALLBACK();
#endif
#ifdef PREFORM_OPTIMISER_WORDS_CALLBACK
PREFORM_OPTIMISER_WORDS_CALLBACK();
#endif
}
@ Those callbacks should consist of calls to the following functions.
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".
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.
@d CARDINAL_RES_NT_BIT 0
@d ORDINAL_RES_NT_BIT 1
@d ARTICLE_RES_NT_BIT 2
@d ADJECTIVE_RES_NT_BIT 3
@d PROPER_NOUN_RES_NT_BIT 4
@d COMMON_NOUN_RES_NT_BIT 5
=
void NTI::give_nt_reserved_incidence_bit(nonterminal *nt, int b) {
if (nt == NULL) internal_error("null NT");
if ((b < 0) || (b >= RESERVED_NT_BITS)) internal_error("assigned bad bit");
nt->opt.nt_incidence_bit = (1 << 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.
=
void NTI::one_word_in_match_must_have_my_NTI_bit(nonterminal *nt) {
nt->opt.nt_ntic.DS_req |= (NTI::nt_incidence_bit(nt));
}
void NTI::first_word_in_match_must_have_my_NTI_bit(nonterminal *nt) {
nt->opt.nt_ntic.FS_req |= (NTI::nt_incidence_bit(nt));
}
void NTI::every_word_in_match_must_have_my_NTI_bit(nonterminal *nt) {
nt->opt.nt_ntic.CS_req |= (NTI::nt_incidence_bit(nt));
}
void NTI::every_word_in_match_must_have_my_NTI_bit_or_this_one(nonterminal *nt, int x) {
nt->opt.nt_ntic.CW_req |= (NTI::nt_incidence_bit(nt) + x);
}

View file

@ -92,11 +92,9 @@ are needed because the Preform optimiser can't see inside |any_integer_NTMR| to
calculate those bounds for itself. |max| can be infinity, in which case we
use the constant |INFINITE_WORD_COUNT| for it.
@d INFINITE_WORD_COUNT 1000000000
@d INTERNAL_NONTERMINAL(quotedname, identifier, min, max)
identifier = Nonterminals::find(Vocabulary::entry_for_text(quotedname));
identifier->opt.min_nt_words = min; identifier->opt.max_nt_words = max;
identifier->opt.nt_extremes = LengthExtremes::new(min, max);
identifier->internal_definition = identifier##R;
identifier->marked_internal = TRUE;
@ -118,6 +116,8 @@ typedef struct nonterminal {
struct production_list *first_production_list; /* if not internal, this defines it */
int (*compositor_fn)(int *r, void **rp, int *i_s, void **i_ps, wording *i_W, wording W);
int multiplicitous; /* if true, matches are alternative syntax tree readings */
int number_words_by_production; /* this parses names for numbers, like "huit" or "zwei" */
unsigned int flag_words_in_production; /* all words in the production should get these flags */
/* Storage for most recent correct match */
struct wording range_result[MAX_RANGES_PER_PRODUCTION]; /* storage for word ranges matched */
@ -147,7 +147,10 @@ result of parsing text against a nonterminal is that the first grammar line
matching that text determines the meaning, but for a multiplicitous nonterminal,
every line matching the text determines one of perhaps many possible meanings.
(d) The optimisation data helps the parser to reject non-matching text quickly.
(d) For numbering and flagging on regular NTs, see //Nonterminals::make_numbering//
below.
(e) The optimisation data helps the parser to reject non-matching text quickly.
For example, if the optimiser can determine that <competitor> only ever matches
texts of between 3 and 7 words in length, it can quickly reject any run of
words outside that range. (However: note that a maximum of 0 means that the
@ -183,6 +186,8 @@ nonterminal *Nonterminals::find(vocabulary_entry *name_word) {
nt->first_production_list = NULL;
nt->compositor_fn = NULL;
nt->multiplicitous = FALSE;
nt->number_words_by_production = FALSE; /* i.e., don't */
nt->flag_words_in_production = 0; /* i.e., apply no flags */
for (int i=0; i<MAX_RANGES_PER_PRODUCTION; i++)
nt->range_result[i] = EMPTY_WORDING;
@ -232,3 +237,39 @@ any single NT.
=
int most_recent_result = 0; /* the variable which |inweb| writes |<<r>>| */
void *most_recent_result_p = NULL; /* the variable which |inweb| writes |<<rp>>| */
@h Flagging and numbering.
The following mechanism arranges for words used in the grammar for a NT to
be given properties just because of that -- either flags or numerical values.
For example, if we wanted the numbers from Stoppard's play "Dogg's Hamlet",
we might have:
= (text as Preform)
<dogg-numbers> ::=
sun | dock | trog | slack | pan
=
And if <dogg-numbers> were made a "numbering" NT, the effect would be that
these five words would pick up the numerical values 1, 2, 3, 4, 5, because
they occur in production number 1, 2, 3, 4, 5 for the NT.
=
void Nonterminals::make_numbering(nonterminal *nt) {
nt->number_words_by_production = TRUE;
}
@ Similarly, we could flag this NT with |NUMBER_MC|, and then the five words
sun, dock, trog, slack, pan would all pick up the |NUMBER_MC| flag
automatically.
=
void Nonterminals::flag_words_with(nonterminal *nt, unsigned int flags) {
nt->flag_words_in_production = flags;
}
@ This is all done by the following function, which is called when a word |ve|
is read as part of a production with match number |pc| for the nonterminal |nt|:
=
void Nonterminals::note_word(vocabulary_entry *ve, nonterminal *nt, int pc) {
ve->flags |= (nt->flag_words_in_production);
if (nt->number_words_by_production) ve->literal_number_value = pc;
}

View file

@ -30,8 +30,8 @@ int Preform::parse_nt_against_word_range(nonterminal *nt, wording W, int *result
}
int input_length = Wordings::length(W);
if ((nt->opt.max_nt_words == 0) ||
((input_length >= nt->opt.min_nt_words) && (input_length <= nt->opt.max_nt_words)))
if ((nt->opt.nt_extremes.max_words == 0) ||
(LengthExtremes::in_bounds(input_length, nt->opt.nt_extremes)))
@<Try to match the input text to the nonterminal@>;
@<The nonterminal has failed to parse@>;
@ -67,7 +67,7 @@ an internal NT, or try all possible productions for an external one.
unoptimised = TRUE;
if (nt->internal_definition) {
if (nt->voracious) unoptimised = TRUE;
if ((unoptimised) || (Optimiser::nt_bitmap_violates(W, &(nt->opt.nonterminal_req)) == FALSE)) {
if ((unoptimised) || (NTI::nt_bitmap_violates(W, &(nt->opt.nt_ntic)) == FALSE)) {
int r, Q; void *QP = NULL;
if (Wordings::first_wn(W) >= 0) r = (*(nt->internal_definition))(W, &Q, &QP);
else { r = FALSE; Q = 0; }
@ -79,12 +79,12 @@ an internal NT, or try all possible productions for an external one.
} else {
if (ptraci) {
LOG("%V: <%W> violates ", nt->nonterminal_id, W);
Optimiser::log_range_requirement(&(nt->opt.nonterminal_req));
Instrumentation::log_ntic(&(nt->opt.nt_ntic));
LOG("\n");
}
}
} else {
if ((unoptimised) || (Optimiser::nt_bitmap_violates(W, &(nt->opt.nonterminal_req)) == FALSE)) {
if ((unoptimised) || (NTI::nt_bitmap_violates(W, &(nt->opt.nt_ntic)) == FALSE)) {
void *acc_result = NULL;
production_list *pl;
for (pl = nt->first_production_list; pl; pl = pl->next_production_list) {
@ -95,8 +95,8 @@ an internal NT, or try all possible productions for an external one.
for (pr = pl->first_production; pr; pr = pr->next_production) {
int violates = FALSE;
if (unoptimised == FALSE) {
if (pr->opt.production_req.ditto_flag) violates = last_v;
else violates = Optimiser::nt_bitmap_violates(W, &(pr->opt.production_req));
if (pr->opt.pr_ntic.ditto_flag) violates = last_v;
else violates = NTI::nt_bitmap_violates(W, &(pr->opt.pr_ntic));
last_v = violates;
}
if (violates == FALSE) {
@ -106,7 +106,7 @@ an internal NT, or try all possible productions for an external one.
LOG("production in %V: ", nt->nonterminal_id);
Instrumentation::log_production(pr, FALSE);
LOG(": <%W> violates ", W);
Optimiser::log_range_requirement(&(pr->opt.production_req));
Instrumentation::log_ntic(&(pr->opt.pr_ntic));
LOG("\n");
}
}
@ -120,7 +120,7 @@ an internal NT, or try all possible productions for an external one.
} else {
if (ptraci) {
LOG("%V: <%W> violates ", nt->nonterminal_id, W);
Optimiser::log_range_requirement(&(nt->opt.nonterminal_req));
Instrumentation::log_ntic(&(nt->opt.nt_ntic));
LOG("\n");
}
}
@ -139,7 +139,7 @@ text against a production.
#ifdef CORE_MODULE
parse_node *added_to_result = NULL;
#endif
if ((input_length >= pr->opt.min_pr_words) && (input_length <= pr->opt.max_pr_words)) {
if (LengthExtremes::in_bounds(input_length, pr->opt.pr_extremes)) {
int Q; void *QP = NULL;
@<Actually parse the given production, going to Fail if we can't@>;
Instrumentation::note_production_match(pr, W);
@ -399,11 +399,11 @@ we rely on the recursive call to |Preform::parse_nt_against_word_range| returnin
quick no.
@<Match a nonterminal ptoken@> =
if ((wn > Wordings::last_wn(W)) && (pt->nt_pt->opt.min_nt_words > 0)) goto FailThisStrutPosition;
if ((wn > Wordings::last_wn(W)) && (pt->nt_pt->opt.nt_extremes.min_words > 0)) goto FailThisStrutPosition;
int wt;
if (pt->nt_pt->voracious) wt = Wordings::last_wn(W);
else if ((pt->nt_pt->opt.min_nt_words > 0) && (pt->nt_pt->opt.min_nt_words == pt->nt_pt->opt.max_nt_words))
wt = wn + pt->nt_pt->opt.min_nt_words - 1;
else if ((pt->nt_pt->opt.nt_extremes.min_words > 0) && (pt->nt_pt->opt.nt_extremes.min_words == pt->nt_pt->opt.nt_extremes.max_words))
wt = wn + pt->nt_pt->opt.nt_extremes.min_words - 1;
else @<Calculate how much to stretch this elastic ptoken@>;
if (pt == backtrack_token) {
@ -429,7 +429,7 @@ quick no.
}
if (pt->negated_ptoken) q = q?FALSE:TRUE;
if (q == FALSE) goto FailThisStrutPosition;
if (pt->nt_pt->opt.max_nt_words > 0) wn = wt+1;
if (pt->nt_pt->opt.nt_extremes.max_words > 0) wn = wt+1;
@ How much text from the input should this ptoken match? We feed it as much
as possible, and to calculate that, we must either be at the end of the run,
@ -499,10 +499,10 @@ int Preform::next_strut_posn_after(wording W, ptoken *start, int len, int from)
else break;
} else {
int q = Preform::parse_nt_against_word_range(pt->nt_pt,
Wordings::new(pos, pos+pt->nt_pt->opt.max_nt_words-1),
Wordings::new(pos, pos+pt->nt_pt->opt.nt_extremes.max_words-1),
NULL, NULL);
if (pt->negated_ptoken) q = q?FALSE:TRUE;
if (q) pos += pt->nt_pt->opt.max_nt_words;
if (q) pos += pt->nt_pt->opt.nt_extremes.max_words;
else break;
}
if (pos-from >= len) return from;

View file

@ -7,71 +7,33 @@ Preform grammar.
Nonterminals, productions and even ptokens all have packets of precalculated
optimisation data attached.
To begin with, NTs. |min_nt_words| and |max_nt_words| give the minimum and
maximum possible number of words in a matched text: with |INFINITE_WORD_COUNT|
as maximum where there is none. |nonterminal_req| is the "range requirement",
imposing conditions which any matching range of words must conform to: see below.
To begin with, NTs. |nt_ntic| is the "NTI constraint", imposing conditions
which any matching range of words must conform to: see //Nonterminal Incidences//.
=
typedef struct nonterminal_optimisation_data {
int optimised_in_this_pass; /* have the following been worked out yet? */
int min_nt_words, max_nt_words; /* for speed */
int nt_incidence_bit; /* which hashing category the words belong to, or $-1$ if none */
int number_words_by_production; /* this parses names for numbers, like "huit" or "zwei" */
unsigned int flag_words_in_production; /* all words in the production should get these flags */
struct range_requirement nonterminal_req;
struct length_extremes nt_extremes; /* for any wording matching this */
int nt_incidence_bit;
struct nti_constraint nt_ntic;
} nonterminal_optimisation_data;
@ =
void Optimiser::initialise_nonterminal_data(nonterminal_optimisation_data *opt) {
opt->optimised_in_this_pass = FALSE;
opt->min_nt_words = 1; opt->max_nt_words = INFINITE_WORD_COUNT;
opt->nt_incidence_bit = -1;
opt->number_words_by_production = FALSE;
opt->flag_words_in_production = 0;
Optimiser::clear_rreq(&(opt->nonterminal_req));
}
@ Each NT is assigned an "incidence bit", but this is generated on demand;
|nt_incidence_bit| 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).
The lowest 6 bits are reserved, 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.
@d RESERVED_NT_BITS 6
=
int no_req_bits = 0;
int Optimiser::nt_incidence_bit(nonterminal *nt) {
if (nt->opt.nt_incidence_bit == -1) {
int b = RESERVED_NT_BITS + ((no_req_bits++)%(32-RESERVED_NT_BITS));
nt->opt.nt_incidence_bit = (1 << b);
}
return nt->opt.nt_incidence_bit;
}
@ But it is also possible to force the choice to be one of the reserved ones:
=
void Optimiser::give_nt_reserved_incidence_bit(nonterminal *nt, int b) {
if (nt == NULL) internal_error("null NT");
if ((b < 0) || (b >= RESERVED_NT_BITS)) internal_error("assigned bad bit");
nt->opt.nt_incidence_bit = (1 << b);
opt->nt_extremes = LengthExtremes::at_least_one_word();
opt->nt_incidence_bit = -1; /* meaning "not yet allocated" */
opt->nt_ntic = NTI::unconstrained();
}
@h Production optimisation data.
Like nonterminals, productions have minimum and maximum word counts, and a
range requirement:
Like nonterminals, productions have minimum and maximum word counts, and an
NTI constraint:
=
typedef struct production_optimisation_data {
int min_pr_words, max_pr_words;
struct range_requirement production_req;
struct length_extremes pr_extremes; /* for any wording matching this */
struct nti_constraint pr_ntic;
int no_struts;
struct ptoken *struts[MAX_STRUTS_PER_PRODUCTION]; /* first ptoken in strut */
int strut_lengths[MAX_STRUTS_PER_PRODUCTION]; /* length of the strut in words */
@ -99,24 +61,22 @@ contains two ptokens, but because it is always two words wide.
=
void Optimiser::initialise_production_data(production_optimisation_data *opt) {
opt->no_struts = 0;
opt->min_pr_words = 1; opt->max_pr_words = INFINITE_WORD_COUNT;
Optimiser::clear_rreq(&(opt->production_req));
opt->pr_extremes = LengthExtremes::at_least_one_word();
opt->pr_ntic = NTI::unconstrained();
}
@h Ptoken optimisation data.
A ptoken is marked with its position relative to the range matching its
production (see above for positions); with the number of the strut it belongs
to, if it does; with a range requirement; and with a |ptoken_is_fast| flag,
which is set if the token is a single fixed word at a known position which is
not an endpoint of a bracing. That sounds a tall order, but in practice many
ptokens are indeed fast.
to, if it does; and with a |ptoken_is_fast| flag, which is set if the token is
a single fixed word at a known position which is not an endpoint of a bracing.
That sounds a tall order, but in practice many ptokens are indeed fast.
=
typedef struct ptoken_optimisation_data {
int ptoken_position; /* fixed position in range: 1, 2, ... for left, -1, -2, ... for right */
int strut_number; /* if this is part of a strut, what number? or -1 if not */
int ptoken_is_fast; /* can be checked in the fast pass of the parser */
struct range_requirement token_req;
} ptoken_optimisation_data;
@ =
@ -124,433 +84,6 @@ void Optimiser::initialise_ptoken_data(ptoken_optimisation_data *opt) {
opt->ptoken_position = 0;
opt->strut_number = -1;
opt->ptoken_is_fast = FALSE;
Optimiser::clear_rreq(&(opt->token_req));
}
@h The NTI of a word.
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 //Vocabulary::get_nti// and write it with //Vocabulary::set_nti//; if
we don't, it remains 0.
Recall that each NT has an "incidence bit". The NTI for a word will be a
bitmap of the incidence bits for each NT whose grammar includes that word.
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>.
To build that, we'll use the following:
=
void Optimiser::mark_vocabulary(vocabulary_entry *ve, nonterminal *nt) {
int R = Vocabulary::get_nti(ve);
R |= (Optimiser::nt_incidence_bit(nt));
Vocabulary::set_nti(ve, R);
}
int Optimiser::test_vocabulary(vocabulary_entry *ve, nonterminal *nt) {
int R = Vocabulary::get_nti(ve);
if (R & (Optimiser::nt_incidence_bit(nt))) return TRUE;
return FALSE;
}
@ Versions for words identified by their position in the lexer stream:
=
void Optimiser::mark_word(int wn, nonterminal *nt) {
Optimiser::mark_vocabulary(Lexer::word(wn), nt);
}
int Optimiser::test_word(int wn, nonterminal *nt) {
return Optimiser::test_vocabulary(Lexer::word(wn), nt);
}
@ It turns out to be fast to take a wording and to logical-or ("disjoin")
or logical-and ("conjoin") their NTI bitmaps together:
=
int Optimiser::get_range_disjunction(wording W) {
int R = 0;
LOOP_THROUGH_WORDING(i, W)
R |= Vocabulary::get_nti(Lexer::word(i));
return R;
}
int Optimiser::get_range_conjunction(wording W) {
int R = 0;
LOOP_THROUGH_WORDING(i, W) {
if (i == Wordings::first_wn(W)) R = Vocabulary::get_nti(Lexer::word(i));
else R &= Vocabulary::get_nti(Lexer::word(i));
}
return R;
}
@h Range requirements.
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:
= (text as Preform)
<recipe> ::=
pan-fried <fish> |
<fish> veronique |
battered <fish>
=
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.
@ 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.
The above idea can be applied equally well to matching text against a
nonterminal, production or ptoken, so all three have a //range_requirement//
object. A RREQ encodes six rules, applying to a word range in three ways:
(a) D for "disjunction", or logical or. One of the words must satisfy this.
(b) C for "conjunction", or logical and. All of the words must satisfy this.
(c) F for "first". The first word must satisfy this.
And a rule can apply to the NTI bits in two ways:
(i) W for "weak". A word passes if it has one of these NTI bits.
(ii) S for "strong". A word passes if it has all of these NTI bits.
That makes six combinations in all: DW, DS, CW, CS, FW, and FS.
For example, suppose a RREQ has |DS_req| set to |0x280| -- 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.
=
typedef struct range_requirement {
int there_are_no_requirements; /* if set, ignore the bitmaps */
int DW_req; /* one of the words has one of these bits */
int DS_req; /* one of the words has all of these bits */
int CW_req; /* all of the words have one of these bits */
int CS_req; /* all of the words have all of these bits */
int FW_req; /* the first word has one of these bits */
int FS_req; /* the first word has all of these bits */
int ditto_flag;
} range_requirement;
@ And the following applies the RREQ 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 |TRUE| means that the wording does not match.
=
int Optimiser::nt_bitmap_violates(wording W, range_requirement *req) {
if (req->there_are_no_requirements) return FALSE;
if (Wordings::length(W) == 1) @<Perform C, D and F tests on a single word@>
else {
int C_set = ((req->CS_req) | (req->CW_req));
int D_set = ((req->DS_req) | (req->DW_req));
int F_set = ((req->FS_req) | (req->FW_req));
if ((C_set) && (D_set)) @<Perform C, D and F tests@>
else if (C_set) @<Perform C and F tests@>
else if (D_set) @<Perform D and F tests@>
else if (F_set) @<Perform F test@>;
}
return FALSE;
}
@<Perform C, D and F tests on a single word@> =
int bm = Vocabulary::get_nti(Lexer::word(Wordings::first_wn(W)));
if (((bm) & (req->FS_req)) != (req->FS_req)) return TRUE;
if ((((bm) & (req->FW_req)) == 0) && (req->FW_req)) return TRUE;
if (((bm) & (req->DS_req)) != (req->DS_req)) return TRUE;
if ((((bm) & (req->DW_req)) == 0) && (req->DW_req)) return TRUE;
if (((bm) & (req->CS_req)) != (req->CS_req)) return TRUE;
if ((((bm) & (req->CW_req)) == 0) && (req->CW_req)) return TRUE;
@<Perform C, D and F tests@> =
int disj = 0;
LOOP_THROUGH_WORDING(i, W) {
int bm = Vocabulary::get_nti(Lexer::word(i));
disj |= bm;
if (((bm) & (req->CS_req)) != (req->CS_req)) return TRUE;
if ((((bm) & (req->CW_req)) == 0) && (req->CW_req)) return TRUE;
if ((i == Wordings::first_wn(W)) && (F_set)) {
if (((bm) & (req->FS_req)) != (req->FS_req)) return TRUE;
if ((((bm) & (req->FW_req)) == 0) && (req->FW_req)) return TRUE;
}
}
if (((disj) & (req->DS_req)) != (req->DS_req)) return TRUE;
if ((((disj) & (req->DW_req)) == 0) && (req->DW_req)) return TRUE;
@<Perform C and F tests@> =
LOOP_THROUGH_WORDING(i, W) {
int bm = Vocabulary::get_nti(Lexer::word(i));
if (((bm) & (req->CS_req)) != (req->CS_req)) return TRUE;
if ((((bm) & (req->CW_req)) == 0) && (req->CW_req)) return TRUE;
if ((i == Wordings::first_wn(W)) && (F_set)) {
if (((bm) & (req->FS_req)) != (req->FS_req)) return TRUE;
if ((((bm) & (req->FW_req)) == 0) && (req->FW_req)) return TRUE;
}
}
@<Perform D and F tests@> =
int disj = 0;
LOOP_THROUGH_WORDING(i, W) {
int bm = Vocabulary::get_nti(Lexer::word(i));
disj |= bm;
if ((i == Wordings::first_wn(W)) && (F_set)) {
if (((bm) & (req->FS_req)) != (req->FS_req)) return TRUE;
if ((((bm) & (req->FW_req)) == 0) && (req->FW_req)) return TRUE;
}
}
if (((disj) & (req->DS_req)) != (req->DS_req)) return TRUE;
if ((((disj) & (req->DW_req)) == 0) && (req->DW_req)) return TRUE;
@<Perform F test@> =
int bm = Vocabulary::get_nti(Lexer::word(Wordings::first_wn(W)));
if (((bm) & (req->FS_req)) != (req->FS_req)) return TRUE;
if ((((bm) & (req->FW_req)) == 0) && (req->FW_req)) return TRUE;
@ Logging:
=
void Optimiser::log_range_requirement(range_requirement *req) {
if (req->DW_req) { LOG(" DW: %08x", req->DW_req); }
if (req->DS_req) { LOG(" DS: %08x", req->DS_req); }
if (req->CW_req) { LOG(" CW: %08x", req->CW_req); }
if (req->CS_req) { LOG(" CS: %08x", req->CS_req); }
if (req->FW_req) { LOG(" FW: %08x", req->FW_req); }
if (req->FS_req) { LOG(" FS: %08x", req->FS_req); }
}
@h Basic range requirements.
Determining the RREQ for a given nonterminal, production or ptoken involves
some work, and we build them iteratively, starting from something simple.
This RREQ means "no restriction":
=
void Optimiser::clear_rreq(range_requirement *req) {
req->DS_req = 0; req->DW_req = 0;
req->CS_req = 0; req->CW_req = 0;
req->FS_req = 0; req->FW_req = 0;
}
@ And this "atomic" RREQ expresses the idea that every word must be flagged
with the incidence bit for a specific NT:
=
void Optimiser::atomic_rreq(range_requirement *req, nonterminal *nt) {
int b = Optimiser::nt_incidence_bit(nt);
req->DS_req = b; req->DW_req = b;
req->CS_req = b; req->CW_req = b;
req->FS_req = 0; req->FW_req = 0;
}
@h Concatenation of range requirements.
Suppose we are going to match some words X, then some more words Y.
The X words have to satisfy |X_req| and the Y words |Y_req|. The following
function alters |X_req| so that it is now a requirement for "match X and
then Y", or XY for short.
=
void Optimiser::concatenate_rreq(range_requirement *X_req, range_requirement *Y_req) {
X_req->DS_req = Optimiser::concatenate_ds(X_req->DS_req, Y_req->DS_req);
X_req->DW_req = Optimiser::concatenate_dw(X_req->DW_req, Y_req->DW_req);
X_req->CS_req = Optimiser::concatenate_cs(X_req->CS_req, Y_req->CS_req);
X_req->CW_req = Optimiser::concatenate_cw(X_req->CW_req, Y_req->CW_req);
X_req->FS_req = Optimiser::concatenate_fs(X_req->FS_req, Y_req->FS_req);
X_req->FW_req = Optimiser::concatenate_fw(X_req->FW_req, Y_req->FW_req);
}
@ The strong requirements are well-defined. Suppose all of the bits of |m1|
are found in X, and all of the bits of |m2| 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:
=
int Optimiser::concatenate_ds(int m1, int m2) {
return m1 | m2;
}
@ Similarly, suppose all of the bits of |m1| are found in every word of X,
and all of those of |m2| are in every word of Y. The most which can be said
about every word of XY is to take the intersection, so:
=
int Optimiser::concatenate_cs(int m1, int m2) {
return m1 & m2;
}
@ Now suppose that at least one bit of |m1| can be found in X, and one bit
of |m2| 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 |m1| and
say that one bit of |m1| can be found in XY. In principle we ought to choose
the rarest for best effect, but that's too much work.
=
int Optimiser::concatenate_dw(int m1, int m2) {
if (m1 == 0) return m2; /* the case where we have no information about X */
if (m2 == 0) return m1; /* and about Y */
return m1; /* the general case discussed above */
}
@ Now suppose that each word of X matches at least one bit of |m1|, and
similarly for Y and |m2|. Then each word of XY matches at least one bit of
the union, so:
=
int Optimiser::concatenate_cw(int m1, int m2) {
if (m1 == 0) return 0; /* the case where we have no information about X */
if (m2 == 0) return 0; /* and about Y */
return m1 | m2; /* the general case discussed above */
}
@ The first word of XY is the first word of X, so these are much easier:
=
int Optimiser::concatenate_fs(int m1, int m2) {
return m1;
}
int Optimiser::concatenate_fw(int m1, int m2) {
return m1;
}
@h Disjunction of range requirements.
The second operation is disjunction. Again we have words X with requirement
|X_req| and Y with |Y_req|, but this time we want to change |X_req| so that
it is the requirement for "match either X or Y", or X/Y for short.
This amounts to a disguised form of de Morgan's laws.
=
void Optimiser::disjoin_rreq(range_requirement *X_req, range_requirement *Y_req) {
X_req->DS_req = Optimiser::disjoin_ds(X_req->DS_req, Y_req->DS_req);
X_req->DW_req = Optimiser::disjoin_dw(X_req->DW_req, Y_req->DW_req);
X_req->CS_req = Optimiser::disjoin_cs(X_req->CS_req, Y_req->CS_req);
X_req->CW_req = Optimiser::disjoin_cw(X_req->CW_req, Y_req->CW_req);
X_req->FS_req = Optimiser::disjoin_fs(X_req->FS_req, Y_req->FS_req);
X_req->FW_req = Optimiser::disjoin_fw(X_req->FW_req, Y_req->FW_req);
}
@ Suppose all of the bits of |m1| are found in X, and all of the bits of |m2|
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.)
=
int Optimiser::disjoin_ds(int m1, int m2) {
return m1 & m2;
}
@ Similarly, suppose all of the bits of |m1| are found in every word of X,
and all of those of |m2| are in every word of Y. The most which can be said
about every word of XY is to take the intersection, so:
=
int Optimiser::disjoin_cs(int m1, int m2) {
return m1 & m2;
}
@ Now suppose that at least one bit of |m1| can be found in X, and one bit
of |m2| can be found in Y. All we can say is that one of these various bits
must be found in X/Y, so:
=
int Optimiser::disjoin_dw(int m1, int m2) {
if (m1 == 0) return 0; /* the case where we have no information about X */
if (m2 == 0) return 0; /* and about Y */
return m1 | m2; /* the general case discussed above */
}
@ And exactly the same is true for conjunctions:
=
int Optimiser::disjoin_cw(int m1, int m2) {
if (m1 == 0) return 0; /* the case where we have no information about X */
if (m2 == 0) return 0; /* and about Y */
return m1 | m2; /* the general case discussed above */
}
int Optimiser::disjoin_fw(int m1, int m2) {
return Optimiser::disjoin_cw(m1, m2);
}
int Optimiser::disjoin_fs(int m1, int m2) {
return Optimiser::disjoin_cs(m1, m2);
}
@h Range requirement simplification.
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 //Optimiser::nt_bitmap_violates//.
=
void Optimiser::simplify_requirement(range_requirement *req) {
@<Remove a disjunction test contained in a first-word test@>;
@<Remove a first-word test contained in a conjunction test@>;
@<Remove a disjunction test contained in a conjunction test@>;
@<Remove any weak test which partially duplicates a strong one@>;
req->there_are_no_requirements = TRUE;
if ((req->DS_req) || (req->DW_req) || (req->CS_req) ||
(req->CW_req) || (req->FS_req) || (req->FW_req))
req->there_are_no_requirements = FALSE;
}
@ Suppose the RREQ 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.
@<Remove a disjunction test contained in a first-word test@> =
if ((req->DS_req & req->FS_req) == req->DS_req) req->DS_req = 0;
if ((req->DW_req & req->FW_req) == req->DW_req) req->DW_req = 0;
@ Suppose the RREQ 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.
@<Remove a first-word test contained in a conjunction test@> =
if ((req->CS_req & req->FS_req) == req->FS_req) req->FS_req = 0;
if ((req->CW_req & req->FW_req) == req->FW_req) req->FW_req = 0;
@ 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.
@<Remove a disjunction test contained in a conjunction test@> =
if ((req->CS_req & req->DS_req) == req->DS_req) req->DS_req = 0;
if ((req->CW_req & req->DW_req) == req->DW_req) req->DW_req = 0;
@ 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.
@<Remove any weak test which partially duplicates a strong one@> =
if ((req->FW_req & req->FS_req) == req->FW_req) req->FW_req = 0;
if ((req->DW_req & req->DS_req) == req->DW_req) req->DW_req = 0;
if ((req->CW_req & req->CS_req) == req->CW_req) req->CW_req = 0;
@ The "ditto flag" on a requirement is used when there are two requirements,
here |prev| then |req|, representing alternatives for parsing the same text --
i.e., it must match either |prev| or |req|. If these two requirements are
the same, we needn't check the second one after the first has been checked.
So we give |req| the ditto flag, to say "same as the one before".
=
void Optimiser::simplify_pair(range_requirement *req, range_requirement *prev) {
Optimiser::simplify_requirement(req);
req->ditto_flag = FALSE;
if ((prev) &&
(req->DS_req == prev->DS_req) && (req->DW_req == prev->DW_req) &&
(req->CS_req == prev->CS_req) && (req->CW_req == prev->CW_req) &&
(req->FS_req == prev->FS_req) && (req->FW_req == prev->FW_req))
req->ditto_flag = TRUE;
}
@h Optimising nonterminals.
@ -564,38 +97,42 @@ Two callback functions have a one-time opportunity to tweak the process.
=
void Optimiser::optimise_counts(void) {
nonterminal *nt;
LOOP_OVER(nt, nonterminal) Optimiser::clear_requirement_and_extrema(nt);
Optimiser::ask_parent_to_tweak();
LOOP_OVER(nt, nonterminal) Optimiser::find_requirement_and_extrema(nt);
LOOP_OVER(nt, nonterminal) Optimiser::simplify_requirements(nt);
LOOP_OVER(nt, nonterminal) Optimiser::clear_requirement_and_extremes(nt);
NTI::ask_parent_to_tweak();
LOOP_OVER(nt, nonterminal) Optimiser::optimise_nonterminal(nt);
LOOP_OVER(nt, nonterminal) NTI::simplify_nt(nt);
}
void Optimiser::clear_requirement_and_extrema(nonterminal *nt) {
Optimiser::clear_rreq(&(nt->opt.nonterminal_req));
void Optimiser::clear_requirement_and_extremes(nonterminal *nt) {
nt->opt.nt_ntic = NTI::unconstrained();
if (nt->marked_internal) {
nt->opt.optimised_in_this_pass = TRUE;
} else {
nt->opt.optimised_in_this_pass = FALSE;
nt->opt.min_nt_words = 1; nt->opt.max_nt_words = INFINITE_WORD_COUNT;
nt->opt.nt_extremes = LengthExtremes::at_least_one_word();
}
}
@ The following is recursively called: looking through the grammar for NT1,
if we find a token for grammar NT2, then we call this function to make sure
all calculations for that have been done. That mustn't loop, so we make sure
only a single call happens per pass.
@ Although it's not obvious from here, the following function is recursive,
because it calls //NTI::calculate_constraint//, and that in turn needs all the
nonterminals in the grammar for |nt| to have been optimised already -- to
ensure which, it calls //Optimiser::optimise_nonterminal//. A similar thing
also happens in //LengthExtremes::calculate_for_nt//.
Since we cannot rely on grammar to be well-founded, we rig the function to
ensure that a second call to it on the same nonterminal returns immediately;
there are only finitely many NTs and hangs are therefore impossible.
=
void Optimiser::find_requirement_and_extrema(nonterminal *nt) {
void Optimiser::optimise_nonterminal(nonterminal *nt) {
if (nt->opt.optimised_in_this_pass) return;
nt->opt.optimised_in_this_pass = TRUE;
Optimiser::find_extrema(nt);
nt->opt.nt_extremes = LengthExtremes::calculate_for_nt(nt);
for (production_list *pl = nt->first_production_list; pl; pl = pl->next_production_list)
for (production *pr = pl->first_production; pr; pr = pr->next_production)
Optimiser::optimise_production(pr);
Optimiser::find_requirement(nt);
NTI::calculate_constraint(nt);
}
@ -691,216 +228,15 @@ position then all of them have, but we're in no hurry so we don't exploit that.)
&& (pt->range_starts < 0) && (pt->range_ends < 0))
pt->opt.ptoken_is_fast = TRUE;
@
=
void Optimiser::find_requirement(nonterminal *nt) {
Optimiser::clear_rreq(&(nt->opt.nonterminal_req));
#ifdef PREFORM_CIRCULARITY_BREAKER
PREFORM_CIRCULARITY_BREAKER(nt);
#endif
@<Mark up fixed wording in the grammar for NT with the NT's incidence bit@>;
nt->opt.nonterminal_req = Optimiser::find_requirement_for_nonterminal(nt);
#ifdef PREFORM_CIRCULARITY_BREAKER
PREFORM_CIRCULARITY_BREAKER(nt);
#endif
}
@<Mark up fixed wording in the grammar for NT with the NT's incidence bit@> =
for (production_list *pl = nt->first_production_list; pl; pl = pl->next_production_list)
for (production *pr = pl->first_production; pr; pr = pr->next_production)
for (ptoken *pt = pr->first_ptoken; pt; pt = pt->next_ptoken)
if ((pt->ptoken_category == FIXED_WORD_PTC) && (pt->negated_ptoken == FALSE))
for (ptoken *alt = pt; alt; alt = alt->alternative_ptoken)
Optimiser::mark_vocabulary(alt->ve_pt, nt);
@ =
range_requirement Optimiser::find_requirement_for_nonterminal(nonterminal *nt) {
range_requirement nnt;
Optimiser::clear_rreq(&nnt);
int first_production = TRUE;
for (production_list *pl = nt->first_production_list; pl; pl = pl->next_production_list) {
for (production *pr = pl->first_production; pr; pr = pr->next_production) {
pr->opt.production_req = Optimiser::find_requirement_for_production(pr, nt);
if (first_production) nnt = pr->opt.production_req;
else Optimiser::disjoin_rreq(&nnt, &(pr->opt.production_req));
first_production = FALSE;
}
}
return nnt;
}
range_requirement Optimiser::find_requirement_for_production(production *pr, nonterminal *nt) {
range_requirement prt;
Optimiser::clear_rreq(&prt);
int all = TRUE, first = TRUE;
for (ptoken *pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
Optimiser::clear_rreq(&(pt->opt.token_req));
if ((pt->ptoken_category == FIXED_WORD_PTC) && (pt->negated_ptoken == FALSE)) {
ptoken *alt;
for (alt = pt; alt; alt = alt->alternative_ptoken)
Optimiser::mark_vocabulary(alt->ve_pt, nt);
Optimiser::atomic_rreq(&(pt->opt.token_req), nt);
} else all = FALSE;
int empty = FALSE;
if ((pt->ptoken_category == NONTERMINAL_PTC) &&
(pt->nt_pt->opt.min_nt_words == 0) && (pt->nt_pt->opt.max_nt_words == 0))
empty = TRUE; /* even if negated, notice */
if ((pt->ptoken_category == NONTERMINAL_PTC) && (pt->negated_ptoken == FALSE)) {
Optimiser::find_requirement_and_extrema(pt->nt_pt);
pt->opt.token_req = pt->nt_pt->opt.nonterminal_req;
}
if (empty == FALSE) {
if (first) prt = pt->opt.token_req;
else Optimiser::concatenate_rreq(&prt, &(pt->opt.token_req));
first = FALSE;
}
}
return prt;
}
@ =
void Optimiser::simplify_requirements(nonterminal *nt) {
production_list *pl;
for (pl = nt->first_production_list; pl; pl = pl->next_production_list) {
production *pr;
range_requirement *prev_req = NULL;
for (pr = pl->first_production; pr; pr = pr->next_production) {
Optimiser::simplify_pair(&(pr->opt.production_req), prev_req);
prev_req = &(pr->opt.production_req);
}
}
Optimiser::simplify_pair(&(nt->opt.nonterminal_req), NULL);
}
void Optimiser::find_extrema(nonterminal *nt) {
int min = -1, max = -1;
Optimiser::nonterminal_extrema(nt, &min, &max);
if (min >= 1) {
nt->opt.min_nt_words = min; nt->opt.max_nt_words = max;
}
}
@ The minimum matched text length for a nonterminal is the smallest of the
minima for its possible productions; for a production, it's the sum of the
minimum match lengths of its tokens.
=
void Optimiser::nonterminal_extrema(nonterminal *nt, int *min, int *max) {
for (production_list *pl = nt->first_production_list; pl; pl = pl->next_production_list)
for (production *pr = pl->first_production; pr; pr = pr->next_production) {
int min_p = 0, max_p = 0;
for (ptoken *pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
int min_t, max_t;
Optimiser::ptoken_extrema(pt, &min_t, &max_t);
min_p += min_t; max_p += max_t;
if (min_p > INFINITE_WORD_COUNT) min_p = INFINITE_WORD_COUNT;
if (max_p > INFINITE_WORD_COUNT) max_p = INFINITE_WORD_COUNT;
}
pr->opt.min_pr_words = min_p; pr->opt.max_pr_words = max_p;
if ((*min == -1) && (*max == -1)) { *min = min_p; *max = max_p; }
else {
if (min_p < *min) *min = min_p;
if (max_p > *max) *max = max_p;
}
}
}
@ An interesting point here is that the negation of a ptoken can in principle
have any length, except that we specified |^ example| to match only a single
word -- any word other than "example". So the extrema for |^ example| are
1 and 1, whereas for |^ <sample-nonterminal>| they would have to be 0 and
infinity.
=
void Optimiser::ptoken_extrema(ptoken *pt, int *min_t, int *max_t) {
*min_t = 1; *max_t = 1;
if (pt->negated_ptoken) {
if (pt->ptoken_category != FIXED_WORD_PTC) { *min_t = 0; *max_t = INFINITE_WORD_COUNT; }
return;
}
switch (pt->ptoken_category) {
case NONTERMINAL_PTC:
Optimiser::find_requirement_and_extrema(pt->nt_pt); /* recurse as needed to find its extrema */
*min_t = pt->nt_pt->opt.min_nt_words;
*max_t = pt->nt_pt->opt.max_nt_words;
break;
case MULTIPLE_WILDCARD_PTC:
*max_t = INFINITE_WORD_COUNT;
break;
case POSSIBLY_EMPTY_WILDCARD_PTC:
*min_t = 0;
*max_t = INFINITE_WORD_COUNT;
break;
}
}
@ Now to define elasticity:
@h Width and elasticity.
If the min and max are the same, that's the width of the ptoken, and if not
then it is said to be "elastic" and has no width as such.
@d PTOKEN_ELASTIC -1
=
int Optimiser::ptoken_width(ptoken *pt) {
int min, max;
Optimiser::ptoken_extrema(pt, &min, &max);
if (min != max) return PTOKEN_ELASTIC;
return min;
}
@h Flagging and numbering.
The following is called when a word |ve| is read as part of a production
with match number |pc| for the nonterminal |nt|:
=
void Optimiser::flag_words(vocabulary_entry *ve, nonterminal *nt, int pc) {
ve->flags |= (nt->opt.flag_words_in_production);
if (nt->opt.number_words_by_production) ve->literal_number_value = pc;
}
@ =
int first_round_of_nt_optimisation_made = FALSE;
void Optimiser::ask_parent_to_tweak(void) {
if (first_round_of_nt_optimisation_made == FALSE) {
first_round_of_nt_optimisation_made = TRUE;
#ifdef FURTHER_PREFORM_OPTIMISER_WORDS_CALLBACK
FURTHER_PREFORM_OPTIMISER_WORDS_CALLBACK();
#endif
#ifdef PREFORM_OPTIMISER_WORDS_CALLBACK
PREFORM_OPTIMISER_WORDS_CALLBACK();
#endif
}
}
void Optimiser::mark_nt_as_requiring_itself(nonterminal *nt) {
nt->opt.nonterminal_req.DS_req |= (Optimiser::nt_incidence_bit(nt));
nt->opt.nonterminal_req.DW_req |= (Optimiser::nt_incidence_bit(nt));
}
void Optimiser::mark_nt_as_requiring_itself_first(nonterminal *nt) {
nt->opt.nonterminal_req.DS_req |= (Optimiser::nt_incidence_bit(nt));
nt->opt.nonterminal_req.DW_req |= (Optimiser::nt_incidence_bit(nt));
nt->opt.nonterminal_req.FS_req |= (Optimiser::nt_incidence_bit(nt));
nt->opt.nonterminal_req.FW_req |= (Optimiser::nt_incidence_bit(nt));
}
void Optimiser::mark_nt_as_requiring_itself_conj(nonterminal *nt) {
nt->opt.nonterminal_req.DS_req |= (Optimiser::nt_incidence_bit(nt));
nt->opt.nonterminal_req.DW_req |= (Optimiser::nt_incidence_bit(nt));
nt->opt.nonterminal_req.CS_req |= (Optimiser::nt_incidence_bit(nt));
nt->opt.nonterminal_req.CW_req |= (Optimiser::nt_incidence_bit(nt));
nt->opt.nonterminal_req.FS_req |= (Optimiser::nt_incidence_bit(nt));
nt->opt.nonterminal_req.FW_req |= (Optimiser::nt_incidence_bit(nt));
}
void Optimiser::mark_nt_as_requiring_itself_augmented(nonterminal *nt, int x) {
nt->opt.nonterminal_req.DS_req |= (Optimiser::nt_incidence_bit(nt));
nt->opt.nonterminal_req.DW_req |= (Optimiser::nt_incidence_bit(nt));
nt->opt.nonterminal_req.CW_req |= (Optimiser::nt_incidence_bit(nt) + x);
nt->opt.nonterminal_req.FW_req |= (Optimiser::nt_incidence_bit(nt) + x);
length_extremes E = LengthExtremes::calculate_for_pt(pt);
if (E.min_words != E.max_words) return PTOKEN_ELASTIC;
return E.min_words;
}

View file

@ -31,6 +31,8 @@ Chapter 4: Parsing
Nonterminals
Loading Preform
The Optimiser
Length Extremes
Nonterminal Incidences
Preform
Basic Nonterminals
Instrumentation