1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 10:04:21 +03:00
inform7/docs/core-module/8-rs.html
2020-08-25 21:47:14 +01:00

1621 lines
285 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Rule Subtrees</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Preform-Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul><h2>Compiler Webs</h2><ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul><h2>Inbuild Modules</h2><ul>
<li><a href="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
<li><a href="index.html"><span class="selectedlink">core</span></a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../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 'Rule Subtrees' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">core</a></li><li><a href="index.html#8">Chapter 8: Sentences</a></li><li><b>Rule Subtrees</b></li></ul></div>
<p class="purpose">To tidy up |INVOCATION_LIST_NT| nodes into a list of children under the relevant |RULE_NT| node, and so turn each rule definition into a single subtree.</p>
<ul class="toc"><li><a href="8-rs.html#SP5">&#167;5. Parsing Routine Structure</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>Initially, the phrases (<span class="extract"><span class="extract-syntax">INVOCATION_LIST_NT</span></span>) making up a rule (<span class="extract"><span class="extract-syntax">RULE_NT</span></span>) are
simply listed after it in the parse tree, but we want them to become its
children: this is the only thing the \(A\)-grammar does with rules, which
otherwise wait until later to be dealt with.
</p>
<p class="commentary">The code in this section accomplishes the regrouping: after it runs, every
<span class="extract"><span class="extract-syntax">INVOCATION_LIST_NT</span></span> is a child of the <span class="extract"><span class="extract-syntax">RULE_NT</span></span> header to which it belongs.
</p>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>This routine is used whenever new material is added. Whenever it finds a
childless <span class="extract"><span class="extract-syntax">RULE_NT</span></span> followed by a sequence of <span class="extract"><span class="extract-syntax">INVOCATION_LIST_NT</span></span> nodes, it
joins these in sequence as children of the <span class="extract"><span class="extract-syntax">RULE_NT</span></span>. Since it always
acts so as to leave a non-zero number of children, and since it acts only
on childless nodes, it cannot ever act on the same node twice.
</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">RuleSubtrees::register_recently_lexed_phrases</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">RuleSubtrees::register_recently_lexed_phrases</span></span>:<br/>Literal Patterns - <a href="6-lp.html#SP33">&#167;33</a>, <a href="6-lp.html#SP34">&#167;34</a><br/>Measurement Adjectives - <a href="15-ma.html#SP10_4">&#167;10.4</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">; </span><span class="comment-syntax"> for then the tree is perhaps broken anyway</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">SyntaxTree::traverse</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><a href="8-rs.html#SP3" class="function-link"><span class="function-syntax">RuleSubtrees::demote_command_nodes</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">SyntaxTree::traverse</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><a href="8-rs.html#SP4" class="function-link"><span class="function-syntax">RuleSubtrees::detect_loose_command_nodes</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>Command nodes are demoted to be children of routine nodes:
</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">RuleSubtrees::demote_command_nodes</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">RuleSubtrees::demote_command_nodes</span></span>:<br/><a href="8-rs.html#SP2">&#167;2</a><br/>Passes through Major Nodes - <a href="3-ptmn.html#SP3_1_1">&#167;3.1.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) == </span><span class="identifier-syntax">RULE_NT</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">end_def</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">end_def</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">end_def</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) == </span><span class="identifier-syntax">INVOCATION_LIST_NT</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">end_def</span><span class="plain-syntax"> = </span><span class="identifier-syntax">end_def</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> == </span><span class="identifier-syntax">end_def</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">RULE_NT</span></span><span class="comment-syntax"> not followed by any </span><span class="extract"><span class="extract-syntax">INVOCATION_LIST_NT</span></span><span class="comment-syntax">s</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> splice so that </span><span class="extract"><span class="extract-syntax">p-&gt;next</span></span><span class="comment-syntax"> to </span><span class="extract"><span class="extract-syntax">end_def</span></span><span class="comment-syntax"> become the children of </span><span class="extract"><span class="extract-syntax">p</span></span><span class="comment-syntax">:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">end_def</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">end_def</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="8-rs.html#SP5" class="function-link"><span class="function-syntax">RuleSubtrees::parse_routine_structure</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</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. </b>And just in case:
</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">RuleSubtrees::detect_loose_command_nodes</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">RuleSubtrees::detect_loose_command_nodes</span></span>:<br/><a href="8-rs.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) == </span><span class="identifier-syntax">INVOCATION_LIST_NT</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">"loose COMMAND node outside of rule definition"</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. Parsing Routine Structure. </b>There are now two possible syntaxes to express the structural makeup of a
routine. Traditional I7 syntax for blocks is to place them within begin/end
markers: the "begin" occurring at the end of the conditional or loop header,
and the "end if", "end while", etc., as a phrase of its own at the end of
the block. Newer I7 syntax (March 2008) is to use Python-style colons and
indentation. Both are allowed, but not in the same routine.
</p>
<p class="commentary">This routine opens with the routine's parse tree consisting of a simple
linked list of code-point nodes, one for each phrase. We must work out
which syntax is used, decipher it, and turn the list into a proper tree
structure in a single unified format.
</p>
<p class="commentary">How much simpler this would all be if we could abolish the old format, but
it's kept for the benefit of partially sighted users, who find tabbed
indentation difficult to manage with screen-readers.
</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">RuleSubtrees::parse_routine_structure</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">RuleSubtrees::parse_routine_structure</span></span>:<br/><a href="8-rs.html#SP3">&#167;3</a><br/>Text Substitutions - <a href="17-ts.html#SP11_1">&#167;11.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">routine_node</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">initial_problem_count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">problem_count</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">uses_colon_syntax</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">uses_begin_end_syntax</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mispunctuates_begin_end_syntax</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">requires_colon_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">(a.1) See which block syntax is used by conditionals and loops</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_2" class="named-paragraph-link"><span class="named-paragraph">(a.2) Report problems if the two syntaxes are mixed up with each other</span><span class="named-paragraph-number">5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</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">uses_colon_syntax</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_3" class="named-paragraph-link"><span class="named-paragraph">(b.1) Annotate the parse tree with indentation levels</span><span class="named-paragraph-number">5.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_4" class="named-paragraph-link"><span class="named-paragraph">(b.2) Annotate the parse tree with control structure usage</span><span class="named-paragraph-number">5.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_5" class="named-paragraph-link"><span class="named-paragraph">(c) Expand comma notation for blocks</span><span class="named-paragraph-number">5.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</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">uses_colon_syntax</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6" class="named-paragraph-link"><span class="named-paragraph">(d) Insert end nodes and check the indentation</span><span class="named-paragraph-number">5.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_7" class="named-paragraph-link"><span class="named-paragraph">(e) Structure the parse tree to match the use of control structures</span><span class="named-paragraph-number">5.7</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_8" class="named-paragraph-link"><span class="named-paragraph">(f) Police the structure of the parse tree</span><span class="named-paragraph-number">5.8</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_9" class="named-paragraph-link"><span class="named-paragraph">(g) Optimise out the otherwise if nodes</span><span class="named-paragraph-number">5.9</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_11" class="named-paragraph-link"><span class="named-paragraph">(h) Remove any end markers as no longer necessary</span><span class="named-paragraph-number">5.11</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</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">uses_colon_syntax</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_13" class="named-paragraph-link"><span class="named-paragraph">(i) Remove any begin markers as no longer necessary</span><span class="named-paragraph-number">5.13</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_15" class="named-paragraph-link"><span class="named-paragraph">(j) Insert code block nodes so that nodes needing to be parsed are childless</span><span class="named-paragraph-number">5.15</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_17" class="named-paragraph-link"><span class="named-paragraph">(k) Insert instead marker nodes</span><span class="named-paragraph-number">5.17</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_19" class="named-paragraph-link"><span class="named-paragraph">(l) Break up say phrases</span><span class="named-paragraph-number">5.19</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_1" class="paragraph-anchor"></a><b>&#167;5.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(a.1) See which block syntax is used by conditionals and loops</span><span class="named-paragraph-number">5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ControlStructures::detect</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</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">syntax_used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">colon_block_command_ANNOT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">syntax_used</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) { </span><span class="comment-syntax"> i.e., doesn't end with a colon</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> don't count "if x is 1, let y be 2" &mdash; with no block &mdash; as deciding it</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (!(</span><span class="function-syntax">&lt;phrase-beginning-block&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)))))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">syntax_used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">syntax_used</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">syntax_used</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_1_1" class="named-paragraph-link"><span class="named-paragraph">Note what looks like a begin-end piece of syntax</span><span class="named-paragraph-number">5.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">requires_new_syntax</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">requires_colon_syntax</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">requires_colon_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ControlStructures::detect_end</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">uses_begin_end_syntax</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">uses_begin_end_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_1_1" class="paragraph-anchor"></a><b>&#167;5.1.1. </b>It's possible in oddball cases to mis-punctuate such as to fool us, so:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Note what looks like a begin-end piece of syntax</span><span class="named-paragraph-number">5.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">uses_begin_end_syntax</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">mispunctuates_begin_end_syntax</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="function-syntax">&lt;phrase-beginning-block&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uses_begin_end_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mispunctuates_begin_end_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_1">&#167;5.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2" class="paragraph-anchor"></a><b>&#167;5.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(a.2) Report problems if the two syntaxes are mixed up with each other</span><span class="named-paragraph-number">5.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">mispunctuates_begin_end_syntax</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">routine_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">mispunctuates_begin_end_syntax</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BadOldSyntax</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The rule or phrase definition %1 seems to use indentation and "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"colons to group phrases together into 'if', 'repeat' or 'while' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"blocks. That's fine, but then this phrase seems to be missing "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"some punctuation - %2. Perhaps a colon is missing?"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">uses_begin_end_syntax</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">routine_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">uses_begin_end_syntax</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BothBlockSyntaxes</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The rule or phrase definition %1 seems to use both ways of grouping "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"phrases together into 'if', 'repeat' and 'while' blocks at once. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Inform allows two alternative forms, but they cannot be mixed in "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the same definition. %POne way is to end the 'if', 'repeat' or "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'while' phrases with a 'begin', and then to match that with an "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'end if' or similar. ('Otherwise' or 'otherwise if' clauses are "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"phrases like any other, and end with semicolons in this case.) "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"You use this begin/end form here, for instance - %3. %P"</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The other way is to end with a colon ':' and then indent the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"subsequent phrases underneath, using tabs. (Note that any "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'otherwise' or 'otherwise if' clauses also have to end with "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"colons in this case.) You use this indented form here - %2."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">requires_colon_syntax</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">uses_begin_end_syntax</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">routine_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">requires_colon_syntax</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NotInOldSyntax</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The construction %2, in the rule or phrase definition %1, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"is only allowed if the rule is written in the 'new' format, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that is, with the phrases written one to a line with "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"indentation showing how they are grouped together, and "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"with colons indicating the start of such a group."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</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>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_3" class="paragraph-anchor"></a><b>&#167;5.3. </b>If we're using Pythonesque notation, then the number of tab stops of
indentation of a phrase tells us where it belongs in the structure, so
we mark up the tree with that information.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(b.1) Annotate the parse tree with indentation levels</span><span class="named-paragraph-number">5.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Lexer::indentation_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">))));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</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">Lexer::indentation_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_4" class="paragraph-anchor"></a><b>&#167;5.4. </b>Note that we are a little cautious about recognising phrases which will
open blocks, such as "repeat...", because of the dangers of false positives;
so we look for the "begin" keyword, or the colon. We're less cautious with
subordinate phrases (such as "otherwise") because we know their wonding
more certainly, and similarly for "end X" phrases.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(b.2) Annotate the parse tree with control structure usage</span><span class="named-paragraph-number">5.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ControlStructures::detect</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">colon_block_command_ANNOT</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="function-syntax">&lt;phrase-beginning-block&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">csp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">case_CSP</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_4_1" class="named-paragraph-link"><span class="named-paragraph">Trim a switch case to just the case value</span><span class="named-paragraph-number">5.4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ControlStructures::detect_end</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) </span><span class="identifier-syntax">Node::set_end_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">csp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_4_1" class="paragraph-anchor"></a><b>&#167;5.4.1. </b>At this point anything at all can be a case value: it won't be parsed
or type-checked until compilation.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Trim a switch case to just the case value</span><span class="named-paragraph-number">5.4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;control-structure-phrase&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_4">&#167;5.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_5" class="paragraph-anchor"></a><b>&#167;5.5. </b>"Comma notation" is when a comma is used in an "if" statement to divide
off only a single consequential phrase, as in
</p>
<blockquote>
<p>if the hat is worn, try dropping the hat;</p>
</blockquote>
<p class="commentary">Such a line occupies a single node in its routine's parse tree, and we need
to break this up.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(c) Expand comma notation for blocks</span><span class="named-paragraph-number">5.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</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">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ControlStructures::detect</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">if_CSP</span><span class="plain-syntax">) &amp;&amp; (</span><span class="function-syntax">&lt;phrase-with-comma-notation&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_5_1" class="named-paragraph-link"><span class="named-paragraph">Effect a comma expansion</span><span class="named-paragraph-number">5.5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_5_1" class="paragraph-anchor"></a><b>&#167;5.5.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Effect a comma expansion</span><span class="named-paragraph-number">5.5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">BCW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;phrase-with-comma-notation&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">); </span><span class="comment-syntax"> text before the comma</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">ACW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;phrase-with-comma-notation&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">); </span><span class="comment-syntax"> text after the comma</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> First trim and annotate the "if ..." part</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">colon_block_command_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">); </span><span class="comment-syntax"> it previously had no colon...</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">csp</span><span class="plain-syntax">); </span><span class="comment-syntax"> ...and therefore didn't have its CSP set</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">BCW</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Now make a new node for the "then" part, indenting it one step inward</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">then_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">INVOCATION_LIST_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">then_node</span><span class="plain-syntax">, </span><span class="constant-syntax">results_from_splitting_ANNOT</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">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">then_node</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</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">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">then_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">ACW</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">last_node_of_if_construction</span><span class="plain-syntax"> = </span><span class="identifier-syntax">then_node</span><span class="plain-syntax">, *</span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Attach the "then" node after the "if" node:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">then_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_5_1_1" class="named-paragraph-link"><span class="named-paragraph">Deal with an immediately following otherwise node, if there is one</span><span class="named-paragraph-number">5.5.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">uses_colon_syntax</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">last_node_of_if_construction</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><a href="8-rs.html#SP8" class="function-link"><span class="function-syntax">RuleSubtrees::end_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_node_of_if_construction</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_routine</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">last_node_of_if_construction</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_5">&#167;5.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_5_1_1" class="paragraph-anchor"></a><b>&#167;5.5.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Deal with an immediately following otherwise node, if there is one</span><span class="named-paragraph-number">5.5.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">uses_colon_syntax</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">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</span><span class="plain-syntax">) ==</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">) == </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_5_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Deal with an immediately following otherwise</span><span class="named-paragraph-number">5.5.1.1.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ControlStructures::abbreviated_otherwise</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_5_1_1_2" class="named-paragraph-link"><span class="named-paragraph">Deal with an abbreviated otherwise node</span><span class="named-paragraph-number">5.5.1.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_5_1">&#167;5.5.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_5_1_1_1" class="paragraph-anchor"></a><b>&#167;5.5.1.1.1. </b>We string a plain "otherwise" node onto the "if" construction.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Deal with an immediately following otherwise</span><span class="named-paragraph-number">5.5.1.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">then_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_node_of_if_construction</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last_node_of_if_construction</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_5_1_1">&#167;5.5.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_5_1_1_2" class="paragraph-anchor"></a><b>&#167;5.5.1.1.2. </b>An abbreviated otherwise clause looks like this:
</p>
<blockquote>
<p>otherwise award 4 points;</p>
</blockquote>
<p class="commentary">and we want to split this, too, into distinct nodes.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Deal with an abbreviated otherwise node</span><span class="named-paragraph-number">5.5.1.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="constant-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">, </span><span class="constant-syntax">results_from_splitting_ANNOT</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">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Wordings::one_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">)))); </span><span class="comment-syntax"> extract just the word "otherwise"</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">then_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Wordings::trim_first_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">))); </span><span class="comment-syntax"> to remove the "otherwise"</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</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">last_node_of_if_construction</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_routine</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_5_1_1">&#167;5.5.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6" class="paragraph-anchor"></a><b>&#167;5.6. </b>If the old-style syntax is used, there are explicit "end if", "end repeat"
and "end while" nodes in the list already. But if the Pythonesque syntax is
used then we need to create these nodes and insert them into the list; we
do these by reading off the structure from the pattern of indentation. It's
quite a long task, since this pattern may contain errors, which we have to
report more or less helpfully.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(d) Insert end nodes and check the indentation</span><span class="named-paragraph-number">5.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev</span><span class="plain-syntax">, *</span><span class="identifier-syntax">run_on_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_misaligned_phrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">first_overindented_phrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">, </span><span class="identifier-syntax">indent</span><span class="plain-syntax">, </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">indent_misalign</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">indent_overmuch</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">just_opened_block</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> the blocks open stack holds blocks currently open</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">blstack_opening_phrase</span><span class="plain-syntax">[</span><span class="identifier-syntax">GROSS_AMOUNT_OF_INDENTATION</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">GROSS_AMOUNT_OF_INDENTATION</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">blstack_stage</span><span class="plain-syntax">[</span><span class="identifier-syntax">GROSS_AMOUNT_OF_INDENTATION</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for failing to start flush on the left margin</span><span class="named-paragraph-number">5.6.1</span></a></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">prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">=1; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_2" class="named-paragraph-link"><span class="named-paragraph">Determine actual indentation of this phrase</span><span class="named-paragraph-number">5.6.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_3" class="named-paragraph-link"><span class="named-paragraph">Compare actual indentation to what we expect from structure so far</span><span class="named-paragraph-number">5.6.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_4" class="named-paragraph-link"><span class="named-paragraph">Insert begin marker and increase expected indentation if a block begins here</span><span class="named-paragraph-number">5.6.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_5" class="named-paragraph-link"><span class="named-paragraph">Try closing blocks to bring expected indentation down to match</span><span class="named-paragraph-number">5.6.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">indent_overmuch</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_7" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for an excess of indentation</span><span class="named-paragraph-number">5.6.7</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">run_on_at</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_8" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for run-ons within phrase definition</span><span class="named-paragraph-number">5.6.8</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">indent_misalign</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_6" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for misaligned indentation</span><span class="named-paragraph-number">5.6.6</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_1" class="paragraph-anchor"></a><b>&#167;5.6.1. </b>Controversially:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for failing to start flush on the left margin</span><span class="named-paragraph-number">5.6.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NonflushRule</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The phrase or rule definition %1 is written using tab indentations "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to show how its phrases are to be grouped together. But in that "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"case the opening line needs to be on the left margin, not indented."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6">&#167;5.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_2" class="paragraph-anchor"></a><b>&#167;5.6.2. </b>Here we set <span class="extract"><span class="extract-syntax">indent</span></span> to the number of tab-stops in from the margin, or to
<span class="extract"><span class="extract-syntax">expected_indent</span></span> if the text does not appear to be at the start of its own
line in the source (because it runs on from a previous phrase, in
which case we set the <span class="extract"><span class="extract-syntax">run_on_at</span></span> flag: except for following on from cases
in switches with a non-control-structure, which is allowed, because otherwise
the lines often look silly and short).
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Determine actual indentation of this phrase</span><span class="named-paragraph-number">5.6.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::break_before</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'\n'</span><span class="plain-syntax">: </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'\t'</span><span class="plain-syntax">: </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</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="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">prev</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">csp</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">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pcsp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">prev</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pcsp</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pcsp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allow_run_on</span><span class="plain-syntax">)) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">results_from_splitting_ANNOT</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">run_on_at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">run_on_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">indent</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">GROSS_AMOUNT_OF_INDENTATION</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_2_1" class="named-paragraph-link"><span class="named-paragraph">Record an excess of indentation</span><span class="named-paragraph-number">5.6.2.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6">&#167;5.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_3" class="paragraph-anchor"></a><b>&#167;5.6.3. </b>We now know the <span class="extract"><span class="extract-syntax">indent</span></span> level of the line as read, and also the
<span class="extract"><span class="extract-syntax">expected_indent</span></span> given the definition so far. If they agree, fine. If they
don't agree, it isn't necessarily bad news &mdash; if each line's indentation were
a function of the last, there would be no information in it, after all.
Roughly speaking, when <span class="extract"><span class="extract-syntax">indent</span></span> is greater than we expect, that must be
wrong &mdash; it means indentation has jumped inward as if to open a new block,
but blocks are opened explicitly and not by simply raising the indent.
But when <span class="extract"><span class="extract-syntax">indent</span></span> is less than we expect, this may simply mean that the
current block(s) has or have been closed, because blocks are indeed closed
implicitly just by moving the indentation back in.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compare actual indentation to what we expect from structure so far</span><span class="named-paragraph-number">5.6.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">indent</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_3_3" class="named-paragraph-link"><span class="named-paragraph">Record a misalignment of indentation</span><span class="named-paragraph-number">5.6.3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_3_2" class="named-paragraph-link"><span class="named-paragraph">Record a phrase within current block</span><span class="named-paragraph-number">5.6.3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_3_1" class="named-paragraph-link"><span class="named-paragraph">Compare actual indentation to what we expect for an intermediate phrase</span><span class="named-paragraph-number">5.6.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">just_opened_block</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">indent</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_3_3" class="named-paragraph-link"><span class="named-paragraph">Record a misalignment of indentation</span><span class="named-paragraph-number">5.6.3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">indent</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_5" class="named-paragraph-link"><span class="named-paragraph">Try closing blocks to bring expected indentation down to match</span><span class="named-paragraph-number">5.6.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">indent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_3_2" class="named-paragraph-link"><span class="named-paragraph">Record a phrase within current block</span><span class="named-paragraph-number">5.6.3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6">&#167;5.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_3_1" class="paragraph-anchor"></a><b>&#167;5.6.3.1. </b>This is a small variation used for an intermediate phrase like "otherwise".
These are required to be at the same indentation as the line which opened the
block, rather than being one tab step in from there: in other words they are
not deemed part of the block itself. They can also occur in "stages", which
is a way to enforce one intermediate phrase only being allowed after another
one &mdash; for instance, "otherwise if..." is not allowed after an "otherwise"
within an "if".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compare actual indentation to what we expect for an intermediate phrase</span><span class="named-paragraph-number">5.6.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">indent</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for an intermediate phrase not matching</span><span class="named-paragraph-number">5.6.3.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_5" class="named-paragraph-link"><span class="named-paragraph">Try closing blocks to bring expected indentation down to match</span><span class="named-paragraph-number">5.6.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">blo_sp</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">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax"> != </span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1])) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for an intermediate phrase not matching</span><span class="named-paragraph-number">5.6.3.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">blstack_stage</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1] &gt; </span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">used_at_stage</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_3_1_2" class="named-paragraph-link"><span class="named-paragraph">Issue problem for an intermediate phrase out of sequence</span><span class="named-paragraph-number">5.6.3.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blstack_stage</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1] = </span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">used_at_stage</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6_3">&#167;5.6.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_4" class="paragraph-anchor"></a><b>&#167;5.6.4. </b>In colon syntax, blocks are explicitly opened; they are only implicitly
closed. Here is the opening:
</p>
<p class="commentary">If <span class="extract"><span class="extract-syntax">p</span></span> is a node representing a phrase beginning a block, and we're in the
colon syntax, then it is followed by a word which is the colon: thus if <span class="extract"><span class="extract-syntax">p</span></span>
reads "if x is 2" then the word following the "2" will be ":".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Insert begin marker and increase expected indentation if a block begins here</span><span class="named-paragraph-number">5.6.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">colon_block_command_ANNOT</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">indent_subblocks</span><span class="plain-syntax">) </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">] = </span><span class="identifier-syntax">csp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blstack_stage</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</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">blstack_opening_phrase</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">just_opened_block</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6">&#167;5.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_5" class="paragraph-anchor"></a><b>&#167;5.6.5. </b>Now for the closing of colon-syntax blocks. We know that blocks must be
being closed if the indentation has jumped backwards: but it may be that many
blocks are being closed at once. (It may also be that the indentation has
gone awry.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Try closing blocks to bring expected indentation down to match</span><span class="named-paragraph-number">5.6.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">just_opened_block</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (!(</span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1]-&gt;</span><span class="identifier-syntax">body_empty_except_for_subordinates</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_5_2" class="named-paragraph-link"><span class="named-paragraph">Issue problem for an empty block</span><span class="named-paragraph-number">5.6.5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">indent</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">expected_indent</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">opening</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_3_3" class="named-paragraph-link"><span class="named-paragraph">Record a misalignment of indentation</span><span class="named-paragraph-number">5.6.3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">expected_indent</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="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1]-&gt;</span><span class="identifier-syntax">body_empty_except_for_subordinates</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">indent</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">indent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">expected_indent</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="identifier-syntax">expected_indent</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1]-&gt;</span><span class="identifier-syntax">indent_subblocks</span><span class="plain-syntax">) </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">opening</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blstack_opening_phrase</span><span class="plain-syntax">[--</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_5_1" class="named-paragraph-link"><span class="named-paragraph">Insert end marker to match the opening of the block phrase</span><span class="named-paragraph-number">5.6.5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6">&#167;5.6</a>, <a href="8-rs.html#SP5_6_3">&#167;5.6.3</a>, <a href="8-rs.html#SP5_6_3_1">&#167;5.6.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_3_2" class="paragraph-anchor"></a><b>&#167;5.6.3.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Record a phrase within current block</span><span class="named-paragraph-number">5.6.3.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">blstack_stage</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1] == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1]-&gt;</span><span class="identifier-syntax">body_empty_except_for_subordinates</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_6_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for non-case in a switch</span><span class="named-paragraph-number">5.6.3.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">just_opened_block</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6_3">&#167;5.6.3</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_5_1" class="paragraph-anchor"></a><b>&#167;5.6.5.1. </b>An end marker is a phrase like "end if" which matches the "if... begin"
above it: here we insert such a marker at a place where the source text
indentation implicitly requires it.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Insert end marker to match the opening of the block phrase</span><span class="named-paragraph-number">5.6.5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax"> = </span><a href="8-rs.html#SP8" class="function-link"><span class="function-syntax">RuleSubtrees::end_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">opening</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6_5">&#167;5.6.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_3_3" class="paragraph-anchor"></a><b>&#167;5.6.3.3. </b>Here we throw what amounts to an exception...
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Record a misalignment of indentation</span><span class="named-paragraph-number">5.6.3.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">indent_misalign</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_misaligned_phrase</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">first_misaligned_phrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6_3">&#167;5.6.3</a> (twice), <a href="8-rs.html#SP5_6_5">&#167;5.6.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_6" class="paragraph-anchor"></a><b>&#167;5.6.6. </b>...and catch it with something of a catch-all message:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for misaligned indentation</span><span class="named-paragraph-number">5.6.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">routine_node</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">routine_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">first_misaligned_phrase</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_MisalignedIndentation</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The phrase or rule definition %1 is written using the 'colon "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and indentation' syntax for its 'if's, 'repeat's and 'while's, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"where blocks of phrases grouped together are indented one "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"tab step inward from the 'if ...:' or similar phrase to which "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"they belong. But the tabs here seem to be misaligned, and I can't "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"determine the structure. The first phrase going awry in the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"definition seems to be %2, in case that helps. %PThis sometimes "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"happens even when the code looks about right, to the eye, if rows "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of spaces have been used to indent phrases instead of tabs."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-up.html#SP5" class="function-link"><span class="function-syntax">Problems::Using::diagnose_further</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6">&#167;5.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_2_1" class="paragraph-anchor"></a><b>&#167;5.6.2.1. </b>And another...
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Record an excess of indentation</span><span class="named-paragraph-number">5.6.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">indent_overmuch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_overindented_phrase</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">first_overindented_phrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6_2">&#167;5.6.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_7" class="paragraph-anchor"></a><b>&#167;5.6.7. </b>...caught here:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for an excess of indentation</span><span class="named-paragraph-number">5.6.7</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">suppress_further_problems</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">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">first_overindented_phrase</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_TooMuchIndentation</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The phrase or rule definition %1 is written using tab indentations "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to show how its phrases are to be grouped together. But the level "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of indentation goes far too deep, reaching more than 25 tab stops "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"from the left margin."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6">&#167;5.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_8" class="paragraph-anchor"></a><b>&#167;5.6.8. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for run-ons within phrase definition</span><span class="named-paragraph-number">5.6.8</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">suppress_further_problems</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">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">run_on_at</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_RunOnsInTabbedRoutine</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The phrase or rule definition %1 is written using the 'colon "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and indentation' syntax for its 'if's, 'repeat's and 'while's, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but that's only allowed if each phrase in the definition "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"occurs on its own line. So phrases like %2, which follow "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"directly on from the previous phrase, aren't allowed."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6">&#167;5.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_5_2" class="paragraph-anchor"></a><b>&#167;5.6.5.2. </b>It's a moot point whether the following should be incorrect syntax, but it
far more often happens as an accident than anything else, and it's hard to
think of a sensible use.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for an empty block</span><span class="named-paragraph-number">5.6.5.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">routine_node</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">routine_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">prev</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EmptyIndentedBlock</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The phrase or rule definition %1 is written using the 'colon "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and indentation' syntax for its 'if's, 'repeat's and 'while's, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"where blocks of phrases grouped together are indented one "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"tab step inward from the 'if ...:' or similar phrase to which "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"they belong. But the phrase %2, which ought to begin a block, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"is immediately followed by %3 at the same or a lower indentation, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"so the block seems to be empty - this must mean there has been "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a mistake in indenting the phrases."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6_5">&#167;5.6.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_3_2_1" class="paragraph-anchor"></a><b>&#167;5.6.3.2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for non-case in a switch</span><span class="named-paragraph-number">5.6.3.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">suppress_further_problems</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">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NonCaseInIf</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In the phrase or rule definition %1, the phrase %2 came as a "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"surprise since it was not a case in an 'if X is...' but was "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"instead some other miscellaneous instruction."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6_3_2">&#167;5.6.3.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_3_1_1" class="paragraph-anchor"></a><b>&#167;5.6.3.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for an intermediate phrase not matching</span><span class="named-paragraph-number">5.6.3.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">indent_misalign</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">suppress_further_problems</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">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">if_CSP</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">"$T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_MisalignedOtherwise</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this doesn't match a corresponding 'if'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"as it must. An 'otherwise' must be vertically underneath the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'if' to which it corresponds, at the same indentation, and "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"if the 'otherwise' uses a colon to begin a block then the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'if' must do the same."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">switch_CSP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_MisalignedCase</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this seems to be misplaced since it is not a case within an "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'if X is...'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"as it must be. Each case must be placed one tab stop in from "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the 'if X is...' to which it belongs, and the instructions "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"for what to do in that case should be one tab stop further in "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"still."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6_3_1">&#167;5.6.3.1</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_3_1_2" class="paragraph-anchor"></a><b>&#167;5.6.3.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for an intermediate phrase out of sequence</span><span class="named-paragraph-number">5.6.3.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">indent_misalign</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">suppress_further_problems</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">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">default_case_CSP</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">case_CSP</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_DefaultCaseNotLast</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'otherwise' must be the last clause if an 'if ... is:'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and in particular it has to come after all the '-- V:' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"case values supplied."</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">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_MisarrangedOtherwise</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this seems to be misplaced since it is out of sequence within its 'if'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"with an 'otherwise if...' coming after the more general 'otherwise' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"rather than before. (Note that an 'otherwise' or 'otherwise if' must "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"be vertically underneath the 'if' to which it corresponds, at the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"same indentation."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_6_3_1">&#167;5.6.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_7" class="paragraph-anchor"></a><b>&#167;5.7. </b>And after all that work, the routine's parse tree still consists only of a
linked list of nodes; but at least it now contains the same pattern of nodes
whichever syntax is used. We finally make a meaningful tree out of it.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(e) Structure the parse tree to match the use of control structures</span><span class="named-paragraph-number">5.7</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">routine_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</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">top_level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="constant-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">top_level</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">attach_owners</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_BLOCK_NESTING</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">attach_points</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_BLOCK_NESTING</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">attach_csps</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_BLOCK_NESTING</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> push the top level code block onto the stack</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">attach_owners</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</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">attach_csps</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</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">attach_points</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">top_level</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">overflow_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> if any overflow is found</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">routine_list</span><span class="plain-syntax">, *</span><span class="identifier-syntax">pn_prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">pn</span><span class="plain-syntax">; </span><span class="identifier-syntax">pn_prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> unstring this node from the old list</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pn_prev</span><span class="plain-syntax">) </span><span class="identifier-syntax">pn_prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_7_1" class="named-paragraph-link"><span class="named-paragraph">Attach the node to the routine's growing parse tree</span><span class="named-paragraph-number">5.7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">overflow_point</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">overflow_point</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BlockNestingTooDeep</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"compound phrases have gone too deep"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"perhaps because many have begun but not been properly ended?"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_7_1" class="paragraph-anchor"></a><b>&#167;5.7.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Attach the node to the routine's growing parse tree</span><span class="named-paragraph-number">5.7.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">go_up</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">go_down</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">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_end_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) </span><span class="identifier-syntax">go_up</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">go_down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ControlStructures::opens_block</span><span class="plain-syntax">(</span><span class="identifier-syntax">csp</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">go_up</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">Node::set_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="constant-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">go_up</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_7_1_1" class="named-paragraph-link"><span class="named-paragraph">Move the attachment point up in the tree</span><span class="named-paragraph-number">5.7.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_7_1_2" class="named-paragraph-link"><span class="named-paragraph">Attach this latest node</span><span class="named-paragraph-number">5.7.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">go_down</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_7_1_3" class="named-paragraph-link"><span class="named-paragraph">Move the attachment point down in the tree</span><span class="named-paragraph-number">5.7.1.3</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_7">&#167;5.7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_7_1_1" class="paragraph-anchor"></a><b>&#167;5.7.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Move the attachment point up in the tree</span><span class="named-paragraph-number">5.7.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">superior_csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">attach_csps</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">-1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">superior_csp</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">superior_csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_7_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Pop the CSP stack</span><span class="named-paragraph-number">5.7.1.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">go_down</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_7_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Pop the CSP stack</span><span class="named-paragraph-number">5.7.1.1.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_7_1">&#167;5.7.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_7_1_2" class="paragraph-anchor"></a><b>&#167;5.7.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Attach this latest node</span><span class="named-paragraph-number">5.7.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">attach_points</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">-1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">go_up</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">go_down</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">attach_owners</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">-1]))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">attach_owners</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">-1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">SyntaxTree::graft</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_7_1">&#167;5.7.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_7_1_3" class="paragraph-anchor"></a><b>&#167;5.7.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Move the attachment point down in the tree</span><span class="named-paragraph-number">5.7.1.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_attach_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">go_up</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">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="constant-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">next_attach_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP5_7_1_3_1" class="named-paragraph-link"><span class="named-paragraph">Push the CSP stack</span><span class="named-paragraph-number">5.7.1.3.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_7_1">&#167;5.7.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_7_1_1_1" class="paragraph-anchor"></a><b>&#167;5.7.1.1.1. </b>It's an error to let this underflow, but we'll catch that problem later.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Pop the CSP stack</span><span class="named-paragraph-number">5.7.1.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">--;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_7_1_1">&#167;5.7.1.1</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP5_7_1_3_1" class="paragraph-anchor"></a><b>&#167;5.7.1.3.1. </b>An overflow, however, we must catch right here.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Push the CSP stack</span><span class="named-paragraph-number">5.7.1.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">MAX_BLOCK_NESTING</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">attach_owners</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">] = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">attach_csps</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">] = </span><span class="identifier-syntax">csp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">attach_points</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">next_attach_point</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">overflow_point</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">overflow_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5_7_1_3">&#167;5.7.1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_8" class="paragraph-anchor"></a><b>&#167;5.8. </b>We now have a neatly structured tree, so from here on anything we do will
need a recursive procedure.
</p>
<p class="commentary">Firstly, the tree is certainly neat, but it can still contain all kinds
of nonsense: "if" blocks with multiple "otherwise"s, for example. This is
where we look for such mistakes.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(f) Police the structure of the parse tree</span><span class="named-paragraph-number">5.8</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="8-rs.html#SP6" class="function-link"><span class="function-syntax">RuleSubtrees::police_code_block</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</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">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">n</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Local parse tree: $T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>Which recursively uses the following:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">RuleSubtrees::police_code_block</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">RuleSubtrees::police_code_block</span></span>:<br/><a href="8-rs.html#SP5_8">&#167;5.8</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</span><span class="plain-syntax">, </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">context</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</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">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prior</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">)?</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">prev_p</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">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_end_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> != </span><span class="identifier-syntax">prior</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prior</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP6_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for end without begin</span><span class="named-paragraph-number">6.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP6_2" class="named-paragraph-link"><span class="named-paragraph">Issue problem for wrong sort of end</span><span class="named-paragraph-number">6.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ControlStructures::opens_block</span><span class="plain-syntax">(</span><span class="identifier-syntax">csp</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</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">Node::get_end_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP6_3" class="named-paragraph-link"><span class="named-paragraph">Issue problem for begin without end</span><span class="named-paragraph-number">6.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">context</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP6_4" class="named-paragraph-link"><span class="named-paragraph">Choose a problem for a loose clause</span><span class="named-paragraph-number">6.4</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">context</span><span class="plain-syntax"> != </span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP6_5" class="named-paragraph-link"><span class="named-paragraph">Choose a problem for the wrong clause</span><span class="named-paragraph-number">6.5</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP6_6" class="named-paragraph-link"><span class="named-paragraph">Choose a problem for otherwise not occurring last</span><span class="named-paragraph-number">6.6</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">default_case_CSP</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP6_7" class="named-paragraph-link"><span class="named-paragraph">Issue a problem for the default case not occurring last</span><span class="named-paragraph-number">6.7</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">) </span><a href="8-rs.html#SP6" class="function-link"><span class="function-syntax">RuleSubtrees::police_code_block</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">csp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6_1" class="paragraph-anchor"></a><b>&#167;6.1. </b>These used to be much-seen problem messages, until Inform moved to Pythonesque
structure-by-indentation. Nowadays "end if", "end while" and such are
automatically inserted into the stream of commands, always in the right place,
and always passing these checks. But the problem messages are kept for the sake
of old-format source text, and for refuseniks.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for end without begin</span><span class="named-paragraph-number">6.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem_with_note</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EndWithoutBegin</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this is an 'end' with no matching 'begin'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which should not happen: every phrase like 'if ... begin;' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"should eventually be followed by its bookend 'end if'. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"It makes no sense to have an 'end ...' on its own."</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Perhaps the problem is actually that you opened several "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"such begin... end 'blocks' and accidentally closed them "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"once too many? This is very easily done."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_2" class="paragraph-anchor"></a><b>&#167;6.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for wrong sort of end</span><span class="named-paragraph-number">6.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wide_text</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">prior</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">keyword</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_WrongEnd</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"You wrote %1, but the end I was expecting next was 'end %2', "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"finishing the block you began with %3."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_3" class="paragraph-anchor"></a><b>&#167;6.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for begin without end</span><span class="named-paragraph-number">6.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BeginWithoutEnd</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the definition of the phrase ended with no matching 'end' for "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this 'begin'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"bearing in mind that every begin must have a matching end, and "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that the one most recently begun must be the one first to end. For "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"instance, 'if ... begin' must have a matching 'end if'."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_4" class="paragraph-anchor"></a><b>&#167;6.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Choose a problem for a loose clause</span><span class="named-paragraph-number">6.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_OtherwiseWithoutIf</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this is an 'else' or 'otherwise' with no matching 'if' (or 'unless')"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which must be wrong."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">otherwise_if_CSP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_OtherwiseIfMisplaced</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the 'otherwise if' clause here seems not to be occurring inside "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a large 'if'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and seems to be freestanding instead. (Though 'otherwise ...' can "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"usually be used after simple one-line 'if's to provide an alternative "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"course of action, 'otherwise if...' is a different matter, and is "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"used to divide up larger-scale instructions.)"</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">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this clause can't occur outside of a control phrase"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which suggests that the structure of this routine is wrong."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_5" class="paragraph-anchor"></a><b>&#167;6.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Choose a problem for the wrong clause</span><span class="named-paragraph-number">6.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">otherwise_if_CSP</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wide_text</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">context</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">keyword</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_OtherwiseInNonIf</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The %1 here did not make sense inside a "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'%2' structure: it's provided for 'if' (or 'unless')."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</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">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this clause is wrong for the phrase containing it"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which suggests that the structure of this routine is wrong."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_6" class="paragraph-anchor"></a><b>&#167;6.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Choose a problem for otherwise not occurring last</span><span class="named-paragraph-number">6.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">doubled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">oi</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">; </span><span class="identifier-syntax">p2</span><span class="plain-syntax">; </span><span class="identifier-syntax">p2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p2</span><span class="plain-syntax">) == </span><span class="identifier-syntax">otherwise_CSP</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">p2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">doubled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p2</span><span class="plain-syntax">) == </span><span class="identifier-syntax">otherwise_if_CSP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">oi</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">doubled</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_DoubleOtherwise</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that makes two unconditional 'otherwise' or 'else' clauses "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"for this 'if'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which is forbidden since 'otherwise' is meant to be a single "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"(optional) catch-all clause at the end."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">oi</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_OtherwiseIfAfterOtherwise</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this seems to be misplaced since it is out of sequence within its 'if'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"with an 'otherwise if...' coming after the more general 'otherwise' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"rather than before. (If there's an 'otherwise' clause, it has to be "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the last clause of the 'if'.)"</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">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'otherwise' must be the last clause"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but it seems not to be."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_7" class="paragraph-anchor"></a><b>&#167;6.7. </b>This shouldn't happen because the switch construct requires Python syntax
and the structure of that was checked at indentation time, but just in case.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem for the default case not occurring last</span><span class="named-paragraph-number">6.7</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'otherwise' must be the last clause"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which must be wrong."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_9" class="paragraph-anchor"></a><b>&#167;5.9. </b>The tree is now known to be correctly structured, and there are no possible
problem messages left to issue. It's therefore safe to begin rearranging it.
We'll first eliminate one whole construction: "otherwise if whatever: ..."
can now become "otherwise: if whatever: ...".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(g) Optimise out the otherwise if nodes</span><span class="named-paragraph-number">5.9</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="8-rs.html#SP5_10" class="function-link"><span class="function-syntax">RuleSubtrees::purge_otherwise_if</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">n</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Local parse tree: $T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_10" class="paragraph-anchor"></a><b>&#167;5.10. </b>We made a similar manoeuvre above, but for one-line "otherwise do something"
phrases following one-line "if", not for the wider case of "otherwise if". We
didn't handle this back then because to do so would have made it impossible
to issue good problem messages for failures to use "otherwise if" correctly.
</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">RuleSubtrees::purge_otherwise_if</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">RuleSubtrees::purge_otherwise_if</span></span>:<br/><a href="8-rs.html#SP5_9">&#167;5.9</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) == </span><span class="identifier-syntax">otherwise_if_CSP</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">former_contents</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</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">former_successors</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> put an otherwise node in the position previously occupied by p</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="constant-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> extract just the word "otherwise"</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::one_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">) </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> move p to below the otherwise node</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">INVOCATION_LIST_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">if_CSP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</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">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::trim_first_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)));</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> put the code previously under p under a new code block node under p</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="constant-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">former_contents</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> any further "otherwise if" or "otherwise" nodes after p follow</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">former_successors</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">) </span><a href="8-rs.html#SP5_10" class="function-link"><span class="function-syntax">RuleSubtrees::purge_otherwise_if</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_11" class="paragraph-anchor"></a><b>&#167;5.11. </b>End nodes are now redundant: maybe they got here as explicit "end if" phrases
in the source text, or maybe they were auto-inserted by the indentation reader,
but now that the structure is known to be correct they serve no further purpose.
We remove them.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(h) Remove any end markers as no longer necessary</span><span class="named-paragraph-number">5.11</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="8-rs.html#SP5_12" class="function-link"><span class="function-syntax">RuleSubtrees::purge_end_markers</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_12" class="paragraph-anchor"></a><b>&#167;5.12. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">RuleSubtrees::purge_end_markers</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">RuleSubtrees::purge_end_markers</span></span>:<br/><a href="8-rs.html#SP5_11">&#167;5.11</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_end_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">) </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">) </span><a href="8-rs.html#SP5_12" class="function-link"><span class="function-syntax">RuleSubtrees::purge_end_markers</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_13" class="paragraph-anchor"></a><b>&#167;5.13. </b>The "begin" keyword at the end of control constructs in the old-style syntax
can now be removed, too.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(i) Remove any begin markers as no longer necessary</span><span class="named-paragraph-number">5.13</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="8-rs.html#SP5_14" class="function-link"><span class="function-syntax">RuleSubtrees::purge_begin_markers</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_14" class="paragraph-anchor"></a><b>&#167;5.14. </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">RuleSubtrees::purge_begin_markers</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">RuleSubtrees::purge_begin_markers</span></span>:<br/><a href="8-rs.html#SP5_13">&#167;5.13</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;phrase-beginning-block&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;phrase-beginning-block&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">) </span><a href="8-rs.html#SP5_14" class="function-link"><span class="function-syntax">RuleSubtrees::purge_begin_markers</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_15" class="paragraph-anchor"></a><b>&#167;5.15. </b>This all makes a nice tree, but it has the defect that the statements heading
block-opening phrases (the ifs, whiles, repeats) have child nodes (the blocks
of code consequent on them). We want them to be leaves for now, so that we
can append statement-parsing data underneath them later. So we insert blank
code block nodes to mark these phrases, and transfer the control structure
annotations to them.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(j) Insert code block nodes so that nodes needing to be parsed are childless</span><span class="named-paragraph-number">5.15</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="8-rs.html#SP5_16" class="function-link"><span class="function-syntax">RuleSubtrees::insert_cb_nodes</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_16" class="paragraph-anchor"></a><b>&#167;5.16. </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">RuleSubtrees::insert_cb_nodes</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">RuleSubtrees::insert_cb_nodes</span></span>:<br/><a href="8-rs.html#SP5_15">&#167;5.15</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ControlStructures::opens_block</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</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">blank_cb_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="constant-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</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">blank_cb_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</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">prev_p</span><span class="plain-syntax">) </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blank_cb_node</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">blank_cb_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">) </span><a href="8-rs.html#SP5_16" class="function-link"><span class="function-syntax">RuleSubtrees::insert_cb_nodes</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_17" class="paragraph-anchor"></a><b>&#167;5.17. </b>Now:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(k) Insert instead marker nodes</span><span class="named-paragraph-number">5.17</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="8-rs.html#SP5_18" class="function-link"><span class="function-syntax">RuleSubtrees::read_instead_markers</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_18" class="paragraph-anchor"></a><b>&#167;5.18. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">RuleSubtrees::read_instead_markers</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">RuleSubtrees::read_instead_markers</span></span>:<br/><a href="8-rs.html#SP5_17">&#167;5.17</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;instead-keyword&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;instead-keyword&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">instead_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="constant-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">instead_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">instead_CSP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">instead_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">instead_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">) </span><a href="8-rs.html#SP5_18" class="function-link"><span class="function-syntax">RuleSubtrees::read_instead_markers</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_19" class="paragraph-anchor"></a><b>&#167;5.19. </b>Now:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(l) Break up say phrases</span><span class="named-paragraph-number">5.19</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="8-rs.html#SP7" class="function-link"><span class="function-syntax">RuleSubtrees::break_up_says</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">routine_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </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">RuleSubtrees::break_up_says</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">RuleSubtrees::break_up_says</span></span>:<br/><a href="8-rs.html#SP5_19">&#167;5.19</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</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">sf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NO_SIGF</span><span class="plain-syntax">;</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">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">from_text_substitution_ANNOT</span><span class="plain-syntax">)) </span><span class="identifier-syntax">sf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SAY_SIGF</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;other-significant-phrase&gt;</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">sf</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">; </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;other-significant-phrase&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sf</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">SAY_SIGF:</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">blank_cb_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="constant-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">say_CSP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</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">prev_p</span><span class="plain-syntax">) </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blank_cb_node</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">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="8-rs.html#SP7" class="function-link"><span class="function-syntax">RuleSubtrees::unroll_says</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</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">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blank_cb_node</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="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOW_SIGF:</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">now_CSP</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">cond_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="constant-syntax">CONDITION_CONTEXT_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">cond_node</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">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cond_node</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">) </span><a href="8-rs.html#SP7" class="function-link"><span class="function-syntax">RuleSubtrees::break_up_says</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</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">RuleSubtrees::unroll_says</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">RuleSubtrees::unroll_says</span></span>:<br/><a href="8-rs.html#SP7_1">&#167;7.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cb_node</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="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="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;phrase-with-comma-notation&gt;</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">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;phrase-with-comma-notation&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">BW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;phrase-with-comma-notation&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AW</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP7_1" class="named-paragraph-link"><span class="named-paragraph">Bite off a say term</span><span class="named-paragraph-number">7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BW</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP7_1" class="named-paragraph-link"><span class="named-paragraph">Bite off a say term</span><span class="named-paragraph-number">7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7_1" class="paragraph-anchor"></a><b>&#167;7.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Bite off a say term</span><span class="named-paragraph-number">7.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Wordings::length</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Wide::cmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">Lexer::word_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)), </span><span class="identifier-syntax">L</span><span class="string-syntax">"\"\""</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Wordings::length</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) == </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Vocabulary::test_flags</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">), </span><span class="identifier-syntax">TEXTWITHSUBS_MC</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">depth</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">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word_raw_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP7_1_1" class="named-paragraph-link"><span class="named-paragraph">Check that substitution does not contain suspicious punctuation</span><span class="named-paragraph-number">7.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">A</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::feed_C_string_expanding_strings</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;verify-expanded-text-substitution&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">A</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="8-rs.html#SP7" class="function-link"><span class="function-syntax">RuleSubtrees::unroll_says</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cb_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">+1);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">say_term_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="constant-syntax">INVOCATION_LIST_SAY_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">say_term_node</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">SyntaxTree::graft</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">say_term_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">cb_node</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP7">&#167;7</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP7_1_1" class="paragraph-anchor"></a><b>&#167;7.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check that substitution does not contain suspicious punctuation</span><span class="named-paragraph-number">7.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">, </span><span class="identifier-syntax">sqb</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">]; </span><span class="identifier-syntax">k</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">p</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">case</span><span class="plain-syntax"> </span><span class="character-syntax">'['</span><span class="plain-syntax">: </span><span class="identifier-syntax">sqb</span><span class="plain-syntax">++; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sqb</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP7_1_1_2" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for nested substitution</span><span class="named-paragraph-number">7.1.1.2</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">']'</span><span class="plain-syntax">: </span><span class="identifier-syntax">sqb</span><span class="plain-syntax">--; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sqb</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP7_1_1_4" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for unopened substitution</span><span class="named-paragraph-number">7.1.1.4</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">':'</span><span class="plain-syntax">: </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">k</span><span class="plain-syntax">&gt;0) &amp;&amp; (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">-1])) &amp;&amp; (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+1]))) </span><span class="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="character-syntax">';'</span><span class="plain-syntax">:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sqb</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP7_1_1_6" class="named-paragraph-link"><span class="named-paragraph">Issue PM_TSWithPunctuation problem</span><span class="named-paragraph-number">7.1.1.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">','</span><span class="plain-syntax">:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sqb</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP7_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for comma in a substitution</span><span class="named-paragraph-number">7.1.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sqb</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP7_1_1_3" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for unclosed substitution</span><span class="named-paragraph-number">7.1.1.3</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP7_1">&#167;7.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_1_1_1" class="paragraph-anchor"></a><b>&#167;7.1.1.1. </b>And the more specialised:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for comma in a substitution</span><span class="named-paragraph-number">7.1.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="17-ts.html#SP8" class="function-link"><span class="function-syntax">Strings::TextSubstitutions::it_is_not_worth_adding</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_TSWithComma</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a substitution contains a comma ','"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which is against the rules, because 'say' is a special phrase in "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which the comma divides items in a list of things to say, and so it "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"loses its ordinary meanings. Because of this, no text substitution "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"can contain a comma. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"(If you're trying to use a value produced by a phrase with a phrase "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"option - say 'the best route from A to B, using even locked doors' - "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"you'll need to put this in a 'let' variable first and then say that, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"or else define a better text substitution to do the job for you.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="17-ts.html#SP8" class="function-link"><span class="function-syntax">Strings::TextSubstitutions::it_is_worth_adding</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP7_1_1">&#167;7.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_1_1_2" class="paragraph-anchor"></a><b>&#167;7.1.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for nested substitution</span><span class="named-paragraph-number">7.1.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="17-ts.html#SP8" class="function-link"><span class="function-syntax">Strings::TextSubstitutions::it_is_not_worth_adding</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+1] == </span><span class="character-syntax">'u'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+2] == </span><span class="character-syntax">'n'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+3] == </span><span class="character-syntax">'i'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+4] == </span><span class="character-syntax">'c'</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+5] == </span><span class="character-syntax">'o'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+6] == </span><span class="character-syntax">'d'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+7] == </span><span class="character-syntax">'e'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+8] == </span><span class="character-syntax">' '</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NestedUSubstitution</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the text here contains one substitution '[...]' inside another"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which is not allowed. Actually, it looks as if you might have got "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"into this by typing an exotic character as part of the name of a "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"text substitution - those get rewritten automatically as '[unicode N]' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"for the appropriate Unicode character code number N. Either way - "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this isn't allowed."</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">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NestedSubstitution</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the text here contains one substitution '[...]' inside another"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which is not allowed. (If you just wanted a literal open and closed "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"square bracket, use '[bracket]' and '[close bracket]'.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="17-ts.html#SP8" class="function-link"><span class="function-syntax">Strings::TextSubstitutions::it_is_worth_adding</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP7_1_1">&#167;7.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_1_1_3" class="paragraph-anchor"></a><b>&#167;7.1.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for unclosed substitution</span><span class="named-paragraph-number">7.1.1.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="17-ts.html#SP8" class="function-link"><span class="function-syntax">Strings::TextSubstitutions::it_is_not_worth_adding</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_UnclosedSubstitution</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the text here uses an open square bracket '[', which opens a substitution "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"in the text, but doesn't close it again"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"so that the result is malformed. (If you just wanted a literal open "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"square bracket, use '[bracket]'.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="17-ts.html#SP8" class="function-link"><span class="function-syntax">Strings::TextSubstitutions::it_is_worth_adding</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP7_1_1">&#167;7.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_1_1_4" class="paragraph-anchor"></a><b>&#167;7.1.1.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for unopened substitution</span><span class="named-paragraph-number">7.1.1.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="17-ts.html#SP8" class="function-link"><span class="function-syntax">Strings::TextSubstitutions::it_is_not_worth_adding</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_UnopenedSubstitution</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the text here uses a close square bracket ']', which closes a substitution "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"in the text, but never actually opened it"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"with a matching '['. (If you just wanted a literal close square bracket, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"use '[close bracket]'.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="17-ts.html#SP8" class="function-link"><span class="function-syntax">Strings::TextSubstitutions::it_is_worth_adding</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP7_1_1">&#167;7.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_1_1_5" class="paragraph-anchor"></a><b>&#167;7.1.1.5. </b>Something devious happens when production (b) of &lt;s-say-phrase&gt; is matched.
Double-quoted text is literal if it contains no square brackets, but is
expanded if it includes text substitutions in squares. When (b) matches,
Inform expands a text such as
</p>
<blockquote>
<p>"Look, [the noun] said."</p>
</blockquote>
<p class="commentary">into:
</p>
<blockquote>
<p>"Look, ", the noun, " said."</p>
</blockquote>
<p class="commentary">and then re-parses the result with the following nonterminal; note that we
make sure commas are used correctly before handing back to &lt;s-say-phrase&gt;
to parse the list.
</p>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;verify-expanded-text-substitution&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">.</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP7_1_1_6" class="named-paragraph-link"><span class="named-paragraph">Issue PM_TSWithPunctuation problem</span><span class="named-paragraph-number">7.1.1.6</span></a></span><span class="Preform-constant-syntax">;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { fail }</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP7_1_1_5_1" class="named-paragraph-link"><span class="named-paragraph">Issue PM_EmptySubstitution problem</span><span class="named-paragraph-number">7.1.1.5.1</span></a></span><span class="Preform-constant-syntax">;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { fail }</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP7_1_1_5_1" class="named-paragraph-link"><span class="named-paragraph">Issue PM_EmptySubstitution problem</span><span class="named-paragraph-number">7.1.1.5.1</span></a></span><span class="Preform-constant-syntax">;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { fail }</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="8-rs.html#SP7_1_1_5_1" class="named-paragraph-link"><span class="named-paragraph">Issue PM_EmptySubstitution problem</span><span class="named-paragraph-number">7.1.1.5.1</span></a></span><span class="Preform-constant-syntax">;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { fail }</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_1_1_6" class="paragraph-anchor"></a><b>&#167;7.1.1.6. </b>So now just the problem messages:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_TSWithPunctuation problem</span><span class="named-paragraph-number">7.1.1.6</span></span><span class="Preform-comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="17-ts.html#SP8" class="function-link"><span class="function-syntax">Strings::TextSubstitutions::it_is_not_worth_adding</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_TSWithPunctuation</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a substitution contains a '.', ':' or ';'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which suggests that a close square bracket ']' may have gone astray."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="17-ts.html#SP8" class="function-link"><span class="function-syntax">Strings::TextSubstitutions::it_is_worth_adding</span></a><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP7_1_1">&#167;7.1.1</a>, <a href="8-rs.html#SP7_1_1_5">&#167;7.1.1.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_1_1_5_1" class="paragraph-anchor"></a><b>&#167;7.1.1.5.1. </b>And:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_EmptySubstitution problem</span><span class="named-paragraph-number">7.1.1.5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="17-ts.html#SP8" class="function-link"><span class="function-syntax">Strings::TextSubstitutions::it_is_not_worth_adding</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EmptySubstitution</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the text here contains an empty substitution '[]'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which is not allowed. To say nothing - well, say nothing."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="17-ts.html#SP8" class="function-link"><span class="function-syntax">Strings::TextSubstitutions::it_is_worth_adding</span></a><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="8-rs.html#SP7_1_1_5">&#167;7.1.1.5</a> (three times).</li></ul>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>That just leaves one utility routine, for manufacturing end nodes which
match a given begin node.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">RuleSubtrees::end_node</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">RuleSubtrees::end_node</span></span>:<br/><a href="8-rs.html#SP5_5_1">&#167;5.5.1</a>, <a href="8-rs.html#SP5_6_5_1">&#167;5.6.5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opening</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">implicit_end</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">INVOCATION_LIST_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_end_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">opening</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">opening</span><span class="plain-syntax">, </span><span class="constant-syntax">indentation_level_ANNOT</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">implicit_end</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="8-hdn.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-cm.html">1</a></li><li class="progresschapter"><a href="2-up.html">2</a></li><li class="progresschapter"><a href="3-bv.html">3</a></li><li class="progresschapter"><a href="4-dlr.html">4</a></li><li class="progresschapter"><a href="5-rpt.html">5</a></li><li class="progresschapter"><a href="6-lp.html">6</a></li><li class="progresschapter"><a href="7-am.html">7</a></li><li class="progresscurrentchapter">8</li><li class="progresssection"><a href="8-ptu.html">ptu</a></li><li class="progresssection"><a href="8-hdn.html">hdn</a></li><li class="progresscurrent">rs</li><li class="progresschapter"><a href="9-ef.html">9</a></li><li class="progresschapter"><a href="10-its.html">10</a></li><li class="progresschapter"></li><li class="progresschapter"><a href="12-terr.html">12</a></li><li class="progresschapter"><a href="13-kak.html">13</a></li><li class="progresschapter"><a href="14-sp.html">14</a></li><li class="progresschapter"><a href="15-pr.html">15</a></li><li class="progresschapter"><a href="16-is.html">16</a></li><li class="progresschapter"><a href="17-tl.html">17</a></li><li class="progresschapter"><a href="18-lc.html">18</a></li><li class="progresschapter"><a href="19-tc.html">19</a></li><li class="progresschapter"><a href="20-eq.html">20</a></li><li class="progresschapter"><a href="21-rl.html">21</a></li><li class="progresschapter"><a href="22-itp.html">22</a></li><li class="progresschapter"><a href="23-ad.html">23</a></li><li class="progresschapter"><a href="24-lv.html">24</a></li><li class="progresschapter"><a href="25-in.html">25</a></li><li class="progresschapter"><a href="26-fc.html">26</a></li><li class="progresschapter"><a href="27-hr.html">27</a></li><li class="progressnext"><a href="9-ef.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>