1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-16 22:14:23 +03:00
inform7/docs/syntax-module/2-st.html

596 lines
115 KiB
HTML
Raw Normal View History

2020-05-11 17:21:29 +03:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Syntax Trees</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
2022-04-28 19:37:28 +03:00
<h1><a href="../index.html">
2020-05-11 17:21:29 +03:00
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
2022-04-28 19:37:28 +03:00
<ul><li><a href="../index.html">home</a></li>
2022-04-04 20:31:44 +03:00
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
2022-04-04 20:31:44 +03:00
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../indocn.html">indoc</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
<li><a href="../inrtpsn.html">inrtps</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
2022-04-04 20:31:44 +03:00
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inweb/index.html">inweb</a></li>
<li><a href="../../../intest/index.html">intest</a></li>
2020-05-11 17:21:29 +03:00
</ul>
</nav>
<main role="main">
<!--Weave of 'Syntax Trees' generated by Inweb-->
<div class="breadcrumbs">
2022-04-28 19:37:28 +03:00
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../services.html">Services</a></li><li><a href="index.html">syntax</a></li><li><a href="index.html#2">Chapter 2: The Parse Tree</a></li><li><b>Syntax Trees</b></li></ul></div>
2020-05-11 17:21:29 +03:00
<p class="purpose">To parse trees which decompose the meaning of excerpts of text, and which allow annotations to be made at each node.</p>
2022-09-05 02:08:32 +03:00
<ul class="toc"><li><a href="2-st.html#SP1">&#167;1. Optional headings tree</a></li><li><a href="2-st.html#SP2">&#167;2. Syntax trees</a></li><li><a href="2-st.html#SP3">&#167;3. Buds and grafts</a></li><li><a href="2-st.html#SP9">&#167;9. Where we currently are in the text</a></li><li><a href="2-st.html#SP10">&#167;10. General traversals</a></li><li><a href="2-st.html#SP19">&#167;19. Cautious traverses</a></li><li><a href="2-st.html#SP20">&#167;20. Toggling log output</a></li><li><a href="2-st.html#SP21">&#167;21. Ambiguity subtrees</a></li></ul><hr class="tocbar">
2020-05-11 17:21:29 +03:00
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Optional headings tree. </b>Within <a href="../inform7/index.html" class="internal">inform7</a> and <a href="../inbuild/index.html" class="internal">inbuild</a>, the code in this section is augmented by
2020-05-11 17:21:29 +03:00
<a href="../supervisor-module/6-hdn.html" class="internal">Headings (in supervisor)</a>, which gives every syntax tree an associated tree of
source headings; but as far as <a href="index.html" class="internal">syntax</a> is concerned, that's all an optional
extra.
</p>
<p class="commentary">Code using <a href="index.html" class="internal">syntax</a> in this way must define <span class="extract"><span class="extract-syntax">HEADING_TREE_SYNTAX_TYPE</span></span> as the
class of object to which our <span class="extract"><span class="extract-syntax">headings</span></span> field will point, and callback functions
<span class="extract"><span class="extract-syntax">NEW_HEADING_TREE_SYNTAX_CALLBACK</span></span> and <span class="extract"><span class="extract-syntax">NEW_HEADING_SYNTAX_CALLBACK</span></span> to
initialise and add to it.
</p>
2020-07-03 01:09:26 +03:00
<pre class="definitions code-font"><span class="definition-keyword">default</span> <span class="constant-syntax">HEADING_TREE_SYNTAX_TYPE</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="comment-syntax"> in which case, never used</span>
2020-05-11 17:21:29 +03:00
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Syntax trees. </b>Each <a href="2-st.html#SP2" class="internal">parse_node_tree</a> object represents a different syntax tree; typically
2020-05-11 17:21:29 +03:00
the entire source text being compiled by <a href="../inform7/index.html" class="internal">inform7</a>, including any extensions
it includes, will form a single <a href="2-st.html#SP2" class="internal">parse_node_tree</a>.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_BUD_STACK_SIZE</span><span class="plain-syntax"> </span><span class="constant-syntax">100</span><span class="plain-syntax"> </span><span class="comment-syntax"> must be at least the number of heading levels plus 3</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">root_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">bud_parent_sp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">bud_parent_stack</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_BUD_STACK_SIZE</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_sentence</span><span class="plain-syntax">; </span><span class="comment-syntax"> cached position in tree</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">allow_last_sentence_cacheing</span><span class="plain-syntax">;</span>
2022-09-07 01:03:04 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">contains_dialogue</span><span class="plain-syntax">;</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">trace_sentences</span><span class="plain-syntax">;</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="constant-syntax">HEADING_TREE_SYNTAX_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">headings</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="function-syntax">SyntaxTree::new</span><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">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax">);</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">root_node</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP2" class="function-link"><span class="function-syntax">Node::new</span></a><span class="plain-syntax">(</span><span class="constant-syntax">ROOT_NT</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bud_parent_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">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_sentence</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">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">allow_last_sentence_cacheing</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">trace_sentences</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
2022-09-07 01:03:04 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">contains_dialogue</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><a href="2-st.html#SP3" class="function-link"><span class="function-syntax">SyntaxTree::push_bud</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">root_node</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEW_HEADING_TREE_SYNTAX_CALLBACK</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">headings</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_HEADING_TREE_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2022-09-07 01:03:04 +03:00
<ul class="endnotetexts"><li>The structure parse_node_tree is accessed in 2/tv, 3/snt and here.</li></ul>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Buds and grafts. </b>"Buds" are positions in the tree to which new sentence subtrees can be grafted:
2020-05-11 17:21:29 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::push_bud</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">SyntaxTree::push_bud</span></span>:<br/><a href="2-st.html#SP2">&#167;2</a>, <a href="2-st.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">l</span><span class="plain-syntax"> = </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bud_parent_sp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">bud_parent_sp</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_BUD_STACK_SIZE</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bud stack overflow"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bud_parent_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bud_parent_sp</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">to</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">l</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">SyntaxTree::pop_bud</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">l</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bud_parent_sp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">l</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>Sentences are grafted onto the bud position at the top of the stack.
2020-05-11 17:21:29 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
2022-09-14 13:03:49 +03:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::graft_sentence</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">SyntaxTree::graft_sentence</span></span>:<br/>Sentences - <a href="3-snt.html#SP6_1">&#167;6.1</a>, <a href="3-snt.html#SP6_6">&#167;6.6</a>, <a href="3-snt.html#SP6_9_3">&#167;6.9.3</a>, <a href="3-snt.html#SP6_9_9_1">&#167;6.9.9.1</a>, <a href="3-snt.html#SP6_9_9_2">&#167;6.9.9.2</a>, <a href="3-snt.html#SP6_9_9_3">&#167;6.9.9.3</a>, <a href="3-snt.html#SP6_9_9_3_1_1">&#167;6.9.9.3.1.1</a>, <a href="3-snt.html#SP6_9_9_3_3">&#167;6.9.9.3.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new</span><span class="plain-syntax">) {</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">bud_parent_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no attachment point"</span><span class="plain-syntax">);</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pn.html#SP5" class="function-link"><span class="function-syntax">Node::get_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">) == </span><span class="constant-syntax">HEADING_NT</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-st.html#SP4_1" class="named-paragraph-link"><span class="named-paragraph">Adjust bud point for a heading</span><span class="named-paragraph-number">4.1</span></a></span><span class="plain-syntax">;</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sentence_attachment_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bud_parent_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bud_parent_sp</span><span class="plain-syntax">-1];</span>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><a href="2-st.html#SP6" class="function-link"><span class="function-syntax">SyntaxTree::graft</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="identifier-syntax">sentence_attachment_point</span><span class="plain-syntax">);</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pn.html#SP5" class="function-link"><span class="function-syntax">Node::get_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">) == </span><span class="constant-syntax">HEADING_NT</span><span class="plain-syntax">) </span><a href="2-st.html#SP3" class="function-link"><span class="function-syntax">SyntaxTree::push_bud</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">new</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP4_1" class="paragraph-anchor"></a><b>&#167;4.1. </b>When what's attached is a heading node, that changes the stack. The idea
2020-05-11 17:21:29 +03:00
here is that sentences graft beneath the heading to which they belong. If the
current bud point is a heading called "Section 22", and then we reach the
heading sentence "Part 2", this no longer belongs under Section 22, and we
pop the bud stack until we're beneath a heading node superior to Parts.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Adjust bud point for a heading</span><span class="named-paragraph-number">4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
2020-08-07 00:01:38 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">heading_level</span><span class="plain-syntax"> = </span><a href="2-na.html#SP7" class="function-link"><span class="function-syntax">Annotations::read_int</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new</span><span class="plain-syntax">, </span><span class="constant-syntax">heading_level_ANNOT</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">heading_level</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="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bud_parent_sp</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&gt;=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">--) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bud_parent_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-pn.html#SP5" class="function-link"><span class="function-syntax">Node::get_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">) == </span><span class="constant-syntax">HEADING_NT</span><span class="plain-syntax">) &amp;&amp;</span>
2020-08-07 00:01:38 +03:00
<span class="plain-syntax"> (</span><a href="2-na.html#SP7" class="function-link"><span class="function-syntax">Annotations::read_int</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="constant-syntax">heading_level_ANNOT</span><span class="plain-syntax">) &gt;= </span><span class="identifier-syntax">heading_level</span><span class="plain-syntax">))</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bud_parent_sp</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="2-st.html#SP4">&#167;4</a>.</li></ul>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>Syntax trees for Inform source text have a tendency to be wide. If a source
2020-05-11 17:21:29 +03:00
text is basically a list of 5000 sentences, then there may be a node with 5000
children, even though the maximum depth of the tree might be as low as 10.
</p>
<p class="commentary">Because of that we must be wary of algorithms with quadratic running time in
the width of the tree, and we get around that with a cache. Certain "tree
surgery" operations, when the tree is being rearranged, would throw this,
so the optimisation should be enabled only when needed.
</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">SyntaxTree::enable_last_sentence_cache</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">SyntaxTree::enable_last_sentence_cache</span></span>:<br/>Sentences - <a href="3-snt.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> because this may have changed since last enabled</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">allow_last_sentence_cacheing</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::disable_last_sentence_cache</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">SyntaxTree::disable_last_sentence_cache</span></span>:<br/>Sentences - <a href="3-snt.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">allow_last_sentence_cacheing</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>The function <span class="extract"><span class="extract-syntax">SyntaxTree::graft</span></span> is named by analogy with gardening, where the
2020-05-11 17:21:29 +03:00
rootstock of one plant is joined to a scion (or cutting) of another, so that a
root chosen for strength can be combined with the fruits or blossom of the scion.
</p>
<p class="commentary"><span class="extract"><span class="extract-syntax">SyntaxTree::graft</span></span> returns the node for which <span class="extract"><span class="extract-syntax">scion</span></span> is the immediate sibling,
that is, it returns the previously youngest child of the <span class="extract"><span class="extract-syntax">rootstock</span></span> (or <span class="extract"><span class="extract-syntax">NULL</span></span>
if it previously had no children).
</p>
<pre class="displayed-code all-displayed-code code-font">
2022-09-14 13:03:49 +03:00
<span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">SyntaxTree::graft</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">SyntaxTree::graft</span></span>:<br/><a href="2-st.html#SP4">&#167;4</a><br/>Sentences - <a href="3-snt.html#SP6_9_9_2">&#167;6.9.9.2</a>, <a href="3-snt.html#SP6_9_9_3">&#167;6.9.9.3</a>, <a href="3-snt.html#SP7_1">&#167;7.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">scion</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rootstock</span><span class="plain-syntax">) {</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">elder</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">scion</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"scion is 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">rootstock</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"rootstock is null"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> is the new node to be the only child of the old?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rootstock</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="identifier-syntax">rootstock</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">scion</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> can last sentence cacheing save us a long search through many children of root?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">rootstock</span><span class="plain-syntax"> == </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">root_node</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">allow_last_sentence_cacheing</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_sentence</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">elder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">elder</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">scion</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">scion</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">elder</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> we don't know who's the youngest child now, but we know who soon will be:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">last_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">scion</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> find youngest child of rootstock...</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">elder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rootstock</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">elder</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">; </span><span class="identifier-syntax">elder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">elder</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"> ...and make the new node its younger sibling</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">elder</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">scion</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">elder</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>No speed worries on the much smaller trees with alternative readings:
2020-05-11 17:21:29 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">SyntaxTree::graft_alternative</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">scion</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rootstock</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">scion</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"scion is 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">rootstock</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"rootstock is null"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> is the new node to be the only child of the old?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rootstock</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="identifier-syntax">rootstock</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">scion</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> find youngest child of rootstock...</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">elder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">elder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rootstock</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">elder</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_alternative</span><span class="plain-syntax">; </span><span class="identifier-syntax">elder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">elder</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_alternative</span><span class="plain-syntax">) ;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> ...and make the new node its younger sibling</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">elder</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">scion</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">elder</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>And we can loop through these like so:
2020-05-11 17:21:29 +03:00
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_THROUGH_ALTERNATIVES</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</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">from</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_alternative</span><span class="plain-syntax">)</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Where we currently are in the text. </b>Inform makes many traverses through the big parse tree, often modifying as it
2020-05-11 17:21:29 +03:00
goes, and keeps track of its position so that it can make any problem messages
correctly refer to the location of the faulty text in the original source files.
</p>
<p class="commentary">During such traverses, <span class="extract"><span class="extract-syntax">current_sentence</span></span> is always the subtree being looked
at: it is always a child of the tree root, and is usually a <span class="extract"><span class="extract-syntax">SENTENCE_NT</span></span>
node, hence the name.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. General traversals. </b>It's convenient to have a general system for traversing a syntax tree, visiting
2020-05-11 17:21:29 +03:00
each node in the connected component of the tree root. C doesn't make this sort
of thing easy, though, so there follows a welter of boringly similar functions
with convoluted type signatures.
</p>
2020-05-19 18:36:50 +03:00
<p class="commentary">All these do basically the same thing. <a href="2-st.html#SP10" class="internal">SyntaxTree::traverse</a> calls a visitor
function on each node; <a href="2-st.html#SP10" class="internal">SyntaxTree::traverse_from</a> the same, but from a
2020-05-11 17:21:29 +03:00
chosen start position, rather than the root of the tree.
</p>
<p class="commentary">In this first version, the visitor function has type signature <span class="extract"><span class="extract-syntax">parse_node * -&gt; void</span></span>.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *)) {</span>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><a href="2-st.html#SP10" class="function-link"><span class="function-syntax">SyntaxTree::traverse_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">root_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">visitor</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse_from</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SCS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</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>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-st.html#SP11" class="function-link"><span class="function-syntax">SyntaxTree::visitable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) {</span>
2020-08-02 21:04:24 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP11" class="function-link"><span class="function-syntax">NodeType::is_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) </span><span class="identifier-syntax">current_sentence</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">visitor</span><span class="plain-syntax">)(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2022-09-05 02:08:32 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP10" class="function-link"><span class="function-syntax">NodeType::is_top_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) </span><a href="2-st.html#SP10" class="function-link"><span class="function-syntax">SyntaxTree::traverse_from</span></a><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">visitor</span><span class="plain-syntax">);</span>
2020-08-02 21:04:24 +03:00
<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">SCS</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">SyntaxTree::traverse_run</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *), </span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">X</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SCS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pn.html#SP5" class="function-link"><span class="function-syntax">Node::get_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">) != </span><span class="identifier-syntax">X</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-st.html#SP11" class="function-link"><span class="function-syntax">SyntaxTree::visitable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) {</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP11" class="function-link"><span class="function-syntax">NodeType::is_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2022-09-05 02:08:32 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP10" class="function-link"><span class="function-syntax">NodeType::is_top_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) </span><a href="2-st.html#SP10" class="function-link"><span class="function-syntax">SyntaxTree::traverse_from</span></a><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">visitor</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<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">SCS</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>Note that any node not "visitable" is omitted, where the following function
2020-05-11 17:21:29 +03:00
is the sole arbiter. This depends only on its node type.
</p>
<pre class="displayed-code all-displayed-code code-font">
2020-05-19 18:36:50 +03:00
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::visitable</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">SyntaxTree::visitable</span></span>:<br/><a href="2-st.html#SP10">&#167;10</a>, <a href="2-st.html#SP12">&#167;12</a>, <a href="2-st.html#SP13">&#167;13</a>, <a href="2-st.html#SP14">&#167;14</a>, <a href="2-st.html#SP15">&#167;15</a>, <a href="2-st.html#SP16">&#167;16</a>, <a href="2-st.html#SP17">&#167;17</a>, <a href="2-st.html#SP18">&#167;18</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP10" class="function-link"><span class="function-syntax">NodeType::has_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="constant-syntax">DONT_VISIT_NFLAG</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>And now the same thing, but where the visitor function has the type
2020-05-11 17:21:29 +03:00
signature <span class="extract"><span class="extract-syntax">text_stream *, parse_node * -&gt; void</span></span>.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse_text</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *)) {</span>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><a href="2-st.html#SP12" class="function-link"><span class="function-syntax">SyntaxTree::traverse_text_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">root_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">visitor</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse_text_from</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</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">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SCS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</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>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-st.html#SP11" class="function-link"><span class="function-syntax">SyntaxTree::visitable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) {</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP11" class="function-link"><span class="function-syntax">NodeType::is_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2022-09-05 02:08:32 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP10" class="function-link"><span class="function-syntax">NodeType::is_top_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="2-st.html#SP12" class="function-link"><span class="function-syntax">SyntaxTree::traverse_text_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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">visitor</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<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">SCS</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>And now the same thing, but where the visitor function has the type
2020-05-11 17:21:29 +03:00
signature <span class="extract"><span class="extract-syntax">parse_node *, int * -&gt; void</span></span>.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse_intp</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *), </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X</span><span class="plain-syntax">) {</span>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><a href="2-st.html#SP13" class="function-link"><span class="function-syntax">SyntaxTree::traverse_intp_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">root_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">visitor</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse_intp_from</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node</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">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *), </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SCS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</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>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-st.html#SP11" class="function-link"><span class="function-syntax">SyntaxTree::visitable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) {</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP11" class="function-link"><span class="function-syntax">NodeType::is_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2022-09-05 02:08:32 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP10" class="function-link"><span class="function-syntax">NodeType::is_top_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="2-st.html#SP13" class="function-link"><span class="function-syntax">SyntaxTree::traverse_intp_from</span></a><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">visitor</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<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">SCS</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b>And the same thing, but where the visitor function has the type signature
2020-05-11 17:21:29 +03:00
<span class="extract"><span class="extract-syntax">parse_node *, int *, int * -&gt; void</span></span>.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse_intp_intp</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *), </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Y</span><span class="plain-syntax">) {</span>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><a href="2-st.html#SP14" class="function-link"><span class="function-syntax">SyntaxTree::traverse_intp_intp_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">root_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">visitor</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse_intp_intp_from</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node</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">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *), </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Y</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SCS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</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>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-st.html#SP11" class="function-link"><span class="function-syntax">SyntaxTree::visitable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) {</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP11" class="function-link"><span class="function-syntax">NodeType::is_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2022-09-05 02:08:32 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP10" class="function-link"><span class="function-syntax">NodeType::is_top_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="2-st.html#SP14" class="function-link"><span class="function-syntax">SyntaxTree::traverse_intp_intp_from</span></a><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">visitor</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<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">SCS</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b>And now for <span class="extract"><span class="extract-syntax">parse_node *, parse_node ** -&gt; void</span></span>.
2020-05-11 17:21:29 +03:00
</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">SyntaxTree::traverse_nodep</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> **), </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> **</span><span class="identifier-syntax">X</span><span class="plain-syntax">) {</span>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><a href="2-st.html#SP15" class="function-link"><span class="function-syntax">SyntaxTree::traverse_nodep_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">root_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">visitor</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse_nodep_from</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node</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">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> **), </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> **</span><span class="identifier-syntax">X</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SCS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</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>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-st.html#SP11" class="function-link"><span class="function-syntax">SyntaxTree::visitable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) {</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP11" class="function-link"><span class="function-syntax">NodeType::is_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2022-09-05 02:08:32 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP10" class="function-link"><span class="function-syntax">NodeType::is_top_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="2-st.html#SP15" class="function-link"><span class="function-syntax">SyntaxTree::traverse_nodep_from</span></a><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">visitor</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<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">SCS</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b>This is a tricksier sort of traverse, which tells the visitor function the
2020-05-11 17:21:29 +03:00
heading node it belongs to. The visitor function now has type signature
<span class="extract"><span class="extract-syntax">parse_node_tree *, parse_node *, parse_node *, int * -&gt; void</span></span>, where the
two nodes are the one being visited and its heading, respectively.
</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">SyntaxTree::traverse_headingwise</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">int</span><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>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><a href="2-st.html#SP16" class="function-link"><span class="function-syntax">SyntaxTree::traverse_headingwise_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">root_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">visitor</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse_headingwise_from</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</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">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *),</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_h0</span><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="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SCS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</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>
2022-09-05 02:08:32 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-st.html#SP11" class="function-link"><span class="function-syntax">SyntaxTree::visitable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP11" class="function-link"><span class="function-syntax">NodeType::is_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) </span><span class="identifier-syntax">current_sentence</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">visitor</span><span class="plain-syntax">)(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">last_h0</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP10" class="function-link"><span class="function-syntax">NodeType::is_top_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) {</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">H0</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last_h0</span><span class="plain-syntax">;</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-pn.html#SP5" class="function-link"><span class="function-syntax">Node::is</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="constant-syntax">HEADING_NT</span><span class="plain-syntax">)) &amp;&amp;</span>
2020-08-07 00:01:38 +03:00
<span class="plain-syntax"> (</span><a href="2-na.html#SP7" class="function-link"><span class="function-syntax">Annotations::read_int</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="constant-syntax">heading_level_ANNOT</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">H0</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><a href="2-st.html#SP16" class="function-link"><span class="function-syntax">SyntaxTree::traverse_headingwise_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</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">visitor</span><span class="plain-syntax">, </span><span class="identifier-syntax">H0</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<span class="plain-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">SCS</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. </b>And this is another variation: a traverse to find a node with a particular
2020-05-11 17:21:29 +03:00
property. The process halts as soon as the visitor function, which has
signature <span class="extract"><span class="extract-syntax">parse_node *, parse_node *, parse_node ** -&gt; int</span></span>, returns <span class="extract"><span class="extract-syntax">TRUE</span></span>,
and the idea is that the visitor will store its result in the <span class="extract"><span class="extract-syntax">parse_node *</span></span>
pointed to by its last argument.
</p>
<p class="commentary">Note that this one doesn't record its position in <span class="extract"><span class="extract-syntax">current_sentence</span></span>. The
fuss over top-level nodes is to ensure recursion even though top-level
nodes are not visitable; otherwise the function would never find anything
because no visitable nodes would ever be reached.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse_to_find</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</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">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> **),</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> **</span><span class="identifier-syntax">X</span><span class="plain-syntax">) {</span>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-st.html#SP17" class="function-link"><span class="function-syntax">SyntaxTree::traverse_to_find_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">root_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">visitor</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse_to_find_from</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node</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">int</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> **),</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> **</span><span class="identifier-syntax">X</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">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>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-st.html#SP11" class="function-link"><span class="function-syntax">SyntaxTree::visitable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">))</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP10" class="function-link"><span class="function-syntax">NodeType::is_top_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">))</span>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-st.html#SP17" class="function-link"><span class="function-syntax">SyntaxTree::traverse_to_find_from</span></a><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">visitor</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">))</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-22 14:59:50 +03:00
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b>And still another. This one traverses only up to a given stop position,
2020-05-11 17:21:29 +03:00
and the visitor has signature <span class="extract"><span class="extract-syntax">parse_node *, void ** -&gt; void</span></span>, the idea
being that the final <span class="extract"><span class="extract-syntax">void **</span></span> is a pointer to a general object pointer.
This is the sort of thing which brings C into disrepute, but we don't use
it very much.
</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">SyntaxTree::traverse_up_to_ip</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">end</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> **), </span><span class="reserved-syntax">void</span><span class="plain-syntax"> **</span><span class="identifier-syntax">X</span><span class="plain-syntax">) {</span>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><a href="2-st.html#SP18" class="function-link"><span class="function-syntax">SyntaxTree::traverse_from_up_to_ip</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">end</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">root_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">visitor</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">);</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::traverse_from_up_to_ip</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">end</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</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">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">visitor</span><span class="plain-syntax">)(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> **), </span><span class="reserved-syntax">void</span><span class="plain-syntax"> **</span><span class="identifier-syntax">X</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SCS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pn</span><span class="plain-syntax"> == </span><span class="identifier-syntax">end</span><span class="plain-syntax">) { </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SCS</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; }</span>
2022-09-05 02:08:32 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-st.html#SP11" class="function-link"><span class="function-syntax">SyntaxTree::visitable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP11" class="function-link"><span class="function-syntax">NodeType::is_sentence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) </span><span class="identifier-syntax">current_sentence</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">visitor</span><span class="plain-syntax">)(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nt.html#SP10" class="function-link"><span class="function-syntax">NodeType::is_top_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">node_type</span><span class="plain-syntax">)) {</span>
2020-05-19 18:36:50 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-st.html#SP18" class="function-link"><span class="function-syntax">SyntaxTree::traverse_from_up_to_ip</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">end</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">visitor</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">)) {</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SCS</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SCS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2022-09-05 02:08:32 +03:00
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. Cautious traverses. </b>When logging or verifying the tree, we cannot use the carefree functions
2020-05-11 21:14:00 +03:00
above: the tree might be malformed. As a way to detect cycles, we call for
a new "traverse token" &mdash; just a unique integer value &mdash; and mark all nodes
visited with that value.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pn_log_token</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::new_traverse_token</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">SyntaxTree::new_traverse_token</span></span>:<br/>Parse Nodes - <a href="2-pn.html#SP16">&#167;16</a><br/>Tree Verification - <a href="2-tv.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> ++</span><span class="identifier-syntax">pn_log_token</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2022-09-05 02:08:32 +03:00
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. Toggling log output. </b>Various modules conventionally use this global setting to toggle debugging
2020-05-11 21:14:00 +03:00
log output:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::is_trace_set</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</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">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">trace_sentences</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">SyntaxTree::set_trace</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">trace_sentences</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::clear_trace</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">trace_sentences</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SyntaxTree::toggle_trace</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">trace_sentences</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">trace_sentences</span><span class="plain-syntax">)?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2022-09-05 02:08:32 +03:00
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. Ambiguity subtrees. </b>The following function adds a new <span class="extract"><span class="extract-syntax">reading</span></span> to an <span class="extract"><span class="extract-syntax">existing</span></span> interpretation
2020-05-11 21:14:00 +03:00
of some wording <span class="extract"><span class="extract-syntax">W</span></span>, and return the node now representing. For example,
suppose the text "orange" can be read as a noun for fruit, a noun for colour,
or an adjective, resulting in nodes <span class="extract"><span class="extract-syntax">fruit_node</span></span> and <span class="extract"><span class="extract-syntax">colour_node</span></span> and <span class="extract"><span class="extract-syntax">adj_node</span></span>.
Then:
</p>
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">SyntaxTree::add_reading(NULL, fruit_node, W)</span></span> returns <span class="extract"><span class="extract-syntax">noun_node</span></span>,
</li><li>(b) but <span class="extract"><span class="extract-syntax">SyntaxTree::add_reading(fruit_node, colour_node, W)</span></span> returns this subtree:
</li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> AMBIGUITY_NT A</span>
<span class="plain-syntax"> fruit_node</span>
<span class="plain-syntax"> colour_node</span>
</pre>
<ul class="items"><li>(c) and <span class="extract"><span class="extract-syntax">SyntaxTree::add_reading(A, adj_node, W)</span></span> returns the subtree:
</li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> AMBIGUITY_NT A</span>
<span class="plain-syntax"> fruit_node</span>
<span class="plain-syntax"> colour_node</span>
<span class="plain-syntax"> adj_node</span>
</pre>
<p class="commentary">Thus it accumulates possible readings of a given text.
</p>
<p class="commentary">A complication is that the following callback function is offered the chance
to amend this process in individual cases; it's called whenever <span class="extract"><span class="extract-syntax">reading</span></span>
is about to become one of the alternatives to some existing <span class="extract"><span class="extract-syntax">E</span></span>. If it returns
2020-05-13 01:33:17 +03:00
<span class="extract"><span class="extract-syntax">TRUE</span></span>, we assume it has done something of its own already, and do nothing
further.
2020-05-11 21:14:00 +03:00
</p>
2020-05-13 01:33:17 +03:00
<p class="commentary">(<a href="../inform7/index.html" class="internal">inform7</a> uses this to rearrange ambiguous phrase invocations to be sorted
out in type-checking: see <a href="../values-module/5-dsh.html" class="internal">Dash (in values)</a>.)
2020-05-11 21:14:00 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">SyntaxTree::add_reading</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reading</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">existing</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">reading</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pn.html#SP5" class="function-link"><span class="function-syntax">Node::is</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">reading</span><span class="plain-syntax">, </span><span class="constant-syntax">UNKNOWN_NT</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">existing</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pn.html#SP5" class="function-link"><span class="function-syntax">Node::is</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">reading</span><span class="plain-syntax">, </span><span class="constant-syntax">AMBIGUITY_NT</span><span class="plain-syntax">)) </span><span class="identifier-syntax">reading</span><span class="plain-syntax"> = </span><span class="identifier-syntax">reading</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><a href="2-pn.html#SP5" class="function-link"><span class="function-syntax">Node::is</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="constant-syntax">AMBIGUITY_NT</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">AMBIGUITY_JOIN_SYNTAX_CALLBACK</span>
2020-05-13 01:33:17 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">E</span><span class="plain-syntax">; </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_alternative</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">AMBIGUITY_JOIN_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">reading</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">existing</span><span class="plain-syntax">;</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">existing</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">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">L</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_alternative</span><span class="plain-syntax">)) </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_alternative</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">reading</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">existing</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">AMBIGUITY_JOIN_SYNTAX_CALLBACK</span>
2020-05-13 01:33:17 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">AMBIGUITY_JOIN_SYNTAX_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="identifier-syntax">reading</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">existing</span><span class="plain-syntax">;</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">A</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP3" class="function-link"><span class="function-syntax">Node::new_with_words</span></a><span class="plain-syntax">(</span><span class="constant-syntax">AMBIGUITY_NT</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">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">existing</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">reading</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">A</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-05-11 17:21:29 +03:00
<nav role="progress"><div class="progresscontainer">
2021-02-06 20:00:34 +02:00
<ul class="progressbar"><li class="progressprev"><a href="1-sm.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-sm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresscurrent">st</li><li class="progresssection"><a href="2-nt.html">nt</a></li><li class="progresssection"><a href="2-pn.html">pn</a></li><li class="progresssection"><a href="2-na.html">na</a></li><li class="progresssection"><a href="2-tv.html">tv</a></li><li class="progresssection"><a href="2-spc.html">spc</a></li><li class="progresschapter"><a href="3-snt.html">3</a></li><li class="progressnext"><a href="2-nt.html">&#10095;</a></li></ul></div>
2020-05-11 17:21:29 +03:00
</nav><!--End of weave-->
</main>
</body>
</html>