mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
596 lines
115 KiB
HTML
596 lines
115 KiB
HTML
<!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">
|
|
<h1><a href="../index.html">
|
|
<img src="../docs-assets/Inform.png" height=72">
|
|
</a></h1>
|
|
<ul><li><a href="../index.html">home</a></li>
|
|
</ul><h2>Compiler</h2><ul>
|
|
<li><a href="../structure.html">structure</a></li>
|
|
<li><a href="../inbuildn.html">inbuild</a></li>
|
|
<li><a href="../inform7n.html">inform7</a></li>
|
|
<li><a href="../intern.html">inter</a></li>
|
|
<li><a href="../services.html">services</a></li>
|
|
<li><a href="../secrets.html">secrets</a></li>
|
|
</ul><h2>Other Tools</h2><ul>
|
|
<li><a href="../inblorbn.html">inblorb</a></li>
|
|
<li><a href="../indocn.html">indoc</a></li>
|
|
<li><a href="../inform6.html">inform6</a></li>
|
|
<li><a href="../inpolicyn.html">inpolicy</a></li>
|
|
<li><a href="../inrtpsn.html">inrtps</a></li>
|
|
</ul><h2>Resources</h2><ul>
|
|
<li><a href="../extensions.html">extensions</a></li>
|
|
<li><a href="../kits.html">kits</a></li>
|
|
</ul><h2>Repository</h2><ul>
|
|
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
|
|
</ul><h2>Related Projects</h2><ul>
|
|
<li><a href="../../../inweb/index.html">inweb</a></li>
|
|
<li><a href="../../../intest/index.html">intest</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'Syntax Trees' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../services.html">Services</a></li><li><a href="index.html">syntax</a></li><li><a href="index.html#2">Chapter 2: The Parse Tree</a></li><li><b>Syntax Trees</b></li></ul></div>
|
|
<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>
|
|
|
|
<ul class="toc"><li><a href="2-st.html#SP1">§1. Optional headings tree</a></li><li><a href="2-st.html#SP2">§2. Syntax trees</a></li><li><a href="2-st.html#SP3">§3. Buds and grafts</a></li><li><a href="2-st.html#SP9">§9. Where we currently are in the text</a></li><li><a href="2-st.html#SP10">§10. General traversals</a></li><li><a href="2-st.html#SP19">§19. Cautious traverses</a></li><li><a href="2-st.html#SP20">§20. Toggling log output</a></li><li><a href="2-st.html#SP21">§21. Ambiguity subtrees</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§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
|
|
<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>
|
|
|
|
<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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. Syntax trees. </b>Each <a href="2-st.html#SP2" class="internal">parse_node_tree</a> object represents a different syntax tree; typically
|
|
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>
|
|
<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>
|
|
<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>
|
|
<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>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-></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>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-></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">-></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">-></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><span class="identifier-syntax">T</span><span class="plain-syntax">-></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="identifier-syntax">T</span><span class="plain-syntax">-></span><span class="element-syntax">contains_dialogue</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</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">T</span><span class="plain-syntax">-></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">-></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>
|
|
<ul class="endnotetexts"><li>The structure parse_node_tree is accessed in 2/tv, 3/snt and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. Buds and grafts. </b>"Buds" are positions in the tree to which new sentence subtrees can be grafted:
|
|
</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">§2</a>, <a href="2-st.html#SP4">§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">-></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">-></span><span class="identifier-syntax">bud_parent_sp</span><span class="plain-syntax"> >= </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">-></span><span class="element-syntax">bud_parent_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">T</span><span class="plain-syntax">-></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">-></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>
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. </b>Sentences are grafted onto the bud position at the top of the stack.
|
|
</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::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">§6.1</a>, <a href="3-snt.html#SP6_6">§6.6</a>, <a href="3-snt.html#SP6_9_3">§6.9.3</a>, <a href="3-snt.html#SP6_9_9_1">§6.9.9.1</a>, <a href="3-snt.html#SP6_9_9_2">§6.9.9.2</a>, <a href="3-snt.html#SP6_9_9_2_1_1">§6.9.9.2.1.1</a>, <a href="3-snt.html#SP6_9_9_2_3">§6.9.9.2.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>
|
|
<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">-></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>
|
|
<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>
|
|
<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">-></span><span class="element-syntax">bud_parent_stack</span><span class="plain-syntax">[</span><span class="identifier-syntax">T</span><span class="plain-syntax">-></span><span class="element-syntax">bud_parent_sp</span><span class="plain-syntax">-1];</span>
|
|
<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>
|
|
<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>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP4_1" class="paragraph-anchor"></a><b>§4.1. </b>When what's attached is a heading node, that changes the stack. The idea
|
|
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">
|
|
<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>
|
|
<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"> > </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">-></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">>=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">-></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>
|
|
<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">) &&</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">P</span><span class="plain-syntax">, </span><span class="constant-syntax">heading_level_ANNOT</span><span class="plain-syntax">) >= </span><span class="identifier-syntax">heading_level</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-></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">§4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. </b>Syntax trees for Inform source text have a tendency to be wide. If a source
|
|
text is basically a list of 5000 sentences, then there may be a node with 5000
|
|
children, even though the maximum depth of the tree might be as low as 10.
|
|
</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">§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">-></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">-></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">§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">-></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>
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. </b>The function <span class="extract"><span class="extract-syntax">SyntaxTree::graft</span></span> is named by analogy with gardening, where the
|
|
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">
|
|
<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">§4</a><br/>Sentences - <a href="3-snt.html#SP6_9_9_2">§6.9.9.2</a>, <a href="3-snt.html#SP7_1">§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>
|
|
<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">-></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">-></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">-></span><span class="element-syntax">root_node</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-></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">-></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">-></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="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">-></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">-></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">-></span><span class="element-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">elder</span><span class="plain-syntax">-></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">-></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">-></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>
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. </b>No speed worries on the much smaller trees with alternative readings:
|
|
</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">-></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">-></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">-></span><span class="element-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">elder</span><span class="plain-syntax">-></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">-></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">-></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>
|
|
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. </b>And we can loop through these like so:
|
|
</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">-></span><span class="element-syntax">next_alternative</span><span class="plain-syntax">)</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. Where we currently are in the text. </b>Inform makes many traverses through the big parse tree, often modifying as it
|
|
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>
|
|
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>§10. General traversals. </b>It's convenient to have a general system for traversing a syntax tree, visiting
|
|
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>
|
|
|
|
<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
|
|
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 * -> 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>
|
|
<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">-></span><span class="identifier-syntax">root_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">visitor</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_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">-></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-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">-></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">-></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>
|
|
<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">-></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">-></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="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">-></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">-></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">-></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>
|
|
<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">-></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">-></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="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>
|
|
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>§11. </b>Note that any node not "visitable" is omitted, where the following function
|
|
is the sole arbiter. This depends only on its node type.
|
|
</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::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">§10</a>, <a href="2-st.html#SP12">§12</a>, <a href="2-st.html#SP13">§13</a>, <a href="2-st.html#SP14">§14</a>, <a href="2-st.html#SP15">§15</a>, <a href="2-st.html#SP16">§16</a>, <a href="2-st.html#SP17">§17</a>, <a href="2-st.html#SP18">§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>
|
|
<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>
|
|
<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>
|
|
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>§12. </b>And now the same thing, but where the visitor function has the type
|
|
signature <span class="extract"><span class="extract-syntax">text_stream *, parse_node * -> 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>
|
|
<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">-></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="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">-></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-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">-></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">-></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">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><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">-></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">-></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="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>
|
|
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>§13. </b>And now the same thing, but where the visitor function has the type
|
|
signature <span class="extract"><span class="extract-syntax">parse_node *, int * -> 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>
|
|
<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">-></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="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">-></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-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">-></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">-></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>
|
|
<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">-></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">-></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="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>
|
|
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>§14. </b>And the same thing, but where the visitor function has the type signature
|
|
<span class="extract"><span class="extract-syntax">parse_node *, int *, int * -> 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>
|
|
<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">-></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>
|
|
<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">-></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-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">-></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">-></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="identifier-syntax">Y</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><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">-></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">-></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>
|
|
<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>
|
|
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>§15. </b>And now for <span class="extract"><span class="extract-syntax">parse_node *, parse_node ** -> 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_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>
|
|
<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">-></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="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">-></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-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">-></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">-></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>
|
|
<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">-></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">-></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="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>
|
|
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>§16. </b>This is a tricksier sort of traverse, which tells the visitor function the
|
|
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 * -> 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>
|
|
<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">-></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>
|
|
<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">-></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-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">-></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">-></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>
|
|
<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">-></span><span class="element-syntax">node_type</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">H0</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last_h0</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">pn</span><span class="plain-syntax">, </span><span class="constant-syntax">HEADING_NT</span><span class="plain-syntax">)) &&</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">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>
|
|
<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>
|
|
<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">-></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>
|
|
<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>
|
|
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>§17. </b>And this is another variation: a traverse to find a node with a particular
|
|
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 ** -> 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>
|
|
<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">-></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>
|
|
<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">-></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-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">-></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><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>
|
|
<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">-></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-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">-></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>
|
|
<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>
|
|
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>§18. </b>And still another. This one traverses only up to a given stop position,
|
|
and the visitor has signature <span class="extract"><span class="extract-syntax">parse_node *, void ** -> 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>
|
|
<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">-></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="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">-></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>
|
|
<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">-></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">-></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>
|
|
<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">-></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-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">-></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="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>
|
|
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>§19. Cautious traverses. </b>When logging or verifying the tree, we cannot use the carefree functions
|
|
above: the tree might be malformed. As a way to detect cycles, we call for
|
|
a new "traverse token" — just a unique integer value — 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">§16</a><br/>Tree Verification - <a href="2-tv.html#SP1">§1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">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>
|
|
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>§20. Toggling log output. </b>Various modules conventionally use this global setting to toggle debugging
|
|
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">-></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">-></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">-></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">-></span><span class="element-syntax">trace_sentences</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-></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>
|
|
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>§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
|
|
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
|
|
<span class="extract"><span class="extract-syntax">TRUE</span></span>, we assume it has done something of its own already, and do nothing
|
|
further.
|
|
</p>
|
|
|
|
<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>.)
|
|
</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">-></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>
|
|
<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">-></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">-></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>
|
|
<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">-></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">) && (</span><span class="identifier-syntax">L</span><span class="plain-syntax">-></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">-></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">-></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>
|
|
<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>
|
|
<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">-></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">-></span><span class="element-syntax">down</span><span class="plain-syntax">-></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>
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="1-sm.html">❮</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">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|