mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
451 lines
86 KiB
HTML
451 lines
86 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Parse Nodes</title>
|
|
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
|
|
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<script>
|
|
function togglePopup(material_id) {
|
|
var popup = document.getElementById(material_id);
|
|
popup.classList.toggle("show");
|
|
}
|
|
</script>
|
|
|
|
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<script>
|
|
MathJax = {
|
|
tex: {
|
|
inlineMath: '$', '$'], ['\\(', '\\)'
|
|
},
|
|
svg: {
|
|
fontCache: 'global'
|
|
}
|
|
};
|
|
</script>
|
|
<script type="text/javascript" id="MathJax-script" async
|
|
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
|
|
</script>
|
|
|
|
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
|
|
</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 'Parse Nodes' 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>Parse Nodes</b></li></ul></div>
|
|
<p class="purpose">Syntax trees are made of single nodes, each representing one way to understand a given piece of text.</p>
|
|
|
|
<ul class="toc"><li><a href="2-pn.html#SP1">§1. Nodes themselves</a></li><li><a href="2-pn.html#SP2">§2. Creation</a></li><li><a href="2-pn.html#SP5">§5. Annotations</a></li><li><a href="2-pn.html#SP8">§8. Composition</a></li><li><a href="2-pn.html#SP9">§9. Copying parse nodes</a></li><li><a href="2-pn.html#SP12">§12. Child count</a></li><li><a href="2-pn.html#SP13">§13. Detection of subnodes</a></li><li><a href="2-pn.html#SP14">§14. The word range beneath a given node</a></li><li><a href="2-pn.html#SP16">§16. Logging the parse tree</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. Nodes themselves. </b>Each node is an instance of this:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_parsed</span><span class="plain-syntax">; </span><span class="comment-syntax"> the text being interpreted by this node</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">node_type</span><span class="plain-syntax">; </span><span class="comment-syntax"> what the node basically represents</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">annotations</span><span class="plain-syntax">; </span><span class="comment-syntax"> see </span><a href="2-na.html" class="internal">Node Annotations</a>
|
|
|
|
<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">down</span><span class="plain-syntax">; </span><span class="comment-syntax"> pointers within the current interpretation</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">next</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">next_alternative</span><span class="plain-syntax">; </span><span class="comment-syntax"> fork to alternative interpretation</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">score</span><span class="plain-syntax">; </span><span class="comment-syntax"> scratch storage for choosing between interpretations</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_seen_on_traverse</span><span class="plain-syntax">; </span><span class="comment-syntax"> scratch storage for detecting accidental loops</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure parse_node is accessed in 2/st, 2/na, 2/tv and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. Creation. </b></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">Node::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Node::new</span></span>:<br/><a href="2-pn.html#SP3">§3</a>, <a href="2-pn.html#SP9">§9</a>, <a href="2-pn.html#SP11">§11</a><br/>Syntax Trees - <a href="2-st.html#SP2">§2</a><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_3">§6.9.9.3</a>, <a href="3-snt.html#SP6_9_9_3_1_1">§6.9.9.3.1.1</a>, <a href="3-snt.html#SP6_9_9_3_3">§6.9.9.3.3</a>, <a href="3-snt.html#SP7_1">§7.1</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</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="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">t</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-na.html#SP5" class="function-link"><span class="function-syntax">Annotations::clear</span></a><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">pn</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">pn</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">next_alternative</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">pn</span><span class="plain-syntax">-></span><span class="element-syntax">last_seen_on_traverse</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP7" class="function-link"><span class="function-syntax">Node::set_score</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. </b>The following constructor routines fill out the fields in useful ways.
|
|
Here's one if a word range is to be attached:
|
|
</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">Node::new_with_words</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">Node::new_with_words</span></span>:<br/>Syntax Trees - <a href="2-st.html#SP21">§21</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">code_number</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</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="identifier-syntax">code_number</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::set_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pn</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>The attached text.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="function-syntax">Node::get_text</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Node::get_text</span></span>:<br/><a href="2-pn.html#SP14">§14</a>, <a href="2-pn.html#SP15">§15</a>, <a href="2-pn.html#SP17">§17</a>, <a href="2-pn.html#SP18">§18</a><br/>Simple Preform Cache - <a href="2-spc.html#SP2">§2</a></span></button><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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pn</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">EMPTY_WORDING</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</span><span class="plain-syntax">-></span><span class="element-syntax">text_parsed</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">Node::set_text</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">Node::set_text</span></span>:<br/><a href="2-pn.html#SP2">§2</a>, <a href="2-pn.html#SP3">§3</a><br/>Simple Preform Cache - <a href="2-spc.html#SP2">§2</a><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_6">§6.9.6</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_3">§6.9.9.3</a>, <a href="3-snt.html#SP6_9_9_3_1_1">§6.9.9.3.1.1</a>, <a href="3-snt.html#SP6_9_9_3_3">§6.9.9.3.3</a>, <a href="3-snt.html#SP7_1">§7.1</a></span></button><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="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">pn</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">"tried to set words for null node"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">text_parsed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. Annotations. </b>It's easily overlooked that the single most useful piece of information
|
|
at each node is its node type, accessed as follows:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="function-syntax">Node::get_type</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">Node::get_type</span></span>:<br/>Syntax Trees - <a href="2-st.html#SP4">§4</a>, <a href="2-st.html#SP4_1">§4.1</a>, <a href="2-st.html#SP10">§10</a><br/>Node Annotations - <a href="2-na.html#SP16">§16</a><br/>Tree Verification - <a href="2-tv.html#SP2">§2</a>, <a href="2-tv.html#SP4">§4</a>, <a href="2-tv.html#SP4_3">§4.3</a></span></button><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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pn</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="constant-syntax">INVALID_NT</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</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">int</span><span class="plain-syntax"> </span><span class="function-syntax">Node::is</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">Node::is</span></span>:<br/><a href="2-pn.html#SP17">§17</a><br/>Syntax Trees - <a href="2-st.html#SP16">§16</a>, <a href="2-st.html#SP21">§21</a><br/>Tree Verification - <a href="2-tv.html#SP4_1_1">§4.1.1</a></span></button><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="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><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">node_type</span><span class="plain-syntax"> == </span><span class="identifier-syntax">t</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. </b>When setting, we have to preserve the invariant, so we clear away any
|
|
annotations no longer relevant to the node's new identity.
|
|
</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">Node::set_type</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">Node::set_type</span></span>:<br/>Sentences - <a href="3-snt.html#SP6_9">§6.9</a>, <a href="3-snt.html#SP6_9_4">§6.9.4</a>, <a href="3-snt.html#SP6_9_5">§6.9.5</a>, <a href="3-snt.html#SP6_9_6">§6.9.6</a></span></button><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="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">IMMUTABLE_NODE</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><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">IMMUTABLE_NODE</span><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$P changed to $N\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"immutable type changed"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
|
|
|
|
<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">nt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="2-na.html#SP16" class="function-link"><span class="function-syntax">Annotations::clear_invalid</span></a><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="function-syntax">Node::set_type_and_clear_annotations</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="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">node_type</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="2-na.html#SP5" class="function-link"><span class="function-syntax">Annotations::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</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>The integer score, used in choosing best matches:
|
|
</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">Node::get_score</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Node::get_score</span></span>:<br/><a href="2-pn.html#SP17">§17</a></span></button><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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">score</span><span class="plain-syntax">; }</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Node::set_score</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Node::set_score</span></span>:<br/><a href="2-pn.html#SP2">§2</a></span></button><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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s</span><span class="plain-syntax">) { </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">score</span><span class="plain-syntax"> = </span><span class="identifier-syntax">s</span><span class="plain-syntax">; }</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. Composition. </b>This simply means stringing two nodes together into a list.
|
|
</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">Node::compose</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><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B</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">A</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">B</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">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</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>
|
|
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. Copying parse nodes. </b>If we want to duplicate a parse node, we cannot do so with a shallow bit copy:
|
|
the node points to a list of its annotations, and the duplicated node would
|
|
therefore point to the same list. If, subsequently, one of the two nodes
|
|
were annotated further, then the other would change in synchrony, which
|
|
would be the source of mysterious bugs. We therefore need to perform a
|
|
deep copy which duplicates not only the node, but also its annotation list.
|
|
</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">Node::copy</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Node::copy</span></span>:<br/><a href="2-pn.html#SP10">§10</a>, <a href="2-pn.html#SP11">§11</a></span></button><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="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">COPY</span><span class="plain-syntax">(</span><span class="identifier-syntax">to</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="plain-syntax"> </span><a href="2-na.html#SP12" class="function-link"><span class="function-syntax">Annotations::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">to</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">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">Node::duplicate</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="plain-syntax"> </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dup</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">INVALID_NT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP9" class="function-link"><span class="function-syntax">Node::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">dup</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">dup</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>§10. </b>This variation preserves links out.
|
|
</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">Node::copy_in_place</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="reserved-syntax">parse_node</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_link</span><span class="plain-syntax"> = </span><span class="identifier-syntax">to</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt_link</span><span class="plain-syntax"> = </span><span class="identifier-syntax">to</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">down_link</span><span class="plain-syntax"> = </span><span class="identifier-syntax">to</span><span class="plain-syntax">-></span><span class="element-syntax">down</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP9" class="function-link"><span class="function-syntax">Node::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">to</span><span class="plain-syntax">, </span><span class="identifier-syntax">from</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">next_link</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax">-></span><span class="element-syntax">next_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">alt_link</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax">-></span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">down_link</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>And to deep-copy a whole subtree:
|
|
</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">Node::copy_subtree</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">to</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">level</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">from</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">to</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">"Null deep copy"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP9" class="function-link"><span class="function-syntax">Node::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">to</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">from</span><span class="plain-syntax">-></span><span class="element-syntax">down</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax">-></span><span class="element-syntax">down</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">INVALID_NT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP11" class="function-link"><span class="function-syntax">Node::copy_subtree</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">-></span><span class="identifier-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">-></span><span class="element-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">level</span><span class="plain-syntax">+1);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">level</span><span class="plain-syntax">>0) && (</span><span class="identifier-syntax">from</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax">-></span><span class="element-syntax">next</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">INVALID_NT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP11" class="function-link"><span class="function-syntax">Node::copy_subtree</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">-></span><span class="identifier-syntax">next</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">, </span><span class="identifier-syntax">level</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">level</span><span class="plain-syntax">>0) && (</span><span class="identifier-syntax">from</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">to</span><span class="plain-syntax">-></span><span class="element-syntax">next_alternative</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">INVALID_NT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP11" class="function-link"><span class="function-syntax">Node::copy_subtree</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">-></span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">-></span><span class="element-syntax">next_alternative</span><span class="plain-syntax">, </span><span class="identifier-syntax">level</span><span class="plain-syntax">);</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. Child count. </b></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">Node::no_children</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">c</span><span class="plain-syntax">=0;</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">p</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">down</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">) </span><span class="identifier-syntax">c</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">c</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. Detection of subnodes. </b>This is needed when producing problem messages: we may need to work up from
|
|
an arbitrary leaf to the main sentence branch containing it. At any rate,
|
|
given a node <span class="extract"><span class="extract-syntax">PN</span></span>, we want to know if another node <span class="extract"><span class="extract-syntax">to_find</span></span> lies beneath
|
|
it. (This will never be called when <span class="extract"><span class="extract-syntax">PN</span></span> is the root, and from all other
|
|
nodes it will certainly run quickly, since the tree is otherwise neither
|
|
wide nor deep.)
|
|
</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">Node::contains</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to_find</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">to_try</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">to_find</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">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">to_try</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">to_try</span><span class="plain-syntax">; </span><span class="identifier-syntax">to_try</span><span class="plain-syntax"> = </span><span class="identifier-syntax">to_try</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#SP13" class="function-link"><span class="function-syntax">Node::contains</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">to_try</span><span class="plain-syntax">, </span><span class="identifier-syntax">to_find</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>§14. The word range beneath a given node. </b>Any given node may be the root of a subtree concerning the structure of
|
|
a given contiguous range of words in the original source text. The
|
|
"left edge" of a node <span class="extract"><span class="extract-syntax">PN</span></span> is the least-numbered word considered by any
|
|
node at or below <span class="extract"><span class="extract-syntax">PN</span></span> in the tree; the "right edge" is the highest-numbered
|
|
word similarly considered.
|
|
</p>
|
|
|
|
<p class="commentary">The left edge is calculated by taking the minimum value of the word number
|
|
for <span class="extract"><span class="extract-syntax">PN</span></span> and the left edges of its children, except that \(-1\) is not counted.
|
|
(A left edge of \(-1\) means no source text is here.)
|
|
</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">Node::left_edge_of</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">child</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">Wordings::first_wn</span><span class="plain-syntax">(</span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::get_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PN</span><span class="plain-syntax">)), </span><span class="identifier-syntax">lc</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">child</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">child</span><span class="plain-syntax">; </span><span class="identifier-syntax">child</span><span class="plain-syntax"> = </span><span class="identifier-syntax">child</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">lc</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP14" class="function-link"><span class="function-syntax">Node::left_edge_of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">child</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">lc</span><span class="plain-syntax"> >= </span><span class="constant-syntax">0</span><span class="plain-syntax">) && ((</span><span class="identifier-syntax">l</span><span class="plain-syntax"> == -1) || (</span><span class="identifier-syntax">lc</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="identifier-syntax">lc</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">l</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>Symmetrically, the right edge is found by taking the maximum word number
|
|
for <span class="extract"><span class="extract-syntax">PN</span></span> and the right edges of its children.
|
|
</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">Node::right_edge_of</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">child</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">r</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::get_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PN</span><span class="plain-syntax">)), </span><span class="identifier-syntax">rc</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::get_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PN</span><span class="plain-syntax">)) < </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">r</span><span class="plain-syntax"> = -1;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">child</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">child</span><span class="plain-syntax">; </span><span class="identifier-syntax">child</span><span class="plain-syntax"> = </span><span class="identifier-syntax">child</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">rc</span><span class="plain-syntax"> = </span><a href="2-pn.html#SP15" class="function-link"><span class="function-syntax">Node::right_edge_of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">child</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">rc</span><span class="plain-syntax"> >= </span><span class="constant-syntax">0</span><span class="plain-syntax">) && ((</span><span class="identifier-syntax">r</span><span class="plain-syntax"> == -1) || (</span><span class="identifier-syntax">rc</span><span class="plain-syntax"> > </span><span class="identifier-syntax">r</span><span class="plain-syntax">))) </span><span class="identifier-syntax">r</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rc</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">r</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. Logging the parse tree. </b>For most trees, logging is a fearsome prospect, but here we only mean printing
|
|
out a textual representation to the debugging log.
|
|
</p>
|
|
|
|
<p class="commentary">There are two ways to recurse through it: logging the entire tree as seen from
|
|
a given node, or logging just the "subtree" of that node: meaning, itself and
|
|
everything beneath it, but not its siblings or alternatives. Each recursion
|
|
has its own unique token value, used to prevent infinite loops in the event
|
|
that we're logging a badly-formed tree; this should never happen, but since
|
|
logging is a diagnostic tool, we want it to work even when Inform is sick.
|
|
</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">Node::log_tree</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Node::log_tree</span></span>:<br/>Syntax Module - <a href="1-sm.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vpn</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">pn</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">vpn</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">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"<null-meaning-list>\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP17" class="function-link"><span class="function-syntax">Node::log_subtree_recursively</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="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">1</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#SP19" class="function-link"><span class="function-syntax">SyntaxTree::new_traverse_token</span></a><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">Node::summarise_tree</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vpn</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">pn</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">vpn</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">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"<null-meaning-list>\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP17" class="function-link"><span class="function-syntax">Node::log_subtree_recursively</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="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><a href="2-st.html#SP19" class="function-link"><span class="function-syntax">SyntaxTree::new_traverse_token</span></a><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">Node::log_subtree</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Node::log_subtree</span></span>:<br/>Syntax Module - <a href="1-sm.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vpn</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">pn</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">vpn</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">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"<null-parse-node>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"$P\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">down</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP17" class="function-link"><span class="function-syntax">Node::log_subtree_recursively</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="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">1</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#SP19" class="function-link"><span class="function-syntax">SyntaxTree::new_traverse_token</span></a><span class="plain-syntax">());</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</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>Either way, we recurse as follows, being careful not to make recursive calls
|
|
to pursue <span class="extract"><span class="extract-syntax">next</span></span> links, since otherwise a source text with more than 100,000
|
|
sentences or so will exceed the typical stack size Inform has to run in.
|
|
</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">Node::log_subtree_recursively</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Node::log_subtree_recursively</span></span>:<br/><a href="2-pn.html#SP16">§16</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">num</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">of</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">summarise</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">traverse_token</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">active</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">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pn</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">last_seen_on_traverse</span><span class="plain-syntax"> == </span><span class="identifier-syntax">traverse_token</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"*** Not a tree: %W ***\n"</span><span class="plain-syntax">, </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::get_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">)); </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">last_seen_on_traverse</span><span class="plain-syntax"> = </span><span class="identifier-syntax">traverse_token</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pn.html#SP17_1" class="named-paragraph-link"><span class="named-paragraph">Calculate num and of such that this is [num/of] if they aren't already supplied</span><span class="named-paragraph-number">17.1</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pn</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"<null-parse-node>\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">summarise</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">ENDHERE_NT</span><span class="plain-syntax">)) </span><span class="identifier-syntax">active</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">active</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">of</span><span class="plain-syntax"> > </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[%d/%d] "</span><span class="plain-syntax">, </span><span class="identifier-syntax">num</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</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#SP7" class="function-link"><span class="function-syntax">Node::get_score</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"(score %d) "</span><span class="plain-syntax">, </span><a href="2-pn.html#SP7" class="function-link"><span class="function-syntax">Node::get_score</span></a><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="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"$P\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">down</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</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">recurse</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">IMPERATIVE_NT</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">summarise</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="identifier-syntax">IMPERATIVE_NT</span><span class="plain-syntax">))) </span><span class="identifier-syntax">recurse</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">endif</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">recurse</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP17" class="function-link"><span class="function-syntax">Node::log_subtree_recursively</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">,</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="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">gen</span><span class="plain-syntax">+1, </span><span class="identifier-syntax">summarise</span><span class="plain-syntax">, </span><span class="identifier-syntax">traverse_token</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">next_alternative</span><span class="plain-syntax">) </span><a href="2-pn.html#SP17" class="function-link"><span class="function-syntax">Node::log_subtree_recursively</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">next_alternative</span><span class="plain-syntax">, </span><span class="identifier-syntax">num</span><span class="plain-syntax">+1, </span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">gen</span><span class="plain-syntax">+1, </span><span class="identifier-syntax">summarise</span><span class="plain-syntax">, </span><span class="identifier-syntax">traverse_token</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">summarise</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">BEGINHERE_NT</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">active</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"...\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">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="identifier-syntax">num</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">gen</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP17_1" class="paragraph-anchor"></a><b>§17.1. </b>When the first alternative is called, <span class="extract"><span class="extract-syntax">Node::log_subtree_recursively</span></span>
|
|
has arguments 0 and 0 for the possibility. The following code finds out the
|
|
correct value for <span class="extract"><span class="extract-syntax">of</span></span>, setting this possibility to be <span class="extract"><span class="extract-syntax">[1/of]</span></span>. When we later
|
|
iterate through other alternatives, we pass on correct values of <span class="extract"><span class="extract-syntax">num</span></span> and <span class="extract"><span class="extract-syntax">of</span></span>,
|
|
so that this code won't be used again on the same horizontal list of possibilities.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Calculate num and of such that this is [num/of] if they aren't already supplied</span><span class="named-paragraph-number">17.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">num</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn2</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">pn2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">pn2</span><span class="plain-syntax">; </span><span class="identifier-syntax">pn2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn2</span><span class="plain-syntax">-></span><span class="element-syntax">next_alternative</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax">++) ;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">num</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="2-pn.html#SP17">§17</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>§18. </b>All of those routines make use of the following, which actually performs
|
|
the log of a parse node.
|
|
</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">Node::log_node</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Node::log_node</span></span>:<br/>Syntax Module - <a href="1-sm.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vpn</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">pn</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">vpn</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">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"<null-parse-node>"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> </span><a href="2-nt.html#SP8" class="function-link"><span class="function-syntax">NodeType::log</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="identifier-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">Wordings::nonempty</span><span class="plain-syntax">(</span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::get_text</span></a><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">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="string-syntax">"%W"</span><span class="plain-syntax">, </span><a href="2-pn.html#SP4" class="function-link"><span class="function-syntax">Node::get_text</span></a><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">Str::truncate</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="constant-syntax">60</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"'%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="2-na.html#SP2" class="function-link"><span class="function-syntax">Annotations::write_annotations</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="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">a</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">next_alternative</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">a</span><span class="plain-syntax"><9)) </span><span class="identifier-syntax">a</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_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">a</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"/%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">a</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">Node::write_node</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Node::write_node</span></span>:<br/>Syntax Module - <a href="1-sm.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">format_string</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vpn</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="2-pn.html#SP18" class="function-link"><span class="function-syntax">Node::log_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">vpn</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="2-nt.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="progresssection"><a href="2-st.html">st</a></li><li class="progresssection"><a href="2-nt.html">nt</a></li><li class="progresscurrent">pn</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-na.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|