mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
361 lines
54 KiB
HTML
361 lines
54 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>The Optimiser</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">
|
|
<script>
|
|
MathJax = {
|
|
tex: {
|
|
inlineMath: '$', '$'], ['\\(', '\\)'
|
|
},
|
|
svg: {
|
|
fontCache: 'global'
|
|
}
|
|
};
|
|
</script>
|
|
<script type="text/javascript" id="MathJax-script" async
|
|
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
|
|
</script>
|
|
|
|
<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="../index.html">home</a></li>
|
|
</ul><h2>Compiler</h2><ul>
|
|
<li><a href="../structure.html">structure</a></li>
|
|
<li><a href="../inbuildn.html">inbuild</a></li>
|
|
<li><a href="../inform7n.html">inform7</a></li>
|
|
<li><a href="../intern.html">inter</a></li>
|
|
<li><a href="../services.html">services</a></li>
|
|
<li><a href="../secrets.html">secrets</a></li>
|
|
</ul><h2>Other Tools</h2><ul>
|
|
<li><a href="../inblorbn.html">inblorb</a></li>
|
|
<li><a href="../indocn.html">indoc</a></li>
|
|
<li><a href="../inform6.html">inform6</a></li>
|
|
<li><a href="../inpolicyn.html">inpolicy</a></li>
|
|
<li><a href="../inrtpsn.html">inrtps</a></li>
|
|
</ul><h2>Resources</h2><ul>
|
|
<li><a href="../extensions.html">extensions</a></li>
|
|
<li><a href="../kits.html">kits</a></li>
|
|
</ul><h2>Repository</h2><ul>
|
|
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
|
|
</ul><h2>Related Projects</h2><ul>
|
|
<li><a href="../../../inweb/index.html">inweb</a></li>
|
|
<li><a href="../../../intest/index.html">intest</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'The Optimiser' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../services.html">Services</a></li><li><a href="index.html">words</a></li><li><a href="index.html#4">Chapter 4: Parsing</a></li><li><b>The Optimiser</b></li></ul></div>
|
|
<p class="purpose">To precalculate data which enables rapid parsing of source text against a Preform grammar.</p>
|
|
|
|
<ul class="toc"><li><a href="4-to.html#SP1">§1. Nonterminal optimisation data</a></li><li><a href="4-to.html#SP3">§3. Production optimisation data</a></li><li><a href="4-to.html#SP5">§5. Ptoken optimisation data</a></li><li><a href="4-to.html#SP7">§7. Optimising nonterminals</a></li><li><a href="4-to.html#SP9">§9. Width and elasticity</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. Nonterminal optimisation data. </b>Nonterminals, productions and even ptokens all have packets of precalculated
|
|
optimisation data attached.
|
|
</p>
|
|
|
|
<p class="commentary">To begin with, NTs. <span class="extract"><span class="extract-syntax">nt_ntic</span></span> is the "NTI constraint", imposing conditions
|
|
which any matching range of words must conform to: see <a href="4-ni.html" class="internal">Nonterminal Incidences</a>.
|
|
</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">nonterminal_optimisation_data</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">optimised_in_this_pass</span><span class="plain-syntax">; </span><span class="comment-syntax"> have the following been worked out yet?</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">nt_extremes</span><span class="plain-syntax">; </span><span class="comment-syntax"> for any wording matching this</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">nt_incidence_bit</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">nti_constraint</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">nonterminal_optimisation_data</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure nonterminal_optimisation_data is accessed in 4/nnt, 4/le, 4/ni, 4/prf, 4/ins and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. </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">Optimiser::initialise_nonterminal_data</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">Optimiser::initialise_nonterminal_data</span></span>:<br/>Nonterminals - <a href="4-nnt.html#SP8">§8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal_optimisation_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opt</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">opt</span><span class="plain-syntax">-></span><span class="element-syntax">optimised_in_this_pass</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">opt</span><span class="plain-syntax">-></span><span class="element-syntax">nt_extremes</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="plain-syntax"> </span><span class="identifier-syntax">opt</span><span class="plain-syntax">-></span><span class="element-syntax">nt_incidence_bit</span><span class="plain-syntax"> = -1; </span><span class="comment-syntax"> meaning "not yet allocated"</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">opt</span><span class="plain-syntax">-></span><span class="element-syntax">nt_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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. Production optimisation data. </b>Like nonterminals, productions have minimum and maximum word counts, and an
|
|
NTI constraint:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production_optimisation_data</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">length_extremes</span><span class="plain-syntax"> </span><span class="identifier-syntax">pr_extremes</span><span class="plain-syntax">; </span><span class="comment-syntax"> for any wording matching this</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="identifier-syntax">pr_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">no_struts</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">struts</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_STRUTS_PER_PRODUCTION</span><span class="plain-syntax">]; </span><span class="comment-syntax"> first ptoken in strut</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">strut_lengths</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_STRUTS_PER_PRODUCTION</span><span class="plain-syntax">]; </span><span class="comment-syntax"> length of the strut in words</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">production_optimisation_data</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure production_optimisation_data is accessed in 4/le, 4/ni, 4/prf, 4/ins and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. </b>There's a new idea here as well, though: struts. A "strut" is a run of
|
|
ptokens in the interior of the production whose position relative to the
|
|
ends is not known. For example, if we match:
|
|
</p>
|
|
|
|
<pre class="Preform-displayed-code all-displayed-code code-font">
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">frogs</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">like</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">but</span><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><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">to</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">eat</span>
|
|
</pre>
|
|
<p class="commentary">then we know that in a successful match, "frogs" and "like" must be the
|
|
first two words in the text matched, and "eat" and "to" the last two.
|
|
They are said to have positions 1, 2, -1 and -2 respectively: a positive
|
|
number is relative to the start of the range, a negative relative to the end,
|
|
so that position 1 is always the first word and position -1 is the last.
|
|
</p>
|
|
|
|
<p class="commentary">But we don't know where "but not" will occur; it could be anywhere in the
|
|
middle of the text. The ptokens for such words have position set to 0. A run
|
|
of these ptokens, not counting wildcards like <span class="extract"><span class="Preform-extract-syntax">...</span></span>, is called a "strut":
|
|
here, then, <span class="extract"><span class="Preform-extract-syntax">but not</span></span> is a strut. We can think of it as a partition which
|
|
can slide backwards and forwards. This strut has length 2, not because it
|
|
contains two ptokens, but because it is always two words wide.
|
|
</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">Optimiser::initialise_production_data</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">Optimiser::initialise_production_data</span></span>:<br/>Loading Preform - <a href="4-lp.html#SP14">§14</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">production_optimisation_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opt</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">opt</span><span class="plain-syntax">-></span><span class="element-syntax">no_struts</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-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#SP4" class="function-link"><span class="function-syntax">LengthExtremes::at_least_one_word</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">opt</span><span class="plain-syntax">-></span><span class="element-syntax">pr_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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. Ptoken optimisation data. </b>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; and with a <span class="extract"><span class="extract-syntax">ptoken_is_fast</span></span> 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.
|
|
</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">ptoken_optimisation_data</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ptoken_position</span><span class="plain-syntax">; </span><span class="comment-syntax"> fixed position in range: 1, 2, ... for left, -1, -2, ... for right</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">strut_number</span><span class="plain-syntax">; </span><span class="comment-syntax"> if this is part of a strut, what number? or -1 if not</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ptoken_is_fast</span><span class="plain-syntax">; </span><span class="comment-syntax"> can be checked in the fast pass of the parser</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">ptoken_optimisation_data</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure ptoken_optimisation_data is accessed in 4/prf, 4/ins and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. </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">Optimiser::initialise_ptoken_data</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">Optimiser::initialise_ptoken_data</span></span>:<br/>Loading Preform - <a href="4-lp.html#SP16_1">§16.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">ptoken_optimisation_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opt</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-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">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="identifier-syntax">opt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_is_fast</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. Optimising nonterminals. </b>That's enough groundwork laid: we now have to calculate all of these NTIs
|
|
and range requirements. The process will have to repeated if there are ever
|
|
extra Preform nonterminals created, because new grammar throws off the old
|
|
results. So the following may in principle be called multiple times.
|
|
</p>
|
|
|
|
<p class="commentary">Two callback functions have a one-time 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">Optimiser::optimise_counts</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">Optimiser::optimise_counts</span></span>:<br/>Loading Preform - <a href="4-lp.html#SP7">§7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">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><a href="4-to.html#SP7" class="function-link"><span class="function-syntax">Optimiser::clear_requirement_and_extremes</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="4-ni.html#SP28" class="function-link"><span class="function-syntax">NTI::ask_parent_to_add_constraints</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax">) </span><a href="4-to.html#SP8" class="function-link"><span class="function-syntax">Optimiser::optimise_nonterminal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax">) </span><a href="4-ni.html#SP24" class="function-link"><span class="function-syntax">NTI::simplify_nt</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Optimiser::clear_requirement_and_extremes</span><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_ntic</span><span class="plain-syntax"> = </span><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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">marked_internal</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">optimised_in_this_pass</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">optimised_in_this_pass</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></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#SP4" class="function-link"><span class="function-syntax">LengthExtremes::at_least_one_word</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. </b>Although it's not obvious from here, the following function is recursive,
|
|
because it calls <a href="4-ni.html#SP25" class="internal">NTI::calculate_constraint</a>, and that in turn needs all the
|
|
nonterminals in the grammar for <span class="extract"><span class="extract-syntax">nt</span></span> to have been optimised already — to
|
|
ensure which, it calls <a href="4-to.html#SP8" class="internal">Optimiser::optimise_nonterminal</a>. A similar thing
|
|
also happens in <a href="4-le.html#SP8" class="internal">LengthExtremes::calculate_for_nt</a>.
|
|
</p>
|
|
|
|
<p class="commentary">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.
|
|
</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">Optimiser::optimise_nonterminal</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Optimiser::optimise_nonterminal</span></span>:<br/><a href="4-to.html#SP7">§7</a><br/>Length Extremes - <a href="4-le.html#SP9">§9</a><br/>Nonterminal Incidences - <a href="4-ni.html#SP25_2_1_1">§25.2.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">optimised_in_this_pass</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">optimised_in_this_pass</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">nt_extremes</span><span class="plain-syntax"> = </span><a href="4-le.html#SP8" class="function-link"><span class="function-syntax">LengthExtremes::calculate_for_nt</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">first_pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="element-syntax">next_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="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="element-syntax">first_pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax">; </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">next_pr</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_production</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-ni.html#SP25" class="function-link"><span class="function-syntax">NTI::calculate_constraint</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">Optimiser::optimise_production</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">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> this will point to the last ptoken in the production</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-to.html#SP8_1" class="named-paragraph-link"><span class="named-paragraph">Compute front-end ptoken positions</span><span class="named-paragraph-number">8.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-to.html#SP8_2" class="named-paragraph-link"><span class="named-paragraph">Compute back-end ptoken positions</span><span class="named-paragraph-number">8.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-to.html#SP8_3" class="named-paragraph-link"><span class="named-paragraph">Compute struts within the production</span><span class="named-paragraph-number">8.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-to.html#SP8_4" class="named-paragraph-link"><span class="named-paragraph">Work out which ptokens are fast</span><span class="named-paragraph-number">8.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP8_1" class="paragraph-anchor"></a><b>§8.1. </b>A token is "elastic" if it can match text of differing lengths, and
|
|
"inelastic" otherwise. For example, in English, <indefinite-article> is
|
|
elastic (it always matches a single word). If the first ptoken is inelastic,
|
|
we know it must match words 1 to \(L_1\) of whatever text is to be matched,
|
|
and we give it position 1; if the second is also inelastic, that will match
|
|
\(L_1+1\) to \(L_2\), and it gets position \(L_1+1\); and so on. As soon as we
|
|
hit an elastic token — a wildcard like <span class="extract"><span class="extract-syntax">...</span></span>, for example — this
|
|
predictability stops, and we can only assign position 0, which means that
|
|
we don't know.
|
|
</p>
|
|
|
|
<p class="commentary">Note that we only assign a nonzero position if we know where the ptoken both
|
|
starts and finishes; it's not enough just to know where it starts.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compute front-end ptoken positions</span><span class="named-paragraph-number">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">posn</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">first_pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">next_pt</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">last</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><a href="4-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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">posn</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> != </span><span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></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="identifier-syntax">posn</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">posn</span><span class="plain-syntax"> += </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></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="comment-syntax"> thus clearing any expired positions from earlier</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">posn</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-to.html#SP8">§8</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8_2" class="paragraph-anchor"></a><b>§8.2. </b>And similarly from the back end, if there are inelastic ptokens at the end
|
|
of the production (and which are separated from the front end by at least one
|
|
elastic one).
|
|
</p>
|
|
|
|
<p class="commentary">The following has quadratic running time in the number of tokens in the
|
|
production, but this is never larger than about 10.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compute back-end ptoken positions</span><span class="named-paragraph-number">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">posn</span><span class="plain-syntax"> = -1;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; ) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></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="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> don't use a back-end position if there's a front one</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><a href="4-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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">posn</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> != </span><span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></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="identifier-syntax">posn</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">posn</span><span class="plain-syntax"> -= </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prevt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prevt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">first_pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">prevt</span><span class="plain-syntax">; </span><span class="identifier-syntax">prevt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prevt</span><span class="plain-syntax">-></span><span class="element-syntax">next_pt</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prevt</span><span class="plain-syntax">-></span><span class="element-syntax">next_pt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">pt</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prevt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-to.html#SP8">§8</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8_3" class="paragraph-anchor"></a><b>§8.3. </b>So, then, a strut is a maximal sequence of one or more inelastic ptokens
|
|
each of which has no known position. (Clearly if one of them has a known
|
|
position then all of them have, but we're in no hurry so we don't exploit that.)
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compute struts within the production</span><span class="named-paragraph-number">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">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">no_struts</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">first_pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">next_pt</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></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><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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">no_struts</span><span class="plain-syntax"> >= </span><span class="constant-syntax">MAX_STRUTS_PER_PRODUCTION</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">struts</span><span class="plain-syntax">[</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">no_struts</span><span class="plain-syntax">] = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">strut_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">no_struts</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></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><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">pt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">strut_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">no_struts</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">strut_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">no_struts</span><span class="plain-syntax">] += </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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">next_pt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> should be impossible</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">next_pt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">no_struts</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-to.html#SP8">§8</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8_4" class="paragraph-anchor"></a><b>§8.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Work out which ptokens are fast</span><span class="named-paragraph-number">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">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">-></span><span class="element-syntax">first_pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">next_pt</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">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">pt</span><span class="plain-syntax">-></span><span class="element-syntax">range_starts</span><span class="plain-syntax"> < </span><span class="constant-syntax">0</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">range_ends</span><span class="plain-syntax"> < </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">.</span><span class="element-syntax">ptoken_is_fast</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-to.html#SP8">§8</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. Width and elasticity. </b>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.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax"> -1</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Optimiser::ptoken_width</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">Optimiser::ptoken_width</span></span>:<br/><a href="4-to.html#SP8_1">§8.1</a>, <a href="4-to.html#SP8_2">§8.2</a>, <a href="4-to.html#SP8_3">§8.3</a><br/>Preform - <a href="4-prf.html#SP1_3_2_1_4_4_2_3_1_3_1">§1.3.2.1.4.4.2.3.1.3.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">length_extremes</span><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">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"> != </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="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">PTOKEN_ELASTIC</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">.</span><span class="element-syntax">min_words</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-lp.html">❮</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-wm.html">1</a></li><li class="progresschapter"><a href="2-vcb.html">2</a></li><li class="progresschapter"><a href="3-lxr.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-ap.html">ap</a></li><li class="progresssection"><a href="4-nnt.html">nnt</a></li><li class="progresssection"><a href="4-lp.html">lp</a></li><li class="progresscurrent">to</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="progresssection"><a href="4-pu.html">pu</a></li><li class="progressnext"><a href="4-le.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|