1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 08:34:22 +03:00
inform7/docs/if-module/5-cg.html
2021-03-15 09:31:16 +00:00

637 lines
118 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Command Grammars</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="../assertions-module/index.html">assertions</a></li>
<li><a href="../values-module/index.html">values</a></li>
<li><a href="../knowledge-module/index.html">knowledge</a></li>
<li><a href="../imperative-module/index.html">imperative</a></li>
<li><a href="../runtime-module/index.html">runtime</a></li>
<li><a href="index.html"><span class="selectedlink">if</span></a></li>
<li><a href="../multimedia-module/index.html">multimedia</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>Services</h2><ul>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../calculus-module/index.html">calculus</a></li>
<li><a href="../html-module/index.html">html</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Command Grammars' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7</a></li><li><a href="index.html">if</a></li><li><a href="index.html#5">Chapter 5: Command Parser</a></li><li><b>Command Grammars</b></li></ul></div>
<p class="purpose">The possible command text following a command verb, or referring to a single concept or object, is gathered into a "command grammar".</p>
<ul class="toc"><li><a href="5-cg.html#SP4">&#167;4. Command words</a></li><li><a href="5-cg.html#SP10">&#167;10. Named grammar tokens</a></li><li><a href="5-cg.html#SP12">&#167;12. Consultation grammars</a></li><li><a href="5-cg.html#SP13">&#167;13. Subject parsing grammars</a></li><li><a href="5-cg.html#SP14">&#167;14. Data type parsing grammars</a></li><li><a href="5-cg.html#SP15">&#167;15. Property name parsing grammars</a></li><li><a href="5-cg.html#SP16">&#167;16. The list of grammar lines</a></li><li><a href="5-cg.html#SP19">&#167;19. Grammar Preparation</a></li><li><a href="5-cg.html#SP20">&#167;20. Phase I: Slash Grammar</a></li><li><a href="5-cg.html#SP21">&#167;21. Phase II: Determining Grammar</a></li><li><a href="5-cg.html#SP23">&#167;23. Kinds as CGs</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>Command grammars, or CGs, are used in six different settings:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">CG_IS_COMMAND</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> </span><span class="comment-syntax"> an imperative verbal command at run-time</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CG_IS_TOKEN</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax"> </span><span class="comment-syntax"> a square-bracketed token in other grammar</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CG_IS_SUBJECT</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax"> </span><span class="comment-syntax"> a noun phrase at run time: a name for an object</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CG_IS_VALUE</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax"> </span><span class="comment-syntax"> a noun phrase at run time: a name for a value</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CG_IS_CONSULT</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax"> </span><span class="comment-syntax"> a pattern to match in part of a command (such as "consult")</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CG_IS_PROPERTY_NAME</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax"> </span><span class="comment-syntax"> a noun phrase at run time: a name for an either/or pval</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>The following maxima are imposed by the I6 compiler:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_ALIASED_COMMANDS</span><span class="plain-syntax"> </span><span class="constant-syntax">32</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">MAX_LINES_PER_GRAMMAR</span><span class="plain-syntax"> </span><span class="constant-syntax">32</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">command_grammar</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">cg_is</span><span class="plain-syntax">; </span><span class="comment-syntax"> one of the </span><span class="extract"><span class="extract-syntax">CG_IS_*</span></span><span class="comment-syntax"> values above</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">where_cg_created</span><span class="plain-syntax">; </span><span class="comment-syntax"> for problem message reports</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">grammar_type</span><span class="plain-syntax"> </span><span class="identifier-syntax">cg_type</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">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_line</span><span class="plain-syntax">; </span><span class="comment-syntax"> linked list in creation order</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sorted_first_line</span><span class="plain-syntax">; </span><span class="comment-syntax"> and in logical applicability order</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">slashed</span><span class="plain-syntax">; </span><span class="comment-syntax"> slashing has been done</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">determined</span><span class="plain-syntax">; </span><span class="comment-syntax"> determination has been done</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">command</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">CG_IS_COMMAND</span></span><span class="comment-syntax">: what command verb this belongs to</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">aliased_command</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_ALIASED_COMMANDS</span><span class="plain-syntax">]; </span><span class="comment-syntax"> ...and other commands synonymous</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_aliased_commands</span><span class="plain-syntax">; </span><span class="comment-syntax"> ...and how many of them there are</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">name</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">CG_IS_TOKEN</span></span><span class="comment-syntax">: name of this token</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subj_understood</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">CG_IS_SUBJECT</span></span><span class="comment-syntax">: what this provides names for</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_understood</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">CG_IS_VALUE</span></span><span class="comment-syntax">: for which type it names an instance of</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn_understood</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">CG_IS_PROPERTY_NAME</span></span><span class="comment-syntax">: which prn this names</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">cg_compilation_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">compilation_data</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure command_grammar is accessed in 2/bd, 3/sm, 3/tp, 3/bck, 3/rgn, 3/tm, 3/scn, 3/ts, 4/act, 4/nap, 5/pp, 5/gpr and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>We begin as usual with a constructor and some debug log tracing.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="function-syntax">CommandGrammars::cg_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">CommandGrammars::cg_new</span></span>:<br/><a href="5-cg.html#SP5">&#167;5</a>, <a href="5-cg.html#SP10">&#167;10</a>, <a href="5-cg.html#SP12">&#167;12</a>, <a href="5-cg.html#SP13">&#167;13</a>, <a href="5-cg.html#SP14">&#167;14</a>, <a href="5-cg.html#SP15">&#167;15</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cg_is</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_type</span><span class="plain-syntax"> = </span><a href="5-gt2.html#SP2" class="function-link"><span class="function-syntax">UnderstandTokens::Types::new</span></a><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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg_is</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_aliased_commands</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_first_line</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">subj_understood</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_understood</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">prn_understood</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">where_cg_created</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slashed</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">determined</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">compilation_data</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RTCommandGrammars::new_compilation_data</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">cg</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">CommandGrammars::log</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">CommandGrammars::log</span></span>:<br/>IF Module - <a href="1-im.html#SP2">&#167;2</a>, <a href="1-im.html#SP2_3">&#167;2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</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;CG%d:"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</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">CG_IS_COMMAND:</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</span><span class="plain-syntax">)) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"command=no-verb verb"</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">"command=%W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CG_IS_TOKEN:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"token=%W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</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">CG_IS_SUBJECT:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"object"</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">CG_IS_VALUE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"value=%u"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_understood</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">CG_IS_CONSULT:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"consult"</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">CG_IS_PROPERTY_NAME:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"property-name"</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">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;unknown&gt;"</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="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>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Command words. </b>Some CGs are used to represent the command grammar for imperative verbs
used by the player at run-time. Such a CG handles multiple commands, which
are considered equivalent at run-time: the first of these is the official
command word, and the rest are "aliases". For instance, the Standard Rules
create a CG for the command PULL with one alias, DRAG. (This somewhat
asymmetric approach is used because it matches the way I6 <span class="extract"><span class="extract-syntax">Verb</span></span> declarations
are laid out.)
</p>
<p class="commentary">A complication is that one CG is permitted to be a special case: the
so-called "no verb verb", whose main command word is empty and which
can have no aliases. This is used to parse verbless commands at run-time:
for instance, the I7 designer can specify that a command consisting only
of a number followed by the word GO should cause some action, and this
is implemented not with a command verb but using I6's hooks for verbless
commands. The grammar "[number] go" is attached as a grammar line to
the "no verb verb", which is distinguished by having its command word
number set to <span class="extract"><span class="extract-syntax">-1</span></span>. Note that the "no verb verb" exists only in runs of
Inform where it has been needed: the Standard Rules do not use it.
</p>
<p class="commentary">Command CGs other than the "no verb verb" are said to be "genuinely
verbal".
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="function-syntax">CommandGrammars::get_verb_text</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">CommandGrammars::get_verb_text</span></span>:<br/>Command Grammar Lines - <a href="5-cgl.html#SP24">&#167;24</a>, <a href="5-cgl.html#SP25">&#167;25</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</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">CommandGrammars::cg_is_genuinely_verbal</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">CommandGrammars::cg_is_genuinely_verbal</span></span>:<br/><a href="5-cg.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> == </span><span class="constant-syntax">CG_IS_COMMAND</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</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="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>The next routine finds, or if necessary creates, a CG for a given command
word encountered without any indication that it should alias another. Note
that calling this with word number <span class="extract"><span class="extract-syntax">-1</span></span> finds, or creates, the "no verb
verb".
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="function-syntax">CommandGrammars::find_or_create_command</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">CommandGrammars::find_or_create_command</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP19_11">&#167;19.11</a></span></button><span class="plain-syntax">(</span><span class="identifier-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">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax"> = </span><a href="5-cg.html#SP6" class="function-link"><span class="function-syntax">CommandGrammars::find_command</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">cg</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax"> = </span><a href="5-cg.html#SP3" class="function-link"><span class="function-syntax">CommandGrammars::cg_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">CG_IS_COMMAND</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</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">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">iname</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">NO_VERB_VERB_DEFINED_HL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Emit::named_numeric_constant</span><span class="plain-syntax">(</span><span class="identifier-syntax">iname</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</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">global_compilation_settings</span><span class="plain-syntax">.</span><span class="identifier-syntax">no_verb_verb_exists</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR_CONSTRUCTION</span><span class="plain-syntax">, </span><span class="string-syntax">"CG%d has verb %W\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>By contrast, this routine merely finds a CG, or returns null if none
exists with the given command word.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="function-syntax">CommandGrammars::find_command</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">CommandGrammars::find_command</span></span>:<br/><a href="5-cg.html#SP5">&#167;5</a><br/>Understand Sentences - <a href="5-us.html#SP15_1">&#167;15.1</a>, <a href="5-us.html#SP15_2">&#167;15.2</a>, <a href="5-us.html#SP15_3">&#167;15.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-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">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</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">cg</span><span class="plain-syntax">, </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> == </span><span class="constant-syntax">CG_IS_COMMAND</span><span 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="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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cg</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">Wordings::match</span><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</span><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="identifier-syntax">cg</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="function-syntax">&lt;cg-&gt;</span><span class="element-syntax">no_aliased_commands</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">Wordings::match</span><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">aliased_command</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cg</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">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>We now have routines to add or remove commands from a given CG. Removing
is the tricky case, since detaching the main command word means that one
of the aliases must become the new main command; or, in the worst case,
that there are no commands left, in which case we need to empty the CG
of grammar lines so that it can either be ignored or re-used (in the
event that the designer, having cancelled the old meaning of the command,
now supplies new ones).
</p>
<p class="commentary">It is not possible to add to, or remove from, the "no verb verb".
</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">CommandGrammars::add_command</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">CommandGrammars::add_command</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP15_3">&#167;15.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="identifier-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">cg</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to add alias command to null CG"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> != </span><span class="constant-syntax">CG_IS_COMMAND</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to add alias command to non-command CG"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_aliased_commands</span><span class="plain-syntax"> == </span><span class="constant-syntax">MAX_ALIASED_COMMANDS</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_TooManyAliases</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this 'understand the command ... as ...' makes too many aliases "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"for the same command"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"exceeding the limit of 32."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">aliased_command</span><span class="plain-syntax">[</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_aliased_commands</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR</span><span class="plain-syntax">, </span><span class="string-syntax">"Adding alias '%W' to G%d '%W'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</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">CommandGrammars::remove_command</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">CommandGrammars::remove_command</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP15_1">&#167;15.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="identifier-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">cg</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to detach alias command from null CG"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> != </span><span class="constant-syntax">CG_IS_COMMAND</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to detach alias command from non-command CG"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR</span><span class="plain-syntax">, </span><span class="string-syntax">"Detaching verb '%W' from grammar\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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span 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::match</span><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR</span><span class="plain-syntax">, </span><span class="string-syntax">"Detached verb is the head-verb\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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_aliased_commands</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR</span><span class="plain-syntax">, </span><span class="string-syntax">"Which had no aliases: clearing grammar to NULL\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">aliased_command</span><span class="plain-syntax">[--(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_aliased_commands</span><span class="plain-syntax">)];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR</span><span class="plain-syntax">, </span><span class="string-syntax">"Which had aliases: making new head-verb '%W'\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR</span><span class="plain-syntax">, </span><span class="string-syntax">"Detached verb is one of the aliases\n"</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="function-syntax">&lt;cg-&gt;</span><span class="element-syntax">no_aliased_commands</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">Wordings::match</span><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">aliased_command</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">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">=</span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="function-syntax">&lt;cg-&gt;</span><span class="element-syntax">no_aliased_commands</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">aliased_command</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">aliased_command</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_aliased_commands</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<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">CommandGrammars::index_command_aliases</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_aliased_commands</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">n</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">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"/%N"</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">aliased_command</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">CommandGrammars::remove_action</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">CommandGrammars::remove_action</span></span>:<br/>Actions - <a href="4-act.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="reserved-syntax">action_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">an</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> != </span><span class="constant-syntax">CG_IS_COMMAND</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax"> = </span><a href="5-cgl.html#SP4" class="function-link"><span class="function-syntax">UnderstandLines::list_remove</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax">, </span><span class="identifier-syntax">an</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>A few imperative verbs are reserved for Inform testing, such as SHOWME.
We record those as instances of the following:
</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">reserved_command_verb</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reserved_text</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">reserved_command_verb</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure reserved_command_verb is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></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">CommandGrammars::reserve</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">verb_name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">reserved_command_verb</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rcv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">reserved_command_verb</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rcv</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reserved_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="5-cg.html#SP9" class="function-link"><span class="function-syntax">CommandGrammars::normalise_cv_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rcv</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reserved_text</span><span class="plain-syntax">, </span><span class="identifier-syntax">verb_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CommandsIndex::test_verb</span><span class="plain-syntax">(</span><span class="identifier-syntax">rcv</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reserved_text</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">CommandGrammars::command_verb_reserved</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">verb_tried</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">reserved_command_verb</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rcv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">normalised_vt</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="5-cg.html#SP9" class="function-link"><span class="function-syntax">CommandGrammars::normalise_cv_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">normalised_vt</span><span class="plain-syntax">, </span><span class="identifier-syntax">verb_tried</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">rcv</span><span class="plain-syntax">, </span><span class="reserved-syntax">reserved_command_verb</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">normalised_vt</span><span class="plain-syntax">, </span><span class="identifier-syntax">rcv</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reserved_text</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="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">normalised_vt</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CommandGrammars::normalise_cv_to</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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;31) &amp;&amp; (</span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">from</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">PUT</span><span class="plain-syntax">(</span><span class="identifier-syntax">Characters::tolower</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Named grammar tokens. </b>These are like text substitutions in reverse. For instance, we could define
a token "[suitable colour]". These are identified solely by their textual
names (e.g., "suitable colour").
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="function-syntax">CommandGrammars::named_token_new</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">CommandGrammars::named_token_new</span></span>:<br/><a href="5-cg.html#SP11">&#167;11</a><br/>Understand Sentences - <a href="5-us.html#SP19_11">&#167;19.11</a></span></button><span class="plain-syntax">(</span><span class="identifier-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">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax"> = </span><a href="5-cg.html#SP10" class="function-link"><span class="function-syntax">CommandGrammars::named_token_by_name</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">cg</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">cg</span><span class="plain-syntax"> = </span><a href="5-cg.html#SP3" class="function-link"><span class="function-syntax">CommandGrammars::cg_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">CG_IS_TOKEN</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</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">RTCommandGrammars::new_CG_IS_TOKEN</span><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="function-syntax">CommandGrammars::named_token_by_name</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">CommandGrammars::named_token_by_name</span></span>:<br/><a href="5-cg.html#SP11">&#167;11</a><br/>Grammar Tokens - <a href="5-gt.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="identifier-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">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</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">cg</span><span class="plain-syntax">, </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> == </span><span class="constant-syntax">CG_IS_TOKEN</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Wordings::match</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</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">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>A slight variation is provided by those which are defined by I6 routines.
</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">CommandGrammars::translates</span><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax"> = </span><a href="5-cg.html#SP10" class="function-link"><span class="function-syntax">CommandGrammars::named_token_by_name</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">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_GrammarTranslatedAlready</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this grammar token has already been translated"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"so there must be some duplication somewhere."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax"> = </span><a href="5-cg.html#SP10" class="function-link"><span class="function-syntax">CommandGrammars::named_token_new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RTCommandGrammars::set_CG_IS_TOKEN_identifier</span><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p2</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Consultation grammars. </b>These are used for grammar included as a column of a table or in a
conditional match. The terminology goes back to the early days of I6, when
CONSULT was a command capable of parsing arbitrary text, something which
a game called Curses made heavy use of.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="function-syntax">CommandGrammars::consultation_new</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">CommandGrammars::consultation_new</span></span>:<br/>General Parsing Routines - <a href="5-gpr.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="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax"> = </span><a href="5-cg.html#SP3" class="function-link"><span class="function-syntax">CommandGrammars::cg_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">CG_IS_CONSULT</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">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Subject parsing grammars. </b>Each inference subject can optionally have a CG, used to parse unusual forms of
its name (though of course many subjects are never parsed at all, so this is
only used in practice for objects and their kinds). The following routine finds
or creates such.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="function-syntax">CommandGrammars::for_subject</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">CommandGrammars::for_subject</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP19_11">&#167;19.11</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subj</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PARSING_DATA_FOR_SUBJ</span><span class="plain-syntax">(</span><span class="identifier-syntax">subj</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">understand_as_this_object</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">PARSING_DATA_FOR_SUBJ</span><span class="plain-syntax">(</span><span class="identifier-syntax">subj</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">understand_as_this_object</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax"> = </span><a href="5-cg.html#SP3" class="function-link"><span class="function-syntax">CommandGrammars::cg_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">CG_IS_SUBJECT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PARSING_DATA_FOR_SUBJ</span><span class="plain-syntax">(</span><span class="identifier-syntax">subj</span><span class="plain-syntax">)-&gt;</span><span class="identifier-syntax">understand_as_this_object</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">subj_understood</span><span class="plain-syntax"> = </span><span class="identifier-syntax">subj</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">cg</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">CommandGrammars::take_out_one_word_grammar</span><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> != </span><span class="constant-syntax">CG_IS_SUBJECT</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">"One-word optimisation applies only to objects"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax"> = </span><a href="5-cgl.html#SP10" class="function-link"><span class="function-syntax">UnderstandLines::list_take_out_one_word_grammar</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</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">CommandGrammars::allow_mixed_lines</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">CommandGrammars::allow_mixed_lines</span></span>:<br/>Command Grammar Lines - <a href="5-cgl.html#SP13">&#167;13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> == </span><span class="constant-syntax">CG_IS_SUBJECT</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> == </span><span class="constant-syntax">CG_IS_VALUE</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="SP14" class="paragraph-anchor"></a><b>&#167;14. Data type parsing grammars. </b>Each kind can optionally have a CG, used to parse unusual forms of
its literals. The following routine finds or creates this.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="function-syntax">CommandGrammars::for_kind</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">CommandGrammars::for_kind</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP19_11">&#167;19.11</a></span></button><span class="plain-syntax">(</span><span class="identifier-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="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-cg.html#SP23" class="function-link"><span class="function-syntax">CommandGrammars::get_parsing_grammar</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</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">return</span><span class="plain-syntax"> </span><a href="5-cg.html#SP23" class="function-link"><span class="function-syntax">CommandGrammars::get_parsing_grammar</span></a><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">cg</span><span class="plain-syntax"> = </span><a href="5-cg.html#SP3" class="function-link"><span class="function-syntax">CommandGrammars::cg_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">CG_IS_VALUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="5-cg.html#SP23" class="function-link"><span class="function-syntax">CommandGrammars::set_parsing_grammar</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_understood</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K</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">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Property name parsing grammars. </b>Only either/or properties can have a CG, used to parse unusual forms of
the alternatives as used when properties are describing objects. The
following routine finds or creates this for a given property.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="function-syntax">CommandGrammars::for_prn</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">CommandGrammars::for_prn</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP19_11">&#167;19.11</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">EitherOrProperties::get_parsing_grammar</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">EitherOrProperties::get_parsing_grammar</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax"> = </span><a href="5-cg.html#SP3" class="function-link"><span class="function-syntax">CommandGrammars::cg_new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">CG_IS_PROPERTY_NAME</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EitherOrProperties::set_parsing_grammar</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">prn_understood</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RTCommandGrammars::new_CG_IS_PROPERTY_NAME</span><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="identifier-syntax">prn</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">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. The list of grammar lines. </b>Every CG has a list of GLs: indeed, this list is really the grammar. Here
we test this for emptiness, and provide for adding to it. Removals are not
possible.
</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">CommandGrammars::is_empty</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">CommandGrammars::is_empty</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP15_2">&#167;15.2</a><br/>General Parsing Routines - <a href="5-gpr.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cg</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CommandGrammars::add_line</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">CommandGrammars::add_line</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP19">&#167;19</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR</span><span class="plain-syntax">, </span><span class="string-syntax">"Adding grammar line $g to verb $G\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> == </span><span class="constant-syntax">CG_IS_COMMAND</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="5-cgl.html#SP4" class="function-link"><span class="function-syntax">UnderstandLines::list_length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">MAX_LINES_PER_GRAMMAR</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_TooManyGrammarLines</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this command verb now has too many Understand possibilities"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that is, there are too many 'Understand \"whatever ...\" as ...' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which share the same initial word 'whatever'. The best way to "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"get around this is to try to consolidate some of those lines "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"together, perhaps by using slashes to combine alternative "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"wordings, or by defining new grammar tokens [in square brackets]."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax"> = </span><a href="5-cgl.html#SP4" class="function-link"><span class="function-syntax">UnderstandLines::list_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. </b>Each CG has the potential to carry a kind made up of the number of
values produced, and what their types are. This is only really meaningful
for the CGs trying to express a single value: the following routine returns
<span class="extract"><span class="extract-syntax">UNKNOWN_NT</span></span> unless that's the case.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">CommandGrammars::get_data_type_as_token</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">CommandGrammars::get_data_type_as_token</span></span>:<br/>Grammar Tokens - <a href="5-gt.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="5-gt2.html#SP3" class="function-link"><span class="function-syntax">UnderstandTokens::Types::get_data_type_as_token</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_type</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b>Some tokens require suitable I6 routines to have already been compiled,
if they are to work nicely: the following routine goes through the tokens
by exploring each CG in turn.
</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">CommandGrammars::compile_conditions</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">CommandGrammars::compile_conditions</span></span>:<br/>Parsing Plugin - <a href="5-pp.html#SP2">&#167;2</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">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</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">cg</span><span class="plain-syntax">, </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">where_cg_created</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="5-cgl.html#SP5" class="function-link"><span class="function-syntax">UnderstandLines::line_list_compile_condition_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. Grammar Preparation. </b>This simply causes Phases I and II of grammar processing to take place, one
after the other.
</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">CommandGrammars::prepare</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">CommandGrammars::prepare</span></span>:<br/>Parsing Plugin - <a href="5-pp.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="5-cg.html#SP20" class="function-link"><span class="function-syntax">CommandGrammars::cg_slash_all</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="5-cg.html#SP21" class="function-link"><span class="function-syntax">CommandGrammars::cg_determine_all</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. Phase I: Slash Grammar. </b>Slashing is really a grammar-line based activity, so we do no more than
pass the buck down to the list of grammar lines.
</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">CommandGrammars::cg_slash_all</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">CommandGrammars::cg_slash_all</span></span>:<br/><a href="5-cg.html#SP19">&#167;19</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">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Log::new_stage</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Slashing grammar (G1)"</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">cg</span><span class="plain-syntax">, </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slashed</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR_CONSTRUCTION</span><span class="plain-syntax">, </span><span class="string-syntax">"Slashing $G\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="5-cgl.html#SP11" class="function-link"><span class="function-syntax">UnderstandLines::line_list_slash</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slashed</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>
</pre>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. Phase II: Determining Grammar. </b>Again, at this top level we are really only calling downwards.
</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">CommandGrammars::cg_determine_all</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">CommandGrammars::cg_determine_all</span></span>:<br/><a href="5-cg.html#SP19">&#167;19</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">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Log::new_stage</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Determining grammar (G2)"</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">cg</span><span class="plain-syntax">, </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">determined</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">where_cg_created</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="5-cg.html#SP21" class="function-link"><span class="function-syntax">CommandGrammars::determine</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">determined</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="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">CommandGrammars::determine</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">CommandGrammars::determine</span></span>:<br/>Grammar Tokens - <a href="5-gt.html#SP10_1">&#167;10.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</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">spec_union</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">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">where_cg_created</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-gt2.html#SP3" class="function-link"><span class="function-syntax">UnderstandTokens::Types::has_return_type</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_type</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="5-gt2.html#SP3" class="function-link"><span class="function-syntax">UnderstandTokens::Types::get_single_type</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_type</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">depth</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NUMBER_CREATED</span><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_GrammarIllFounded</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"grammar tokens are not allowed to be defined in terms of "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"themselves"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"either directly or indirectly."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR_CONSTRUCTION</span><span class="plain-syntax">, </span><span class="string-syntax">"Determining $G\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">spec_union</span><span class="plain-syntax"> = </span><a href="5-cgl.html#SP13" class="function-link"><span class="function-syntax">UnderstandLines::line_list_determine</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><a href="5-cg.html#SP4" class="function-link"><span class="function-syntax">CommandGrammars::cg_is_genuinely_verbal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR_CONSTRUCTION</span><span class="plain-syntax">, </span><span class="string-syntax">"Result of verb $G is $P\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="identifier-syntax">spec_union</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="5-gt2.html#SP3" class="function-link"><span class="function-syntax">UnderstandTokens::Types::set_single_type</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_type</span><span class="plain-syntax">), </span><span class="identifier-syntax">spec_union</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">spec_union</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>Note that some grammars are
compiled more than once (if a red ball and a blue ball are both of kind
ball, then compiling grammars for them will also involve compiling grammars
for the ball in each case: see above), so the following routine may well be
called more than once for the same CG. We only want to sort once, though, 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">CommandGrammars::sort_command_grammar</span><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_first_line</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">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_first_line</span><span class="plain-syntax"> = </span><a href="5-cgl.html#SP15" class="function-link"><span class="function-syntax">UnderstandLines::list_sort</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. Kinds as CGs. </b>If the user writes lines in the source text such as
</p>
<blockquote>
<p>Understand "eleventy-one" as 111.</p>
</blockquote>
<p class="commentary">then grammar lines will have to be attached to a kind; in fact, a kind can
have its own <span class="extract"><span class="extract-syntax">command_grammar</span></span> structure attached, which holds a sequence of
such grammar lines. (These are possibilities in addition to those provided
by any GPR existing because of the above routines.)
</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">CommandGrammars::set_parsing_grammar</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">CommandGrammars::set_parsing_grammar</span></span>:<br/><a href="5-cg.html#SP14">&#167;14</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"wrong way to handle object grammar"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">construct</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">understand_as_values</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="function-syntax">CommandGrammars::get_parsing_grammar</span><button class="popup" onclick="togglePopup('usagePopup26')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup26">Usage of <span class="code-font"><span class="function-syntax">CommandGrammars::get_parsing_grammar</span></span>:<br/><a href="5-cg.html#SP14">&#167;14</a><br/>Tokens Parsing Values - <a href="5-tpv.html#SP1">&#167;1</a>, <a href="5-tpv.html#SP1_1">&#167;1.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"wrong way to handle object grammar"</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">K</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">construct</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">understand_as_values</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="5-us.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-im.html">1</a></li><li class="progresschapter"><a href="2-bd.html">2</a></li><li class="progresschapter"><a href="3-sm.html">3</a></li><li class="progresschapter"><a href="4-ap.html">4</a></li><li class="progresscurrentchapter">5</li><li class="progresssection"><a href="5-pp.html">pp</a></li><li class="progresssection"><a href="5-pnaa.html">pnaa</a></li><li class="progresssection"><a href="5-us.html">us</a></li><li class="progresscurrent">cg</li><li class="progresssection"><a href="5-cgl.html">cgl</a></li><li class="progresssection"><a href="5-gt.html">gt</a></li><li class="progresssection"><a href="5-gt2.html">gt2</a></li><li class="progresssection"><a href="5-gp.html">gp</a></li><li class="progresssection"><a href="5-nft.html">nft</a></li><li class="progresssection"><a href="5-tpv.html">tpv</a></li><li class="progresssection"><a href="5-gpr.html">gpr</a></li><li class="progressnext"><a href="5-cgl.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>