mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 10:04:21 +03:00
1571 lines
328 KiB
HTML
1571 lines
328 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Parse Tree</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="../compiler.html">compiler tools</a></li>
|
|
<li><a href="../other.html">other tools</a></li>
|
|
<li><a href="../extensions.html">extensions and kits</a></li>
|
|
<li><a href="../units.html">unit test tools</a></li>
|
|
</ul><h2>Compiler Webs</h2><ul>
|
|
<li><a href="../inbuild/index.html">inbuild</a></li>
|
|
<li><a href="../inform7/index.html">inform7</a></li>
|
|
<li><a href="../inter/index.html">inter</a></li>
|
|
</ul><h2>Inbuild Modules</h2><ul>
|
|
<li><a href="../supervisor-module/index.html">supervisor</a></li>
|
|
</ul><h2>Inform7 Modules</h2><ul>
|
|
<li><a href="../core-module/index.html">core</a></li>
|
|
<li><a href="../inflections-module/index.html">inflections</a></li>
|
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
|
<li><a href="../kinds-module/index.html">kinds</a></li>
|
|
<li><a href="../if-module/index.html">if</a></li>
|
|
<li><a href="../multimedia-module/index.html">multimedia</a></li>
|
|
<li><a href="../problems-module/index.html">problems</a></li>
|
|
<li><a href="../index-module/index.html">index</a></li>
|
|
</ul><h2>Inter Modules</h2><ul>
|
|
<li><a href="../bytecode-module/index.html">bytecode</a></li>
|
|
<li><a href="../building-module/index.html">building</a></li>
|
|
<li><a href="../codegen-module/index.html">codegen</a></li>
|
|
</ul><h2>Shared Modules</h2><ul>
|
|
<li><a href="../arch-module/index.html">arch</a></li>
|
|
<li><a href="index.html"><span class="selectedlink">syntax</span></a></li>
|
|
<li><a href="../words-module/index.html">words</a></li>
|
|
<li><a href="../html-module/index.html">html</a></li>
|
|
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'Parse Tree' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</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 Tree</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-pt.html#SP1">§1. Trees store meanings</a></li><li><a href="2-pt.html#SP4">§4. Structural vs specifications</a></li><li><a href="2-pt.html#SP5">§5. Node types</a></li><li><a href="2-pt.html#SP7">§7. The structure</a></li><li><a href="2-pt.html#SP8">§8. Where we currently are in the text</a></li><li><a href="2-pt.html#SP12">§12. Node metadata</a></li><li><a href="2-pt.html#SP16">§16. The metadata table</a></li><li><a href="2-pt.html#SP20">§20. Logging node types</a></li><li><a href="2-pt.html#SP21">§21. Creation</a></li><li><a href="2-pt.html#SP24">§24. Annotations</a></li><li><a href="2-pt.html#SP33">§33. Copying parse nodes</a></li><li><a href="2-pt.html#SP36">§36. Child count</a></li><li><a href="2-pt.html#SP37">§37. Detection of subnodes</a></li><li><a href="2-pt.html#SP38">§38. The word range beneath a given node</a></li><li><a href="2-pt.html#SP45">§45. Logging the parse tree</a></li><li><a href="2-pt.html#SP50">§50. General traversals</a></li><li><a href="2-pt.html#SP52">§52. Verify integrity</a></li><li><a href="2-pt.html#SP54">§54. Verify structure</a></li><li><a href="2-pt.html#SP56">§56. Parentage rules</a></li><li><a href="2-pt.html#SP58">§58. Annotation rules</a></li><li><a href="2-pt.html#SP60">§60. Ambiguity subtrees</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1"></a><b>§1. Trees store meanings. </b>Most algorithms for parsing natural language involve the construction of
|
|
trees, in which the original words appear as leaves at the top of the tree,
|
|
while the grammatical functions they serve appear as the branches and trunk:
|
|
thus the word "orange", as an adjective, might be growing from a branch
|
|
which represents a noun clause ("the orange envelope"), growing in turn from
|
|
a trunk which in turn might represent a assertion sentence:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>The card is in the orange envelope.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">Inform goes further than this. The result of parsing any piece of text is
|
|
always a tree, so that a common data structure is used for every meaning
|
|
which is stored inside Inform.
|
|
</p>
|
|
|
|
<p class="commentary">The tree is stored as a collection of "parse nodes", with <span class="extract"><span class="extract-syntax">next</span></span> and
|
|
<span class="extract"><span class="extract-syntax">down</span></span> links between them to represent siblings and children.
|
|
</p>
|
|
|
|
<p class="commentary">Some text is ambiguous. Because of that, the tree needs to be capable of
|
|
representing multiple interpretations of the same wording. So nodes also
|
|
have a <span class="extract"><span class="extract-syntax">next_alternative</span></span> link, which — if used — forks the tree into
|
|
different possible readings.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_ATTACHMENT_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">attachment_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">attachment_stack_parent</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_ATTACHMENT_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">one_off_attachment_point</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">MEMORY_MANAGEMENT</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">ParseTree::new_tree</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-pt.html#SP21" class="function-link"><span class="function-syntax">ParseTree::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">attachment_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">one_off_attachment_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP2" class="function-link"><span class="function-syntax">ParseTree::push_attachment_point</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="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 private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2"></a><b>§2. </b>It turns out to be convenient to have a mechanism for inserting sentences,
|
|
the main large-scale structural nodes, into the tree. These come in a
|
|
stream in the source text, but can attach at different levels in the tree,
|
|
since each sentence needs to be a child of the relevant heading node
|
|
under which it falls. We therefore keep a stack of open headings:
|
|
</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">ParseTree::push_attachment_point</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">ParseTree::push_attachment_point</span></span>:<br/><a href="2-pt.html#SP1">§1</a>, <a href="2-pt.html#SP44">§44</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">attachment_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">attachment_sp</span><span class="plain-syntax"> >= </span><span class="constant-syntax">MAX_ATTACHMENT_STACK_SIZE</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"attachment 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">attachment_stack_parent</span><span class="plain-syntax">[</span><span class="identifier-syntax">T</span><span class="plain-syntax">-></span><span class="element-syntax">attachment_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">ParseTree::pop_attachment_point</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">attachment_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="SP3"></a><b>§3. </b>In addition, we can temporarily override this system:
|
|
</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">ParseTree::set_attachment_point_one_off</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">to</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">one_off_attachment_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">to</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP4"></a><b>§4. Structural vs specifications. </b>Each node has a "node type". About half of the node types are called
|
|
"structural", with the remainder being "specifications". Structural nodes
|
|
represent the large-scale structure of the source text: from headings down to
|
|
code points in routines. The shape of the above assertion sentence, for
|
|
example, is made up of structural nodes.
|
|
</p>
|
|
|
|
<p class="commentary">Specification nodes represent data rather than structure. For example, in
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>The tally is a number that varies. The tally is 124.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">the value "124" is stored as a single specification node, of node type
|
|
<span class="extract"><span class="extract-syntax">CONSTANT_NT</span></span>. But more elaborate possibilities exist:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>tally is 124 and the player is in the Library</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">is stored as a tree of three specification nodes:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> LOGICAL_AND_NT</span>
|
|
<span class="plain-syntax"> TEST_PROPOSITION_NT "tally is 124"</span>
|
|
<span class="plain-syntax"> TEST_PROPOSITION_NT "the player is in the Library"</span>
|
|
</pre>
|
|
<p class="commentary">The tree is heavily annotated, so that nodes can carry more meaning than
|
|
just their type alone. For example, the <span class="extract"><span class="extract-syntax">CONSTANT_NT</span></span> node for "124"
|
|
is annotated with the kind <span class="extract"><span class="extract-syntax">K_number</span></span>, showing what kind of constant it
|
|
represents. The <span class="extract"><span class="extract-syntax">TEST_PROPOSITION_NT</span></span> nodes are annotated with
|
|
logical propositions. There's a huge variety of different annotations
|
|
used in different contexts, most of them relevant only for certain node
|
|
types. Some of these point to structures which in turn point back to
|
|
the tree: for example, the proposition "tally is 124" is stored as
|
|
a <span class="extract"><span class="extract-syntax">pcalc_prop</span></span> structure which indirectly contains the values "tally"
|
|
and "124", which are both represented as parse nodes.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP5"></a><b>§5. Node types. </b>The basic meaning of a node is represented by its "node type". Though
|
|
they are only used fleetingly, and never remain in either the structural
|
|
tree or as stored values, every valid meaning code (i.e., every <span class="extract"><span class="extract-syntax">*_MC</span></span>
|
|
constant) is also a valid node type. Since meaning codes are integers
|
|
with a single bit set, and we need up to 31 of them, we enumerate
|
|
node types as values with bit 32 set. That being so, node types have
|
|
to be stored unsigned, and for portability we define:
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="comment-syntax"> (not a typedef only because it makes trouble for inweb)</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP6"></a><b>§6. </b>We now run through the enumeration, in a sequence which must exactly match
|
|
that in the table of metadata below.
|
|
</p>
|
|
|
|
<p class="commentary">Structural node types are enumerated first:
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">BASE_OF_ENUMERATED_NTS</span><span class="plain-syntax"> </span><span class="constant-syntax">0x80000000</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">INVALID_NT</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> </span><span class="constant-syntax">0x80000000</span><span class="plain-syntax"> </span><span class="comment-syntax"> No node with this node type should ever exist</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">ROOT_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> Only one such node exists: the tree root</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">INCLUSION_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> Holds a block of source material</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">HEADING_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> "Chapter VIII: Never Turn Your Back On A Shreve"</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">INCLUDE_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> "Include School Rules by Argus Filch"</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">BEGINHERE_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> "The Standard Rules begin here"</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">ENDHERE_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> "The Standard Rules end here"</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">SENTENCE_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> "The Garden is a room"</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">AMBIGUITY_NT</span><span class="plain-syntax"> </span><span class="comment-syntax"> Marks an ambiguous set of readings in the tree</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP7"></a><b>§7. The structure. </b>Finally, then, the data structure.
|
|
</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"> linked list of miscellaneous annotations</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">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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">score</span><span class="plain-syntax">; </span><span class="comment-syntax"> used to choose most likely 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_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">log_time</span><span class="plain-syntax">; </span><span class="comment-syntax"> used purely as a defensive measure when writing debugging log</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">MEMORY_MANAGEMENT</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 private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8"></a><b>§8. 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="SP9"></a><b>§9. </b>The parse tree annotations are miscellaneous, and many are needed only
|
|
at a few unusual nodes. Rather than have the structure grow large, we
|
|
store annotations in the following:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">parse_node_annotation</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">kind_of_annotation</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">annotation_integer</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="identifier-syntax">annotation_pointer</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_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_annotation</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure parse_node_annotation is private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP10"></a><b>§10. </b></p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">heading_level_ANNOT</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> </span><span class="comment-syntax"> int: for HEADING nodes, a hierarchical level, 0 (highest) to 9 (lowest)</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">language_element_ANNOT</span><span class="plain-syntax"> </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">int</span></span><span class="comment-syntax">: this node is not really a sentence, but a language definition Use</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">sentence_unparsed_ANNOT</span><span class="plain-syntax"> </span><span class="comment-syntax"> int: set if verbs haven't been sought yet here</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">suppress_heading_dependencies_ANNOT</span><span class="plain-syntax"> </span><span class="comment-syntax"> int: ignore extension dependencies on this heading node</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">implied_heading_ANNOT</span><span class="plain-syntax"> </span><span class="comment-syntax"> int: set only for the heading of implied inclusions</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">MAX_ANNOT_NUMBER</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NO_DEFINED_ANNOT_VALUES</span><span class="plain-syntax">+1)</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP11"></a><b>§11. </b>Access routines will be needed for some of these, and the following
|
|
constructs them:
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">DECLARE_ANNOTATION_FUNCTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">annotation_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">pointer_type</span><span class="plain-syntax">)</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="identifier-syntax">ParseTree::set_</span><span class="plain-syntax">##</span><span class="identifier-syntax">annotation_name</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">pointer_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">bp</span><span class="plain-syntax">);</span>
|
|
<span class="identifier-syntax">pointer_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ParseTree::get_</span><span class="plain-syntax">##</span><span class="identifier-syntax">annotation_name</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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP12"></a><b>§12. Node metadata. </b>With such a profusion of node types, we need a systematic way to organise
|
|
information about them.
|
|
</p>
|
|
|
|
<p class="commentary">The following structure is used only for a row in a table of what we
|
|
might call metadata about node types: information on where each node type
|
|
can appear, and what restrictions apply to its use. We also store textual
|
|
names for the node types here, as this is convenient for logging.
|
|
</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_tree_node_type</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">identity</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">node_type_name</span><span class="plain-syntax">; </span><span class="comment-syntax"> text of name of type, such as </span><span class="extract"><span class="extract-syntax">"INVOCATION_LIST_NT"</span></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">min_children</span><span class="plain-syntax">; </span><span class="comment-syntax"> minimum legal number of child nodes</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">max_children</span><span class="plain-syntax">; </span><span class="comment-syntax"> maximum legal number of child nodes</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">category</span><span class="plain-syntax">; </span><span class="comment-syntax"> one of the </span><span class="extract"><span class="extract-syntax">*_NCAT</span></span><span class="comment-syntax"> values below</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">node_flags</span><span class="plain-syntax">; </span><span class="comment-syntax"> bitmap of node flags</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure parse_tree_node_type is private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP13"></a><b>§13. </b>The categories are:
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">INVALID_NCAT</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">L1_NCAT</span>
|
|
<span class="definition-keyword">enum</span> <span class="constant-syntax">L2_NCAT</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP14"></a><b>§14. </b>The bitmap of node flags begins with:
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">DONT_VISIT_NFLAG</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000001</span><span class="plain-syntax"> </span><span class="comment-syntax"> not visited in traverses</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">TABBED_CONTENT_NFLAG</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000002</span><span class="plain-syntax"> </span><span class="comment-syntax"> contains tab-delimited lists</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP15"></a><b>§15. </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="identifier-syntax">trace_sentences</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP16"></a><b>§16. The metadata table. </b>Note that the sequence here must exactly match the enumeration above.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">INFTY</span><span class="plain-syntax"> </span><span class="constant-syntax">1000000000</span><span class="plain-syntax"> </span><span class="comment-syntax"> if ever a node has more than a billion children, we are in trouble anyway</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_tree_node_types</span><span class="plain-syntax">[</span><span class="identifier-syntax">NO_DEFINED_NT_VALUES</span><span class="plain-syntax">];</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::md</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">ParseTree::md</span></span>:<br/><a href="2-pt.html#SP17">§17</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax"> </span><span class="identifier-syntax">ptnt</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-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::valid_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ptnt</span><span class="plain-syntax">.</span><span class="element-syntax">identity</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"set bad metadata"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_tree_node_types</span><span class="plain-syntax">[</span><span class="identifier-syntax">ptnt</span><span class="plain-syntax">.</span><span class="element-syntax">identity</span><span class="plain-syntax"> - </span><span class="constant-syntax">BASE_OF_ENUMERATED_NTS</span><span class="plain-syntax">] = </span><span class="identifier-syntax">ptnt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP17"></a><b>§17. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::metadata_setup</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">ParseTree::metadata_setup</span></span>:<br/>Syntax Module - <a href="1-sm.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP16" class="function-link"><span class="function-syntax">ParseTree::md</span></a><span class="plain-syntax">((</span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax">) { </span><span class="constant-syntax">INVALID_NT</span><span class="plain-syntax">, </span><span class="string-syntax">"(INVALID_NT)"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">INVALID_NCAT</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-pt.html#SP16" class="function-link"><span class="function-syntax">ParseTree::md</span></a><span class="plain-syntax">((</span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax">) { </span><span class="constant-syntax">ROOT_NT</span><span class="plain-syntax">, </span><span class="string-syntax">"ROOT_NT"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L1_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">DONT_VISIT_NFLAG</span><span class="plain-syntax"> });</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP16" class="function-link"><span class="function-syntax">ParseTree::md</span></a><span class="plain-syntax">((</span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax">) { </span><span class="constant-syntax">INCLUSION_NT</span><span class="plain-syntax">, </span><span class="string-syntax">"INCLUSION_NT"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L1_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">DONT_VISIT_NFLAG</span><span class="plain-syntax"> });</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP16" class="function-link"><span class="function-syntax">ParseTree::md</span></a><span class="plain-syntax">((</span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax">) { </span><span class="constant-syntax">HEADING_NT</span><span class="plain-syntax">, </span><span class="string-syntax">"HEADING_NT"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L1_NCAT</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-pt.html#SP16" class="function-link"><span class="function-syntax">ParseTree::md</span></a><span class="plain-syntax">((</span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax">) { </span><span class="constant-syntax">INCLUDE_NT</span><span class="plain-syntax">, </span><span class="string-syntax">"INCLUDE_NT"</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">L2_NCAT</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-pt.html#SP16" class="function-link"><span class="function-syntax">ParseTree::md</span></a><span class="plain-syntax">((</span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax">) { </span><span class="constant-syntax">BEGINHERE_NT</span><span class="plain-syntax">, </span><span class="string-syntax">"BEGINHERE_NT"</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">L2_NCAT</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-pt.html#SP16" class="function-link"><span class="function-syntax">ParseTree::md</span></a><span class="plain-syntax">((</span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax">) { </span><span class="constant-syntax">ENDHERE_NT</span><span class="plain-syntax">, </span><span class="string-syntax">"ENDHERE_NT"</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">L2_NCAT</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-pt.html#SP16" class="function-link"><span class="function-syntax">ParseTree::md</span></a><span class="plain-syntax">((</span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax">) { </span><span class="constant-syntax">SENTENCE_NT</span><span class="plain-syntax">, </span><span class="string-syntax">"SENTENCE_NT"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L2_NCAT</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-pt.html#SP16" class="function-link"><span class="function-syntax">ParseTree::md</span></a><span class="plain-syntax">((</span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax">) { </span><span class="constant-syntax">AMBIGUITY_NT</span><span class="plain-syntax">, </span><span class="string-syntax">"AMBIGUITY_NT"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="constant-syntax">L1_NCAT</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">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNKNOWN_NT</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP16" class="function-link"><span class="function-syntax">ParseTree::md</span></a><span class="plain-syntax">((</span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax">) { </span><span class="identifier-syntax">UNKNOWN_NT</span><span class="plain-syntax">, </span><span class="string-syntax">"UNKNOWN_NT"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">INFTY</span><span class="plain-syntax">, </span><span class="identifier-syntax">L3_NCAT</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">endif</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PARSE_TREE_METADATA_SETUP</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PARSE_TREE_METADATA_SETUP</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP18"></a><b>§18. </b>We can only retrieve metadata on enumerated node types, not on meaning
|
|
codes such as <span class="extract"><span class="extract-syntax">RULE_MC</span></span>, for which the following will return <span class="extract"><span class="extract-syntax">NULL</span></span>.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax"> *</span><span class="function-syntax">ParseTree::node_metadata</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">ParseTree::node_metadata</span></span>:<br/><a href="2-pt.html#SP19">§19</a>, <a href="2-pt.html#SP20">§20</a>, <a href="2-pt.html#SP55">§55</a>, <a href="2-pt.html#SP55_3">§55.3</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><span class="identifier-syntax">t</span><span class="plain-syntax"> >= </span><span class="constant-syntax">BASE_OF_ENUMERATED_NTS</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">t</span><span class="plain-syntax"> < </span><span class="constant-syntax">BASE_OF_ENUMERATED_NTS</span><span class="plain-syntax">+</span><span class="identifier-syntax">NO_DEFINED_NT_VALUES</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> = &(</span><span class="identifier-syntax">parse_tree_node_types</span><span class="plain-syntax">[</span><span class="identifier-syntax">t</span><span class="plain-syntax"> - </span><span class="constant-syntax">BASE_OF_ENUMERATED_NTS</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">metadata</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-></span><span class="element-syntax">identity</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">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"unable to locate node type %08x\n"</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">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"node type metadata lookup incorrect"</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">metadata</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP19"></a><b>§19. </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">ParseTree::valid_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">ParseTree::valid_type</span></span>:<br/><a href="2-pt.html#SP16">§16</a>, <a href="2-pt.html#SP53">§53</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><span class="identifier-syntax">t</span><span class="plain-syntax"> >= </span><span class="constant-syntax">BASE_OF_ENUMERATED_NTS</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">t</span><span class="plain-syntax"> < </span><span class="constant-syntax">BASE_OF_ENUMERATED_NTS</span><span class="plain-syntax">+</span><span class="identifier-syntax">NO_DEFINED_NT_VALUES</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::cat</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">ParseTree::cat</span></span>:<br/><a href="2-pt.html#SP58">§58</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_tree_node_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> = </span><a href="2-pt.html#SP18" class="function-link"><span class="function-syntax">ParseTree::node_metadata</span></a><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">metadata</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-></span><span class="element-syntax">category</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">INVALID_NCAT</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">ParseTree::top_level</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">ParseTree::top_level</span></span>:<br/><a href="2-pt.html#SP50">§50</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_tree_node_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> = </span><a href="2-pt.html#SP18" class="function-link"><span class="function-syntax">ParseTree::node_metadata</span></a><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">metadata</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-></span><span class="identifier-syntax">category</span><span class="plain-syntax"> == </span><span class="constant-syntax">L1_NCAT</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::visitable</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">ParseTree::visitable</span></span>:<br/><a href="2-pt.html#SP50">§50</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-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::test_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>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::test_flag</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">ParseTree::test_flag</span></span>:<br/>Sentences - <a href="2-snt.html#SP5_2">§5.2</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> = </span><a href="2-pt.html#SP18" class="function-link"><span class="function-syntax">ParseTree::node_metadata</span></a><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">metadata</span><span class="plain-syntax">) && ((</span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-></span><span class="element-syntax">node_flags</span><span class="plain-syntax">) & </span><span class="identifier-syntax">f</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="SP20"></a><b>§20. Logging node types. </b>And also making node names available to the machinery for producing internal
|
|
errors when incorrect node types are encountered, though we hope this will
|
|
never be used.
|
|
</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">ParseTree::log_type</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">ParseTree::log_type</span></span>:<br/><a href="2-pt.html#SP47">§47</a><br/>Syntax Module - <a href="1-sm.html#SP3_5">§3.5</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">it</span><span class="plain-syntax">) {</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="constant-syntax">node_type_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">it</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> = </span><a href="2-pt.html#SP18" class="function-link"><span class="function-syntax">ParseTree::node_metadata</span></a><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">metadata</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">metadata</span><span class="plain-syntax">-></span><span class="element-syntax">node_type_name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">UseExcerptMeanings::log_meaning_code</span><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="plain-syntax"> #</span><span class="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"?%08x_NT"</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="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="function-syntax">ParseTree::get_type_name</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">parse_tree_node_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> = </span><a href="2-pt.html#SP18" class="function-link"><span class="function-syntax">ParseTree::node_metadata</span></a><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">metadata</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="string-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">metadata</span><span class="plain-syntax">-></span><span class="element-syntax">node_type_name</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP21"></a><b>§21. 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">ParseTree::new</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">ParseTree::new</span></span>:<br/><a href="2-pt.html#SP1">§1</a>, <a href="2-pt.html#SP22">§22</a>, <a href="2-pt.html#SP33">§33</a>, <a href="2-pt.html#SP35">§35</a><br/>Sentences - <a href="2-snt.html#SP6_1">§6.1</a>, <a href="2-snt.html#SP6_6">§6.6</a>, <a href="2-snt.html#SP6_9_4">§6.9.4</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-pt.html#SP23" class="function-link"><span class="function-syntax">ParseTree::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><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</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">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">log_time</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-pt.html#SP26" class="function-link"><span class="function-syntax">ParseTree::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="SP22"></a><b>§22. </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">ParseTree::new_with_words</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">ParseTree::new_with_words</span></span>:<br/><a href="2-pt.html#SP60">§60</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-pt.html#SP21" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP23" class="function-link"><span class="function-syntax">ParseTree::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="SP23"></a><b>§23. </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">ParseTree::get_text</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">ParseTree::get_text</span></span>:<br/><a href="2-pt.html#SP38">§38</a>, <a href="2-pt.html#SP39">§39</a>, <a href="2-pt.html#SP46">§46</a>, <a href="2-pt.html#SP47">§47</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">ParseTree::set_text</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">ParseTree::set_text</span></span>:<br/><a href="2-pt.html#SP21">§21</a>, <a href="2-pt.html#SP22">§22</a><br/>Sentences - <a href="2-snt.html#SP6_1">§6.1</a>, <a href="2-snt.html#SP6_6">§6.6</a>, <a href="2-snt.html#SP6_9_4">§6.9.4</a>, <a href="2-snt.html#SP6_9_7">§6.9.7</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="SP24"></a><b>§24. 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">ParseTree::get_type</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">ParseTree::get_type</span></span>:<br/><a href="2-pt.html#SP44">§44</a>, <a href="2-pt.html#SP44_1">§44.1</a>, <a href="2-pt.html#SP53">§53</a>, <a href="2-pt.html#SP55">§55</a>, <a href="2-pt.html#SP55_3">§55.3</a>, <a href="2-pt.html#SP60">§60</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">ParseTree::is</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">ParseTree::is</span></span>:<br/><a href="2-pt.html#SP50">§50</a>, <a href="2-pt.html#SP55_1_1">§55.1.1</a>, <a href="2-pt.html#SP60">§60</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="SP25"></a><b>§25. </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">ParseTree::set_type</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">ParseTree::set_type</span></span>:<br/>Sentences - <a href="2-snt.html#SP6_9">§6.9</a>, <a href="2-snt.html#SP6_9_5">§6.9.5</a>, <a href="2-snt.html#SP6_9_6">§6.9.6</a>, <a href="2-snt.html#SP6_9_7">§6.9.7</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><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">annotations</span><span class="plain-syntax">) &&</span>
|
|
<span class="plain-syntax"> (!(</span><a href="2-pt.html#SP59" class="function-link"><span class="function-syntax">ParseTree::annotation_allowed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax">-></span><span class="element-syntax">kind_of_annotation</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">annotations</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</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">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pna</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</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">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</span><span class="plain-syntax">) &&</span>
|
|
<span class="plain-syntax"> (!(</span><a href="2-pt.html#SP59" class="function-link"><span class="function-syntax">ParseTree::annotation_allowed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</span><span class="plain-syntax">-></span><span class="element-syntax">kind_of_annotation</span><span class="plain-syntax">))))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</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">ParseTree::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="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP26"></a><b>§26. </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">ParseTree::get_score</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">ParseTree::get_score</span></span>:<br/><a href="2-pt.html#SP46">§46</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">ParseTree::set_score</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">ParseTree::set_score</span></span>:<br/><a href="2-pt.html#SP21">§21</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="SP27"></a><b>§27. </b>Beyond that, we have to attach something. A blank annotation is like a
|
|
blank luggage ticket, waiting to be filled out and attached to some suitcase:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="function-syntax">ParseTree::pna_new</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">ParseTree::pna_new</span></span>:<br/><a href="2-pt.html#SP30">§30</a>, <a href="2-pt.html#SP31">§31</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">koa</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pna</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">kind_of_annotation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">koa</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">annotation_integer</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">pna</span><span class="plain-syntax">-></span><span class="element-syntax">annotation_pointer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL_GENERAL_POINTER</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pna</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP28"></a><b>§28. </b>Annotations are identified by an enumerated range of constants (KOA here
|
|
stands for "kind of annotation"). Each node is permitted an arbitrary
|
|
selection of these, storing them as a linked list: it will always be short
|
|
(worst case about 5), so there is no need for a more efficient algorithm
|
|
to search this list.
|
|
</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">ParseTree::has_annotation</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">ParseTree::has_annotation</span></span>:<br/><a href="2-pt.html#SP32">§32</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">koa</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pna</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="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">PN</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</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">pna</span><span class="plain-syntax">-></span><span class="element-syntax">kind_of_annotation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">koa</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="SP29"></a><b>§29. </b>Reading annotations is similar. We need two variant forms: one for reading
|
|
integer-valued annotations (which is most of them, as it happens) and the
|
|
other for reading pointers to structures.
|
|
</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">ParseTree::int_annotation</span><button class="popup" onclick="togglePopup('usagePopup22')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup22">Usage of <span class="code-font"><span class="function-syntax">ParseTree::int_annotation</span></span>:<br/><a href="2-pt.html#SP44_1">§44.1</a>, <a href="2-pt.html#SP47">§47</a>, <a href="2-pt.html#SP50">§50</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">koa</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pna</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="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">PN</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</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">pna</span><span class="plain-syntax">-></span><span class="element-syntax">kind_of_annotation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">koa</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">pna</span><span class="plain-syntax">-></span><span class="element-syntax">annotation_integer</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</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">general_pointer</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::pn_pointer_annotation</span><button class="popup" onclick="togglePopup('usagePopup23')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup23">Usage of <span class="code-font"><span class="function-syntax">ParseTree::pn_pointer_annotation</span></span>:<br/><a href="2-pt.html#SP32">§32</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">koa</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pna</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="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">PN</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</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">pna</span><span class="plain-syntax">-></span><span class="element-syntax">kind_of_annotation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">koa</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">pna</span><span class="plain-syntax">-></span><span class="element-syntax">annotation_pointer</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL_GENERAL_POINTER</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP30"></a><b>§30. </b>Integer-valued annotations are set with the following routine. Note that
|
|
any second or subsequent annotation with the same KOA as an existing one
|
|
overwrites it.
|
|
</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">ParseTree::annotate_int</span><button class="popup" onclick="togglePopup('usagePopup24')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup24">Usage of <span class="code-font"><span class="function-syntax">ParseTree::annotate_int</span></span>:<br/>Sentences - <a href="2-snt.html#SP6_1">§6.1</a>, <a href="2-snt.html#SP6_6">§6.6</a>, <a href="2-snt.html#SP6_9">§6.9</a>, <a href="2-snt.html#SP6_9_4">§6.9.4</a>, <a href="2-snt.html#SP6_9_5">§6.9.5</a>, <a href="2-snt.html#SP6_9_8">§6.9.8</a>, <a href="2-snt.html#SP6_9_9">§6.9.9</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">koa</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">newpna</span><span class="plain-syntax">, *</span><span class="identifier-syntax">pna</span><span class="plain-syntax">, *</span><span class="identifier-syntax">final</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">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">"annotated null PN"</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">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">PN</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</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">pna</span><span class="plain-syntax">-></span><span class="element-syntax">kind_of_annotation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">koa</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> an annotation with this KOA exists already: overwrite it</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">annotation_integer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">v</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">final</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pna</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> no annotation with this KOA exists: create a new one and add to end of node's list</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">newpna</span><span class="plain-syntax"> = </span><a href="2-pt.html#SP27" class="function-link"><span class="function-syntax">ParseTree::pna_new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">koa</span><span class="plain-syntax">); </span><span class="identifier-syntax">newpna</span><span class="plain-syntax">-></span><span class="element-syntax">annotation_integer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">v</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">final</span><span class="plain-syntax">) </span><span class="identifier-syntax">final</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">newpna</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">PN</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax"> = </span><span class="identifier-syntax">newpna</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP31"></a><b>§31. </b>Again, almost identical code handles the case of pointer-valued annotations:
|
|
</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">ParseTree::pn_annotate_pointer</span><button class="popup" onclick="togglePopup('usagePopup25')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup25">Usage of <span class="code-font"><span class="function-syntax">ParseTree::pn_annotate_pointer</span></span>:<br/><a href="2-pt.html#SP32">§32</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">koa</span><span class="plain-syntax">, </span><span class="identifier-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="identifier-syntax">data</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">"annotated null PN"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">newpna</span><span class="plain-syntax">, *</span><span class="identifier-syntax">pna</span><span class="plain-syntax">, *</span><span class="identifier-syntax">final</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">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">PN</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</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">pna</span><span class="plain-syntax">-></span><span class="element-syntax">kind_of_annotation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">koa</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> an annotation with this KOA exists already: overwrite it</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">annotation_pointer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">data</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">final</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pna</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> no annotation with this KOA exists: create a new one and add to end of node's list</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">newpna</span><span class="plain-syntax"> = </span><a href="2-pt.html#SP27" class="function-link"><span class="function-syntax">ParseTree::pna_new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">koa</span><span class="plain-syntax">); </span><span class="identifier-syntax">newpna</span><span class="plain-syntax">-></span><span class="element-syntax">annotation_pointer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">data</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">final</span><span class="plain-syntax">) </span><span class="identifier-syntax">final</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">newpna</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">PN</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax"> = </span><span class="identifier-syntax">newpna</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP32"></a><b>§32. </b>It turns out to be convenient to access annotations with standard-form
|
|
get and set functions, for pointers, to avoid difficulties with null
|
|
pointers (which would throw run-time errors as being invalid if the store
|
|
and retrieve routines were allowed to work on them). It's also less verbose.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">MAKE_ANNOTATION_FUNCTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">annotation_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">pointer_type</span><span class="plain-syntax">)</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="identifier-syntax">ParseTree::set_</span><span class="plain-syntax">##</span><span class="identifier-syntax">annotation_name</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">pointer_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">bp</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP31" class="function-link"><span class="function-syntax">ParseTree::pn_annotate_pointer</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">annotation_name</span><span class="plain-syntax">##</span><span class="identifier-syntax">_ANNOT</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">STORE_POINTER_</span><span class="plain-syntax">##</span><span class="identifier-syntax">pointer_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">bp</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax">}</span>
|
|
<span class="identifier-syntax">pointer_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ParseTree::get_</span><span class="plain-syntax">##</span><span class="identifier-syntax">annotation_name</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="identifier-syntax">pointer_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</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><a href="2-pt.html#SP28" class="function-link"><span class="function-syntax">ParseTree::has_annotation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">annotation_name</span><span class="plain-syntax">##</span><span class="identifier-syntax">_ANNOT</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_</span><span class="plain-syntax">##</span><span class="identifier-syntax">pointer_type</span><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP29" class="function-link"><span class="function-syntax">ParseTree::pn_pointer_annotation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">annotation_name</span><span class="plain-syntax">##</span><span class="identifier-syntax">_ANNOT</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP33"></a><b>§33. 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">ParseTree::copy</span><button class="popup" onclick="togglePopup('usagePopup26')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup26">Usage of <span class="code-font"><span class="function-syntax">ParseTree::copy</span></span>:<br/><a href="2-pt.html#SP34">§34</a>, <a href="2-pt.html#SP35">§35</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><span class="identifier-syntax">to</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</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">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pna</span><span class="plain-syntax">, *</span><span class="identifier-syntax">latest</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">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">from</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pna_copy</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> *</span><span class="identifier-syntax">pna_copy</span><span class="plain-syntax"> = *</span><span class="identifier-syntax">pna</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">PARSE_TREE_COPIER</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PARSE_TREE_COPIER</span><span class="plain-syntax">(</span><span class="identifier-syntax">pna_copy</span><span class="plain-syntax">, </span><span class="identifier-syntax">pna</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">pna_copy</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</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">to</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</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="element-syntax">annotations</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pna_copy</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">latest</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pna_copy</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">latest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pna_copy</span><span class="plain-syntax">;</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">ParseTree::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-pt.html#SP21" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP33" class="function-link"><span class="function-syntax">ParseTree::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="SP34"></a><b>§34. </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">ParseTree::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-pt.html#SP33" class="function-link"><span class="function-syntax">ParseTree::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="SP35"></a><b>§35. </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">ParseTree::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-pt.html#SP33" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP21" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP35" class="function-link"><span class="function-syntax">ParseTree::copy_subtree</span></a><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="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-pt.html#SP21" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP35" class="function-link"><span class="function-syntax">ParseTree::copy_subtree</span></a><span class="plain-syntax">(</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="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-pt.html#SP21" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP35" class="function-link"><span class="function-syntax">ParseTree::copy_subtree</span></a><span class="plain-syntax">(</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="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="SP36"></a><b>§36. 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">ParseTree::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="SP37"></a><b>§37. 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">ParseTree::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-pt.html#SP37" class="function-link"><span class="function-syntax">ParseTree::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="SP38"></a><b>§38. 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">ParseTree::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-pt.html#SP23" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP38" class="function-link"><span class="function-syntax">ParseTree::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="SP39"></a><b>§39. </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">ParseTree::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-pt.html#SP23" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP23" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP39" class="function-link"><span class="function-syntax">ParseTree::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="SP40"></a><b>§40. </b>Every node in the tree is indirectly a child of the root node. Such trees
|
|
tends to be very wide: since each sentence in the original source text is a
|
|
different child of the root, the root may have 5000 or so children, though
|
|
the maximum depth of the tree might be only 10.
|
|
</p>
|
|
|
|
<p class="commentary">That means that perpetually scanning through them in order to add another one
|
|
on the end is inefficient: so we cache the "last sentence" in the tree,
|
|
meaning, the youngest child of root. (But we must only do this when we are not
|
|
also performing surgery on the tree at the same time, which is why it is not
|
|
always allowed.)
|
|
</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">youngest_child_of_root</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> youngest child of tree root</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="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::enable_last_sentence_cacheing</span><button class="popup" onclick="togglePopup('usagePopup27')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup27">Usage of <span class="code-font"><span class="function-syntax">ParseTree::enable_last_sentence_cacheing</span></span>:<br/>Sentences - <a href="2-snt.html#SP5">§5</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="identifier-syntax">youngest_child_of_root</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">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">ParseTree::disable_last_sentence_cacheing</span><button class="popup" onclick="togglePopup('usagePopup28')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup28">Usage of <span class="code-font"><span class="function-syntax">ParseTree::disable_last_sentence_cacheing</span></span>:<br/>Sentences - <a href="2-snt.html#SP5">§5</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="identifier-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="SP41"></a><b>§41. </b>Now the metaphors get mixed. The routine below is called <span class="extract"><span class="extract-syntax">ParseTree::graft</span></span>
|
|
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. This is fairly apt for
|
|
the process of joining one subtree onto a node of another. But since
|
|
gardening lacks words to describe branches as being eldest or youngest,
|
|
and so on, for the actual body of the routine we talk about family trees
|
|
instead.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">ParseTree::graft</span></span> returns the node for which <span class="extract"><span class="extract-syntax">newborn</span></span> is the immediate sibling,
|
|
that is, it returns the previously youngest child of the <span class="extract"><span class="extract-syntax">parent</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">ParseTree::graft</span><button class="popup" onclick="togglePopup('usagePopup29')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup29">Usage of <span class="code-font"><span class="function-syntax">ParseTree::graft</span></span>:<br/><a href="2-pt.html#SP44">§44</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">newborn</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parent</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">newborn</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">"newborn is null in tree ParseTree::graft"</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">parent</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">"parent is null in tree ParseTree::graft"</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">parent</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">parent</span><span class="plain-syntax">-></span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">newborn</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">parent</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">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">youngest_child_of_root</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">youngest_child_of_root</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">newborn</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">youngest_child_of_root</span><span class="plain-syntax"> = </span><span class="identifier-syntax">newborn</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">youngest_child_of_root</span><span class="plain-syntax"> = </span><span class="identifier-syntax">newborn</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> find youngest child of attach node...</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">parent</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">newborn</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="SP42"></a><b>§42. </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">ParseTree::graft_alternative</span><span class="plain-syntax">(</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">newborn</span><span class="plain-syntax">, </span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parent</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">newborn</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">"newborn is null in tree ParseTree::graft_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">parent</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">"parent is null in tree ParseTree::graft_alternative"</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">parent</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">parent</span><span class="plain-syntax">-></span><span class="element-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">newborn</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 attach node...</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">parent</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">newborn</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="SP43"></a><b>§43. </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="SP44"></a><b>§44. </b>Sentences are attached as so: at the one-off point if set, or at the
|
|
relevant stacked position.
|
|
</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">ParseTree::insert_sentence</span><button class="popup" onclick="togglePopup('usagePopup30')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup30">Usage of <span class="code-font"><span class="function-syntax">ParseTree::insert_sentence</span></span>:<br/>Sentences - <a href="2-snt.html#SP6_1">§6.1</a>, <a href="2-snt.html#SP6_6">§6.6</a>, <a href="2-snt.html#SP6_9_4">§6.9.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">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">one_off_attachment_point</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">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">T</span><span class="plain-syntax">-></span><span class="element-syntax">one_off_attachment_point</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">T</span><span class="plain-syntax">-></span><span class="identifier-syntax">one_off_attachment_point</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new</span><span class="plain-syntax">-></span><span class="element-syntax">next</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="identifier-syntax">one_off_attachment_point</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">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-></span><span class="element-syntax">attachment_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-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP44_1" class="named-paragraph-link"><span class="named-paragraph">Adjust attachment point for a heading</span><span class="named-paragraph-number">44.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">attachment_stack_parent</span><span class="plain-syntax">[</span><span class="identifier-syntax">T</span><span class="plain-syntax">-></span><span class="element-syntax">attachment_sp</span><span class="plain-syntax">-1];</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP41" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP2" class="function-link"><span class="function-syntax">ParseTree::push_attachment_point</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>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP44_1"></a><b>§44.1. </b>When what's attached is a heading node, that changes the stack, of course:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Adjust attachment point for a heading</span><span class="named-paragraph-number">44.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-pt.html#SP29" class="function-link"><span class="function-syntax">ParseTree::int_annotation</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">attachment_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">attachment_stack_parent</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-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP29" class="function-link"><span class="function-syntax">ParseTree::int_annotation</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">attachment_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-pt.html#SP44">§44</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP45"></a><b>§45. 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">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">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::log_tree</span><button class="popup" onclick="togglePopup('usagePopup31')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup31">Usage of <span class="code-font"><span class="function-syntax">ParseTree::log_tree</span></span>:<br/><a href="2-pt.html#SP49">§49</a><br/>Syntax Module - <a href="1-sm.html#SP3_5">§3.5</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-pt.html#SP46" class="function-link"><span class="function-syntax">ParseTree::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">pn_log_token</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">ParseTree::log_subtree</span><button class="popup" onclick="togglePopup('usagePopup32')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup32">Usage of <span class="code-font"><span class="function-syntax">ParseTree::log_subtree</span></span>:<br/>Syntax Module - <a href="1-sm.html#SP3_5">§3.5</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-pt.html#SP46" class="function-link"><span class="function-syntax">ParseTree::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">pn_log_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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP46"></a><b>§46. </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">ParseTree::log_subtree_recursively</span><button class="popup" onclick="togglePopup('usagePopup33')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup33">Usage of <span class="code-font"><span class="function-syntax">ParseTree::log_subtree_recursively</span></span>:<br/><a href="2-pt.html#SP45">§45</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="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">ltime</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">log_time</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ltime</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-pt.html#SP23" class="function-link"><span class="function-syntax">ParseTree::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">log_time</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ltime</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pt.html#SP46_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">46.1</span></a></span><span class="character-syntax">;</span>
|
|
|
|
<span class="character-syntax"> if (pn == NULL) { WRITE("<null-parse-node>\n"); return; }</span>
|
|
<span class="character-syntax"> if (of > 1) {</span>
|
|
<span class="character-syntax"> WRITE("[%d/%d] ", num, of);</span>
|
|
<span class="character-syntax"> if (ParseTree::get_score(pn) != 0) WRITE("(score %d) ", ParseTree::get_score(pn));</span>
|
|
<span class="character-syntax"> }</span>
|
|
<span class="character-syntax"> WRITE("$P\n", pn);</span>
|
|
<span class="character-syntax"> if (pn->down) {</span>
|
|
<span class="character-syntax"> LOG_INDENT;</span>
|
|
<span class="character-syntax"> ParseTree::log_subtree_recursively(OUT, pn->down, 0, 0, gen+1, ltime);</span>
|
|
<span class="character-syntax"> LOG_OUTDENT;</span>
|
|
<span class="character-syntax"> }</span>
|
|
<span class="character-syntax"> if (pn->next_alternative) ParseTree::log_subtree_recursively(OUT, pn->next_alternative, num+1, of, gen+1, ltime);</span>
|
|
|
|
<span class="character-syntax"> pn = pn->next; num = 0; of = 0; gen++;</span>
|
|
<span class="character-syntax"> }</span>
|
|
<span class="character-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP46_1"></a><b>§46.1. </b>When the first alternative is called, <span class="extract"><span class="extract-syntax">ParseTree::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">46.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-pt.html#SP46">§46</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP47"></a><b>§47. </b>All of those routines make use of the following, which actually performs
|
|
the log of a parse node. Note that this always produces exactly one line of
|
|
text in the debugging log.
|
|
</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">ParseTree::log_node</span><button class="popup" onclick="togglePopup('usagePopup34')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup34">Usage of <span class="code-font"><span class="function-syntax">ParseTree::log_node</span></span>:<br/>Syntax Module - <a href="1-sm.html#SP3_5">§3.5</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>\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="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PARSE_TREE_LOGGER</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PARSE_TREE_LOGGER</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="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP20" class="function-link"><span class="function-syntax">ParseTree::log_type</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="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">Wordings::nonempty</span><span class="plain-syntax">(</span><a href="2-pt.html#SP23" class="function-link"><span class="function-syntax">ParseTree::get_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">))) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"'%W'"</span><span class="plain-syntax">, </span><a href="2-pt.html#SP23" class="function-link"><span class="function-syntax">ParseTree::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">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">LINGUISTICS_MODULE</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Diagrams::log_node</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="identifier-syntax">endif</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</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">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">HEADING_NT:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" (level %d)"</span><span class="plain-syntax">, </span><a href="2-pt.html#SP29" class="function-link"><span class="function-syntax">ParseTree::int_annotation</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="reserved-syntax">break</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="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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP48"></a><b>§48. </b>This is occasionally useful:
|
|
</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">ParseTree::log_with_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="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Diagnosis $P"</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">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pna</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</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">"-%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">kind_of_annotation</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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP49"></a><b>§49. </b>Inform also has a mechanism for dumping the entire parse tree to a file,
|
|
really just for testing purposes:
|
|
</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">ParseTree::write_to_file</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">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_tree_file</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">STREAM_OPEN_TO_FILE</span><span class="plain-syntax">(&</span><span class="identifier-syntax">parse_tree_file</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">ISO_ENC</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">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can't open file to write parse tree"</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">save_DL</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DL</span><span class="plain-syntax"> = &</span><span class="identifier-syntax">parse_tree_file</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Streams::enable_debugging</span><span class="plain-syntax">(</span><span class="identifier-syntax">DL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP45" class="function-link"><span class="function-syntax">ParseTree::log_tree</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">DL</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">DL</span><span class="plain-syntax"> = </span><span class="identifier-syntax">save_DL</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">STREAM_CLOSE</span><span class="plain-syntax">(&</span><span class="identifier-syntax">parse_tree_file</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP50"></a><b>§50. General traversals. </b>It's convenient to have a general system for traversing the tree, visiting
|
|
each node in the connected component of the tree root. Unlike the logging
|
|
routine above, these all assume that the tree is well-formed.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="plain-syntax">@</span><span class="reserved-syntax">default</span><span class="plain-syntax"> </span><span class="constant-syntax">PARSE_TREE_TRAVERSE_TYPE</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_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="plain-syntax">}</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::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-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP51" class="function-link"><span class="function-syntax">ParseTree::sentence_node</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="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">ParseTree::traverse_dfirst</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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_dfirst_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="plain-syntax">}</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::traverse_dfirst_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><a href="2-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_dfirst_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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP51" class="function-link"><span class="function-syntax">ParseTree::sentence_node</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="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">ParseTree::traverse_wfirst</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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_wfirst_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="plain-syntax">}</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::traverse_wfirst_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-pt.html#SP51" class="function-link"><span class="function-syntax">ParseTree::sentence_node</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><a href="2-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_wfirst_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="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="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">ParseTree::traverse_with_stream</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="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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_from_with_stream</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">ParseTree::traverse_from_with_stream</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="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-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_from_with_stream</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP51" class="function-link"><span class="function-syntax">ParseTree::sentence_node</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="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">ParseTree::traverse_int</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="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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_from_int</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">ParseTree::traverse_from_int</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="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-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_from_int</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP51" class="function-link"><span class="function-syntax">ParseTree::sentence_node</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="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">ParseTree::traverse_int_int</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="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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_from_int_int</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">ParseTree::traverse_from_int_int</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="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-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_from_int_int</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP51" class="function-link"><span class="function-syntax">ParseTree::sentence_node</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="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">ParseTree::traverse_ppn</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="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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_from_ppn</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">ParseTree::traverse_from_ppn</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="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-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_from_ppn</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP51" class="function-link"><span class="function-syntax">ParseTree::sentence_node</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="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">ParseTree::traverse_ppni</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_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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_from_ppni</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">ParseTree::traverse_from_ppni</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="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">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-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::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><a href="2-pt.html#SP29" class="function-link"><span class="function-syntax">ParseTree::int_annotation</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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_from_ppni</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP51" class="function-link"><span class="function-syntax">ParseTree::sentence_node</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="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">ParseTree::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="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">PARSE_TREE_TRAVERSE_TYPE</span><span class="plain-syntax"> **), </span><span class="constant-syntax">PARSE_TREE_TRAVERSE_TYPE</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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::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">ParseTree::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="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">PARSE_TREE_TRAVERSE_TYPE</span><span class="plain-syntax"> **), </span><span class="constant-syntax">PARSE_TREE_TRAVERSE_TYPE</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-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP51" class="function-link"><span class="function-syntax">ParseTree::sentence_node</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="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>
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::traverse_ppn_nocs</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">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="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-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_from_ppn_nocs</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">ParseTree::traverse_from_ppn_nocs</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">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="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-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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="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">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">res</span><span class="plain-syntax"> = </span><a href="2-pt.html#SP50" class="function-link"><span class="function-syntax">ParseTree::traverse_from_ppn_nocs</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">res</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="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="SP51"></a><b>§51. </b>This provides a way for users of the module to indicate what's a sentence:
|
|
</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">ParseTree::sentence_node</span><button class="popup" onclick="togglePopup('usagePopup35')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup35">Usage of <span class="code-font"><span class="function-syntax">ParseTree::sentence_node</span></span>:<br/><a href="2-pt.html#SP50">§50</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="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">SENTENCE_NODE</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">SENTENCE_NODE</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="identifier-syntax">ifndef</span><span class="plain-syntax"> </span><span class="identifier-syntax">SENTENCE_NODE</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="identifier-syntax">endif</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP52"></a><b>§52. Verify integrity. </b>The first duty of a tree is to contain no loops, and the following checks
|
|
that (rejecting even undirected loops). In addition, it checks that each
|
|
node has an enumerated node type, rather than a meaning code.
|
|
</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">tree_stats_size</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">tree_stats_depth</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">tree_stats_width</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::verify_integrity</span><button class="popup" onclick="togglePopup('usagePopup36')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup36">Usage of <span class="code-font"><span class="function-syntax">ParseTree::verify_integrity</span></span>:<br/><a href="2-pt.html#SP54">§54</a></span></button><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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">worth_logging</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tree_stats_size</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">tree_stats_depth</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">tree_stats_width</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP53" class="function-link"><span class="function-syntax">ParseTree::verify_tree_integrity_recursively</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="element-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="string-syntax">"down"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, ++</span><span class="identifier-syntax">pn_log_token</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">worth_logging</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">VERIFICATIONS</span><span class="plain-syntax">, </span><span class="string-syntax">"[Initial parse tree has %d nodes, width %d and depth %d.]\n"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tree_stats_size</span><span class="plain-syntax">, </span><span class="identifier-syntax">tree_stats_width</span><span class="plain-syntax">, </span><span class="identifier-syntax">tree_stats_depth</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP53"></a><b>§53. </b>The verification traverse is a very cautious manoeuvre: we step through
|
|
the tree, testing each branch with our outstretched foot in case it might
|
|
be illusory or broken. At the first sign of trouble we panic.
|
|
</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">ParseTree::verify_tree_integrity_recursively</span><button class="popup" onclick="togglePopup('usagePopup37')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup37">Usage of <span class="code-font"><span class="function-syntax">ParseTree::verify_tree_integrity_recursively</span></span>:<br/><a href="2-pt.html#SP52">§52</a></span></button><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">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">way</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ltime</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">width</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pointer_sized_int</span><span class="plain-syntax"> </span><span class="identifier-syntax">probably_an_address</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">pointer_sized_int</span><span class="plain-syntax">) </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax">++; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">depth</span><span class="plain-syntax"> > </span><span class="identifier-syntax">tree_stats_depth</span><span class="plain-syntax">) </span><span class="identifier-syntax">tree_stats_depth</span><span class="plain-syntax"> = </span><span class="identifier-syntax">depth</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">width</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</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">width</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">probably_an_address</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">probably_an_address</span><span class="plain-syntax"> == -1)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Link %s broken from:\n$P"</span><span class="plain-syntax">, </span><span class="identifier-syntax">way</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">Errors::set_internal_handler</span><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Link broken in parse tree"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="element-syntax">log_time</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ltime</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">"Cycle found in parse tree, found %s from:\n$P"</span><span class="plain-syntax">, </span><span class="identifier-syntax">way</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">Errors::set_internal_handler</span><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Cycle found in parse tree"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="identifier-syntax">log_time</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ltime</span><span class="plain-syntax">;</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><a href="2-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::get_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::valid_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">)) </span><span class="identifier-syntax">tree_stats_size</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Invalid node type (%08x) found %s from:\n$P"</span><span class="plain-syntax">, (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="identifier-syntax">way</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">Errors::set_internal_handler</span><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Link broken in parse tree"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="element-syntax">next_alternative</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP53" class="function-link"><span class="function-syntax">ParseTree::verify_tree_integrity_recursively</span></a><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><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="string-syntax">"alt"</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">, </span><span class="identifier-syntax">ltime</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="element-syntax">down</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP53" class="function-link"><span class="function-syntax">ParseTree::verify_tree_integrity_recursively</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="element-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="string-syntax">"down"</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">, </span><span class="identifier-syntax">ltime</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">width</span><span class="plain-syntax"> > </span><span class="identifier-syntax">tree_stats_width</span><span class="plain-syntax">) </span><span class="identifier-syntax">tree_stats_width</span><span class="plain-syntax"> = </span><span class="identifier-syntax">width</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP54"></a><b>§54. Verify structure. </b>The parse tree is a complicated structure, arbitrarily wide and deep, and
|
|
containing many different node types, each subject to its own rules of usage.
|
|
(For instance, a <span class="extract"><span class="extract-syntax">SENTENCE_NT</span></span> node cannot legally be beneath a
|
|
<span class="extract"><span class="extract-syntax">PROPER_NOUN_NT</span></span> one.) This is both good and bad: bad because complexity is
|
|
always the enemy of program correctness, good because it gives us an
|
|
independent opportunity to test a great deal of what earlier code has done.
|
|
If, given every test case, we always construct a well-formed tree, we must be
|
|
doing something right.
|
|
</p>
|
|
|
|
<p class="commentary">The collection of rules like this which the tree must satisfy is called its
|
|
"invariant", and is expressed by the code below. Note that this is
|
|
verification, not an attempt to correct matters. If any test fails, Inform
|
|
will stop with an internal error. (If there are multiple failures, we
|
|
itemise them to the debugging log, and only produce a single internal error
|
|
at the end.)
|
|
</p>
|
|
|
|
<p class="commentary">We protect ourselves by first checking that the tree is intact as a
|
|
structure: once we know the tree is safe to climb over, we can wander
|
|
about counting children with impunity.
|
|
</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">ParseTree::verify</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">VERIFICATIONS</span><span class="plain-syntax">, </span><span class="string-syntax">"[Verifying initial parse tree]\n"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-></span><span class="identifier-syntax">root_node</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">Errors::set_internal_handler</span><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Root of parse tree NULL"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP54" class="function-link"><span class="function-syntax">ParseTree::verify_structure</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="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">VERIFICATIONS</span><span class="plain-syntax">, </span><span class="string-syntax">"[Initial parse tree correct.]\n"</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">node_errors</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::verify_structure</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><a href="2-pt.html#SP52" class="function-link"><span class="function-syntax">ParseTree::verify_integrity</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</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-pt.html#SP56" class="function-link"><span class="function-syntax">ParseTree::make_parentage_allowed_table</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP59" class="function-link"><span class="function-syntax">ParseTree::make_annotation_allowed_table</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">node_errors</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-pt.html#SP55" class="function-link"><span class="function-syntax">ParseTree::verify_structure_recursively</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">node_errors</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">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"[Verification failed: %d node errors]\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">node_errors</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">Errors::set_internal_handler</span><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Parse tree broken"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP55"></a><b>§55. </b>Note that on every call to the following routine, (i) <span class="extract"><span class="extract-syntax">p</span></span> is a valid
|
|
parse node and (ii) either <span class="extract"><span class="extract-syntax">p</span></span> is the tree root, in which case <span class="extract"><span class="extract-syntax">parent</span></span> is
|
|
<span class="extract"><span class="extract-syntax">NULL</span></span>, or <span class="extract"><span class="extract-syntax">parent</span></span> is the unique node having <span class="extract"><span class="extract-syntax">p</span></span> (or an alternative to <span class="extract"><span class="extract-syntax">p</span></span>)
|
|
among its children.
|
|
</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">ParseTree::verify_structure_recursively</span><button class="popup" onclick="togglePopup('usagePopup38')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup38">Usage of <span class="code-font"><span class="function-syntax">ParseTree::verify_structure_recursively</span></span>:<br/><a href="2-pt.html#SP54">§54</a></span></button><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="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parent</span><span class="plain-syntax">) {</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><a href="2-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::get_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata</span><span class="plain-syntax"> = </span><a href="2-pt.html#SP18" class="function-link"><span class="function-syntax">ParseTree::node_metadata</span></a><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">metadata</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">"broken tree should have been reported"</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pt.html#SP55_1" class="named-paragraph-link"><span class="named-paragraph">Check rule (1) of the invariant</span><span class="named-paragraph-number">55.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pt.html#SP55_2" class="named-paragraph-link"><span class="named-paragraph">Check rule (2) of the invariant</span><span class="named-paragraph-number">55.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parent</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-pt.html#SP55_3" class="named-paragraph-link"><span class="named-paragraph">Check rule (3) of the invariant</span><span class="named-paragraph-number">55.3</span></a></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">children_count</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">q</span><span class="plain-syntax">=</span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="element-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">q</span><span class="plain-syntax">; </span><span class="identifier-syntax">q</span><span class="plain-syntax">=</span><span class="identifier-syntax">q</span><span class="plain-syntax">-></span><span class="element-syntax">next</span><span class="plain-syntax">, </span><span class="identifier-syntax">children_count</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP55" class="function-link"><span class="function-syntax">ParseTree::verify_structure_recursively</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">q</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pt.html#SP55_4" class="named-paragraph-link"><span class="named-paragraph">Check rule (4) of the invariant</span><span class="named-paragraph-number">55.4</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">p</span><span class="plain-syntax">-></span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP55" class="function-link"><span class="function-syntax">ParseTree::verify_structure_recursively</span></a><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><span class="identifier-syntax">parent</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP55_1"></a><b>§55.1. </b>Rule (1): no INVALID nodes.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check rule (1) of the invariant</span><span class="named-paragraph-number">55.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">t</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="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"N%d is $N, which is not allowed except temporarily\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pt.html#SP55_1_1" class="named-paragraph-link"><span class="named-paragraph">Log this invariant failure</span><span class="named-paragraph-number">55.1.1</span></a></span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="2-pt.html#SP55">§55</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP55_2"></a><b>§55.2. </b>Rule (2): all annotations must be legal for the given node type.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check rule (2) of the invariant</span><span class="named-paragraph-number">55.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">parse_node_annotation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="element-syntax">annotations</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">; </span><span class="identifier-syntax">pna</span><span class="plain-syntax">=</span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">next_annotation</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-pt.html#SP59" class="function-link"><span class="function-syntax">ParseTree::annotation_allowed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">kind_of_annotation</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%d is $N, which is not allowed to have annotation %d\n"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">kind_of_annotation</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Node %08x, ann %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="identifier-syntax">pna</span><span class="plain-syntax">-></span><span class="element-syntax">kind_of_annotation</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pt.html#SP55_1_1" class="named-paragraph-link"><span class="named-paragraph">Log this invariant failure</span><span class="named-paragraph-number">55.1.1</span></a></span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="2-pt.html#SP55">§55</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP55_3"></a><b>§55.3. </b>Rule (3): can this combination of parent and child exist?
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check rule (3) of the invariant</span><span class="named-paragraph-number">55.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t_parent</span><span class="plain-syntax"> = </span><a href="2-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::get_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parent</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">child_category</span><span class="plain-syntax"> = </span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-></span><span class="element-syntax">category</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">parse_tree_node_type</span><span class="plain-syntax"> *</span><span class="identifier-syntax">metadata_parent</span><span class="plain-syntax"> = </span><a href="2-pt.html#SP18" class="function-link"><span class="function-syntax">ParseTree::node_metadata</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t_parent</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">metadata_parent</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">"broken tree should have been reported"</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">parent_category</span><span class="plain-syntax"> = </span><span class="identifier-syntax">metadata_parent</span><span class="plain-syntax">-></span><span class="element-syntax">category</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-pt.html#SP57" class="function-link"><span class="function-syntax">ParseTree::parentage_allowed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t_parent</span><span class="plain-syntax">, </span><span class="identifier-syntax">parent_category</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="identifier-syntax">child_category</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%d is $N (category %d): should not be a child of $N (category %d)\n"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="identifier-syntax">child_category</span><span class="plain-syntax">, </span><span class="identifier-syntax">t_parent</span><span class="plain-syntax">, </span><span class="identifier-syntax">parent_category</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pt.html#SP55_1_1" class="named-paragraph-link"><span class="named-paragraph">Log this invariant failure</span><span class="named-paragraph-number">55.1.1</span></a></span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="2-pt.html#SP55">§55</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP55_4"></a><b>§55.4. </b>Rule (4): The number of children has to be within the given extrema.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check rule (4) of the invariant</span><span class="named-paragraph-number">55.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">children_count</span><span class="plain-syntax"> < </span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-></span><span class="element-syntax">min_children</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%d has %d children, but min for $N is %d:\n"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">children_count</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-></span><span class="element-syntax">min_children</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pt.html#SP55_1_1" class="named-paragraph-link"><span class="named-paragraph">Log this invariant failure</span><span class="named-paragraph-number">55.1.1</span></a></span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">children_count</span><span class="plain-syntax"> > </span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-></span><span class="element-syntax">max_children</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%d has %d children, but max for $N is %d:\n"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">children_count</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="identifier-syntax">metadata</span><span class="plain-syntax">-></span><span class="element-syntax">max_children</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-pt.html#SP55_1_1" class="named-paragraph-link"><span class="named-paragraph">Log this invariant failure</span><span class="named-paragraph-number">55.1.1</span></a></span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="2-pt.html#SP55">§55</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP55_1_1"></a><b>§55.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Log this invariant failure</span><span class="named-paragraph-number">55.1.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::is</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parent</span><span class="plain-syntax">, </span><span class="constant-syntax">ROOT_NT</span><span class="plain-syntax">)) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Failing subtree:\n$T"</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Failing subtree:\n$T"</span><span class="plain-syntax">, </span><span class="identifier-syntax">parent</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">node_errors</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="2-pt.html#SP55_1">§55.1</a>, <a href="2-pt.html#SP55_2">§55.2</a>, <a href="2-pt.html#SP55_3">§55.3</a>, <a href="2-pt.html#SP55_4">§55.4</a> (twice).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP56"></a><b>§56. Parentage rules. </b>It's mostly the case that node category determines whether one node can be
|
|
parent to another:
|
|
</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">parentage_allowed_set_up</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">parentage_allowed</span><span class="plain-syntax">[</span><span class="identifier-syntax">NO_DEFINED_NCAT_VALUES</span><span class="plain-syntax">][</span><span class="identifier-syntax">NO_DEFINED_NCAT_VALUES</span><span class="plain-syntax">];</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::make_parentage_allowed_table</span><button class="popup" onclick="togglePopup('usagePopup39')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup39">Usage of <span class="code-font"><span class="function-syntax">ParseTree::make_parentage_allowed_table</span></span>:<br/><a href="2-pt.html#SP54">§54</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parentage_allowed_set_up</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parentage_allowed_set_up</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">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="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax"> < </span><span class="identifier-syntax">NO_DEFINED_NCAT_VALUES</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">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax"> < </span><span class="identifier-syntax">NO_DEFINED_NCAT_VALUES</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parentage_allowed</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">][</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parentage_allowed</span><span class="plain-syntax">[</span><span class="constant-syntax">L1_NCAT</span><span class="plain-syntax">][</span><span class="constant-syntax">L1_NCAT</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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP57"></a><b>§57. </b>But there are exceptions. Note that an <span class="extract"><span class="extract-syntax">L2_NCAT</span></span> node can have no parent
|
|
at all, according to the broad rules above: in fact, it can, but only if
|
|
the parent is <span class="extract"><span class="extract-syntax">HEADING_NT</span></span>.
|
|
</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">ParseTree::parentage_allowed</span><button class="popup" onclick="togglePopup('usagePopup40')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup40">Usage of <span class="code-font"><span class="function-syntax">ParseTree::parentage_allowed</span></span>:<br/><a href="2-pt.html#SP55_3">§55.3</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_parent</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cat_parent</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">node_type_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t_child</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cat_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">parentage_allowed</span><span class="plain-syntax">[</span><span class="identifier-syntax">cat_parent</span><span class="plain-syntax">][</span><span class="identifier-syntax">cat_child</span><span class="plain-syntax">]) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PARENTAGE_EXCEPTIONS</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PARENTAGE_EXCEPTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">t_parent</span><span class="plain-syntax">, </span><span class="identifier-syntax">cat_parent</span><span class="plain-syntax">, </span><span class="identifier-syntax">t_child</span><span class="plain-syntax">, </span><span class="identifier-syntax">cat_child</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">t_parent</span><span class="plain-syntax"> == </span><span class="constant-syntax">AMBIGUITY_NT</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">t_child</span><span class="plain-syntax"> == </span><span class="constant-syntax">AMBIGUITY_NT</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="SP58"></a><b>§58. Annotation rules. </b>This is on an altogether grander scale.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_NODE_TYPES</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">for</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="constant-syntax">BASE_OF_ENUMERATED_NTS</span><span class="plain-syntax">; </span><span class="identifier-syntax">t</span><span class="plain-syntax"><</span><span class="constant-syntax">BASE_OF_ENUMERATED_NTS</span><span class="plain-syntax">+</span><span class="identifier-syntax">NO_DEFINED_NT_VALUES</span><span class="plain-syntax">; </span><span class="identifier-syntax">t</span><span class="plain-syntax">++)</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">annotation_allowed_set_up</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">annotation_allowed</span><span class="plain-syntax">[</span><span class="identifier-syntax">NO_DEFINED_NT_VALUES</span><span class="plain-syntax">][</span><span class="constant-syntax">MAX_ANNOT_NUMBER</span><span class="plain-syntax">+1];</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::allow_annotation</span><button class="popup" onclick="togglePopup('usagePopup41')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup41">Usage of <span class="code-font"><span class="function-syntax">ParseTree::allow_annotation</span></span>:<br/><a href="2-pt.html#SP59">§59</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">annot</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">annotation_allowed</span><span class="plain-syntax">[</span><span class="identifier-syntax">t</span><span class="plain-syntax"> - </span><span class="constant-syntax">BASE_OF_ENUMERATED_NTS</span><span class="plain-syntax">][</span><span class="identifier-syntax">annot</span><span class="plain-syntax">] = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::allow_annotation_to_category</span><button class="popup" onclick="togglePopup('usagePopup42')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup42">Usage of <span class="code-font"><span class="function-syntax">ParseTree::allow_annotation_to_category</span></span>:<br/><a href="2-pt.html#SP59">§59</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cat</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">annot</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_NODE_TYPES</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-pt.html#SP19" class="function-link"><span class="function-syntax">ParseTree::cat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">) == </span><span class="identifier-syntax">cat</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP58" class="function-link"><span class="function-syntax">ParseTree::allow_annotation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="identifier-syntax">annot</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP59"></a><b>§59. </b>The eagle-eyed observer will note that the <span class="extract"><span class="extract-syntax">meaning</span></span> annotation is never
|
|
allowed. In fact it does exist, but only for meaning-coded parse nodes, which
|
|
never exist inside trees and are used only as parsing intermediates. So we
|
|
never see this annotation here.
|
|
</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">ParseTree::make_annotation_allowed_table</span><button class="popup" onclick="togglePopup('usagePopup43')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup43">Usage of <span class="code-font"><span class="function-syntax">ParseTree::make_annotation_allowed_table</span></span>:<br/><a href="2-pt.html#SP54">§54</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">annotation_allowed_set_up</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">annotation_allowed_set_up</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-pt.html#SP58" class="function-link"><span class="function-syntax">ParseTree::allow_annotation</span></a><span class="plain-syntax">(</span><span class="constant-syntax">HEADING_NT</span><span class="plain-syntax">, </span><span class="constant-syntax">heading_level_ANNOT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP58" class="function-link"><span class="function-syntax">ParseTree::allow_annotation</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SENTENCE_NT</span><span class="plain-syntax">, </span><span class="constant-syntax">language_element_ANNOT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP58" class="function-link"><span class="function-syntax">ParseTree::allow_annotation_to_category</span></a><span class="plain-syntax">(</span><span class="constant-syntax">L1_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">sentence_unparsed_ANNOT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP58" class="function-link"><span class="function-syntax">ParseTree::allow_annotation_to_category</span></a><span class="plain-syntax">(</span><span class="constant-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">sentence_unparsed_ANNOT</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">ANNOTATION_PERMISSIONS_WRITER</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ANNOTATION_PERMISSIONS_WRITER</span><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</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">ParseTree::annotation_allowed</span><button class="popup" onclick="togglePopup('usagePopup44')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup44">Usage of <span class="code-font"><span class="function-syntax">ParseTree::annotation_allowed</span></span>:<br/><a href="2-pt.html#SP25">§25</a>, <a href="2-pt.html#SP55_2">§55.2</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">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">annot</span><span class="plain-syntax"> <= </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">annot</span><span class="plain-syntax"> > </span><span class="constant-syntax">MAX_ANNOT_NUMBER</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">"annotation number out of range"</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="constant-syntax">BASE_OF_ENUMERATED_NTS</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">t</span><span class="plain-syntax"> < </span><span class="constant-syntax">BASE_OF_ENUMERATED_NTS</span><span class="plain-syntax">+</span><span class="identifier-syntax">NO_DEFINED_NT_VALUES</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">annotation_allowed</span><span class="plain-syntax">[</span><span class="identifier-syntax">t</span><span class="plain-syntax"> - </span><span class="constant-syntax">BASE_OF_ENUMERATED_NTS</span><span class="plain-syntax">][</span><span class="identifier-syntax">annot</span><span class="plain-syntax">];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP60"></a><b>§60. Ambiguity subtrees. </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">ParseTree::add_possible_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="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::is</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">reading</span><span class="plain-syntax">, </span><span class="identifier-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="identifier-syntax">endif</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::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-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::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">CORE_MODULE</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ParseTreeUsage::is_phrasal</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">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><a href="2-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::get_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">reading</span><span class="plain-syntax">) == </span><a href="2-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::get_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP60" class="function-link"><span class="function-syntax">ParseTree::add_pr_inv</span></a><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="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">CORE_MODULE</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ParseTreeUsage::is_phrasal</span><span class="plain-syntax">(</span><span class="identifier-syntax">reading</span><span class="plain-syntax">)) &&</span>
|
|
<span class="plain-syntax"> (</span><a href="2-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::get_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">reading</span><span class="plain-syntax">) == </span><a href="2-pt.html#SP24" class="function-link"><span class="function-syntax">ParseTree::get_type</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">))) {</span>
|
|
<span class="plain-syntax"> </span><a href="2-pt.html#SP60" class="function-link"><span class="function-syntax">ParseTree::add_pr_inv</span></a><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="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">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-pt.html#SP22" class="function-link"><span class="function-syntax">ParseTree::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>
|
|
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParseTree::add_pr_inv</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="reserved-syntax">parse_node</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">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">N</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="element-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">next_N</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">N</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">N</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="identifier-syntax">N</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax"> = </span><span class="identifier-syntax">next_N</span><span class="plain-syntax">, </span><span class="identifier-syntax">next_N</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">N</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">N</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><a href="2-pt.html#SP60" class="function-link"><span class="function-syntax">ParseTree::add_single_pr_inv</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</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">ParseTree::add_single_pr_inv</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="reserved-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">N</span><span class="plain-syntax">) {</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">down</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><span class="identifier-syntax">Invocations::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">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">while</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="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">Invocations::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">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="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="identifier-syntax">N</span><span class="plain-syntax">; </span><span class="identifier-syntax">N</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="plain-syntax">#</span><span class="identifier-syntax">endif</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="1-sm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresscurrent">pt</li><li class="progresssection"><a href="2-snt.html">snt</a></li><li class="progressnext"><a href="2-snt.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|