1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/docs/core-module/25-pi.html
2019-04-22 15:42:10 +01:00

624 lines
70 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>25/in</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '25/pi' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#25">Chapter 25: Compilation</a></li><li><b>Parse Invocations</b></li></ul><p class="purpose">To register phrases with the excerpt parser, and to provide the excerpt parser with help in putting invocations together.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Parsing of phrases</a></li><li><a href="#SP4">&#167;4. Parsing invocations</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Parsing of phrases. </b>The control structures of Inform are defined in the Standard Rules. Before
the coming of Python-style indentation to Inform, blocks of code were closed
with "end..." phrases: "end if", "end repeat" and "end while". In fact these
are still valid, for the benefit of partially sighted users, and the
following construction makes the end phrase for a given control structure.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">end</span><span class="plain">-</span><span class="reserved">phrase</span><span class="plain">-</span><span class="identifier">construction</span><span class="plain">&gt; ::=</span>
<span class="identifier">end</span><span class="plain"> ...</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>This section aims to take text like
</p>
<blockquote>
<p>add 17 to the list of small primes;</p>
</blockquote>
<p class="inwebparagraph">which the excerpt parser can see is a possible usage of a phrase such as
</p>
<blockquote>
<p>To add (new entry - K) to (L - list of values of kind K), if absent: ...</p>
</blockquote>
<p class="inwebparagraph">and to help the excerpt parser by putting together an invocation.
</p>
<p class="inwebparagraph">To even make that possible, though, we must first register each "To..."
phrase definition with the excerpt parser:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Parser::register_excerpt</span><span class="plain">(</span><span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">) {</span>
<span class="reserved">ph_type_data</span><span class="plain"> *</span><span class="identifier">phtd</span><span class="plain"> = &amp;(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;type_data</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::empty</span><span class="plain">(</span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;registration_text</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PHRASE_REGISTRATION</span><span class="plain">, </span><span class="string">"Register phrase &lt;%W&gt; with type:\</span><span class="plain">n</span><span class="string">$h"</span><span class="plain">, </span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;registration_text</span><span class="plain">, </span><span class="identifier">phtd</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;registration_text</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;manner_of_return</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DECIDES_NOTHING_MOR</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Phrases::TypeData::is_a_say_phrase</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">))</span>
<span class="functiontext">Phrases::Parser::register_phrasal</span><span class="plain">(</span><span class="constant">SAY_PHRASE_MC</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">Wordings::trim_first_word</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;as_inline.block_follows</span><span class="plain"> != </span><span class="constant">NO_BLOCK_FOLLOWS</span><span class="plain">)</span>
<span class="functiontext">Phrases::Parser::register_phrasal</span><span class="plain">(</span><span class="constant">VOID_PHRASE_MC</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">Wordings::trim_last_word</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">));</span>
<span class="reserved">else</span>
<span class="functiontext">Phrases::Parser::register_phrasal</span><span class="plain">(</span><span class="constant">VOID_PHRASE_MC</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DECIDES_CONDITION_MOR</span><span class="plain">: </span><span class="functiontext">Phrases::Parser::register_phrasal</span><span class="plain">(</span><span class="constant">COND_PHRASE_MC</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DECIDES_VALUE_MOR</span><span class="plain">: </span><span class="functiontext">Phrases::Parser::register_phrasal</span><span class="plain">(</span><span class="constant">VALUE_PHRASE_MC</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Parser::register_excerpt is used in 22/tp (<a href="22-tp.html#SP6">&#167;6</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>At this point, then, we've identified the meaning code (MC) to register
the phrase under, and must make the actual registration.
</p>
<pre class="display">
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">last_phrase_where_rp_problemed</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Parser::register_phrasal</span><span class="plain">(</span><span class="reserved">unsigned</span><span class="plain"> </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">phrase_mc</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PHRASE_REGISTRATION</span><span class="plain">, </span><span class="string">"Register phrasal on &lt;%W&gt;: $u\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">,</span>
<span class="functiontext">Phrases::TypeData::kind</span><span class="plain">(&amp;(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;type_data</span><span class="plain">)));</span>
&lt;<span class="cwebmacro">Vet phrase text for suitability</span> <span class="cwebmacronumber">3.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Look for slash-divided alternative phrasings and recurse to register all variations</span> <span class="cwebmacronumber">3.2</span>&gt;<span class="plain">;</span>
<span class="identifier">ExcerptMeanings::register</span><span class="plain">(</span><span class="identifier">phrase_mc</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">STORE_POINTER_phrase</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">));</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Parser::register_phrasal is used in <a href="#SP2">&#167;2</a>, <a href="#SP3_2_1">&#167;3.2.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b>Some sanity checks first:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Vet phrase text for suitability</span> <span class="cwebmacronumber">3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">bl</span><span class="plain"> = 0, </span><span class="identifier">fixed_words</span><span class="plain"> = 0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phrase_mc</span><span class="plain"> == </span><span class="constant">SAY_PHRASE_MC</span><span class="plain">) </span><span class="identifier">fixed_words</span><span class="plain">++;</span>
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">OPENBRACKET_V</span><span class="plain">) </span><span class="identifier">bl</span><span class="plain">++;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">CLOSEBRACKET_V</span><span class="plain">) </span><span class="identifier">bl</span><span class="plain">--;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bl</span><span class="plain"> == 0) {</span>
<span class="identifier">fixed_words</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Vocabulary::test_flags</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">TEXT_MC</span><span class="plain">+</span><span class="identifier">TEXTWITHSUBS_MC</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Issue problem for quoted text in phrase wording</span> <span class="cwebmacronumber">3.1.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">CLOSEBRACKET_V</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">+1) == </span><span class="identifier">OPENBRACKET_V</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Issue problem for brackets jammed up against each other</span> <span class="cwebmacronumber">3.1.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fixed_words</span><span class="plain"> == 0) </span>&lt;<span class="cwebmacro">Issue problem for phrase consisting only of tokens</span> <span class="cwebmacronumber">3.1.3</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1"></a><b>&#167;3.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue problem for quoted text in phrase wording</span> <span class="cwebmacronumber">3.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain"> != </span><span class="identifier">last_phrase_where_rp_problemed</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_QuotedInPhrase</span><span class="plain">),</span>
<span class="string">"phrases can't be defined with quoted text as part of the fixed wording"</span><span class="plain">,</span>
<span class="string">"so something like 'To go \</span><span class="plain">"</span><span class="string">voluntarily\</span><span class="plain">"</span><span class="string"> to jail: ...' is not allowed."</span><span class="plain">);</span>
<span class="identifier">last_phrase_where_rp_problemed</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1">&#167;3.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_2"></a><b>&#167;3.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue problem for brackets jammed up against each other</span> <span class="cwebmacronumber">3.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain"> != </span><span class="identifier">last_phrase_where_rp_problemed</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_AdjacentTokens</span><span class="plain">),</span>
<span class="string">"phrases can't be defined so that they have two bracketed varying elements "</span>
<span class="string">"immediately next to each other"</span><span class="plain">,</span>
<span class="string">"but instead need at least one fixed word in between. Thus 'To combine "</span>
<span class="string">"(X - a number) (Y - a number)' is not allowed, but 'To combine (X - a "</span>
<span class="string">"number) with (Y - a number)' works because of the 'with' dividing the "</span>
<span class="string">"bracketed terms X and Y."</span><span class="plain">);</span>
<span class="identifier">last_phrase_where_rp_problemed</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1">&#167;3.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_3"></a><b>&#167;3.1.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue problem for phrase consisting only of tokens</span> <span class="cwebmacronumber">3.1.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain"> != </span><span class="identifier">last_phrase_where_rp_problemed</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_MustBeOneWord</span><span class="plain">),</span>
<span class="string">"a 'To...' phrase must contain at least one fixed word"</span><span class="plain">,</span>
<span class="string">"that is, one word other than the bracketed variables. So a declaration "</span>
<span class="string">"like 'To (N - number): ...' is not allowed."</span><span class="plain">);</span>
<span class="identifier">last_phrase_where_rp_problemed</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1">&#167;3.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_2"></a><b>&#167;3.2. </b>The remaining work is to look out for this sort of thing:
</p>
<blockquote>
<p>To rearrange the deckchairs/loungers on (S - a ship): ...</p>
</blockquote>
<p class="inwebparagraph">where the slash indicates an alternative wording:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Look for slash-divided alternative phrasings and recurse to register all variations</span> <span class="cwebmacronumber">3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">bl</span><span class="plain"> = 0;</span>
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">OPENBRACKET_V</span><span class="plain">) </span><span class="identifier">bl</span><span class="plain">++;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">CLOSEBRACKET_V</span><span class="plain">) </span><span class="identifier">bl</span><span class="plain">--;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bl</span><span class="plain"> == 0) {</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phrase_mc</span><span class="plain"> == </span><span class="constant">SAY_PHRASE_MC</span><span class="plain">) </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">Lexer::word_raw_text</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">Lexer::word_text</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]; </span><span class="identifier">j</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">j</span><span class="plain">&gt;0) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">-1] != </span><span class="character">'/'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] == </span><span class="character">'/'</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">+1]) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">+1] != </span><span class="character">'/'</span><span class="plain">))</span>
&lt;<span class="cwebmacro">This word is divided by a forward slash at the j-position in word i</span> <span class="cwebmacronumber">3.2.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_1"></a><b>&#167;3.2.1. </b>What we do is to reconstruct this as two different registrations:
</p>
<blockquote>
<p>To rearrange the deckchairs on (S - a ship): ...</p>
</blockquote>
<blockquote>
<p>To rearrange the loungers on (S - a ship): ...</p>
</blockquote>
<p class="inwebparagraph">and then recursively call ourselves to handle each individual one. We'll
call the left and right hand sides of "deckchairs/loungers" the A and
B forms.
</p>
<p class="inwebparagraph">Note than a phrase with many slashed words will register a frightening
number of possibilities &mdash; for example,
</p>
<blockquote>
<p>To meld/blend/merge (O - object) onto/into/amongst/with (P - object) quickly/rapidly/pronto: ...</p>
</blockquote>
<p class="inwebparagraph">will register 36 excerpts. But the hashing in the excerpts parser shouldn't
make the result too slow.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">This word is divided by a forward slash at the j-position in word i</span> <span class="cwebmacronumber">3.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">a_form</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">b_form</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Splice up the A and B forms of the slashed word</span> <span class="cwebmacronumber">3.2.1.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Make sure the A form isn't the S-word</span> <span class="cwebmacronumber">3.2.1.2</span>&gt;<span class="character">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">AW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">BW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Splice up the A and B forms of the whole phrase wording</span> <span class="cwebmacronumber">3.2.1.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">AW</span><span class="plain">)) </span><span class="functiontext">Phrases::Parser::register_phrasal</span><span class="plain">(</span><span class="identifier">phrase_mc</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">AW</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">BW</span><span class="plain">)) </span><span class="functiontext">Phrases::Parser::register_phrasal</span><span class="plain">(</span><span class="identifier">phrase_mc</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">BW</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">a_form</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">b_form</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2">&#167;3.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_1_1"></a><b>&#167;3.2.1.1. </b>The double-dash means "omit this word altogether".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Splice up the A and B forms of the slashed word</span> <span class="cwebmacronumber">3.2.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">=0; </span><span class="identifier">k</span><span class="plain">&lt;</span><span class="identifier">j</span><span class="plain">; </span><span class="identifier">k</span><span class="plain">++) </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">a_form</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">]);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">=</span><span class="identifier">j</span><span class="plain">+1; </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">]; </span><span class="identifier">k</span><span class="plain">++) </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">b_form</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">]);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">a_form</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"--"</span><span class="plain">)) </span><span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">a_form</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">b_form</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"--"</span><span class="plain">)) </span><span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">b_form</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2_1">&#167;3.2.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_1_2"></a><b>&#167;3.2.1.2. </b>If we don't check this then hybrids like
</p>
<blockquote>
<p>To say/adjust (X - an object): ...</p>
</blockquote>
<p class="inwebparagraph">will confuse two different sorts of phrase. ("Say" is allowed after the first
word, though.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Make sure the A form isn't the S-word</span> <span class="cwebmacronumber">3.2.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">a_form</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"say"</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">phrase_mc</span><span class="plain"> != </span><span class="constant">SAY_PHRASE_MC</span><span class="plain">))</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain"> != </span><span class="identifier">last_phrase_where_rp_problemed</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_SaySlashed</span><span class="plain">),</span>
<span class="string">"'say' is not allowed as the first word of a phrase"</span><span class="plain">,</span>
<span class="string">"even when presented as one of a number of slashed alternatives. "</span>
<span class="string">"(This is because 'say' is reserved for creating text substitutions.)"</span><span class="plain">);</span>
<span class="identifier">last_phrase_where_rp_problemed</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2_1">&#167;3.2.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_1_3"></a><b>&#167;3.2.1.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Splice up the A and B forms of the whole phrase wording</span> <span class="cwebmacronumber">3.2.1.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">feed_t</span><span class="plain"> </span><span class="identifier">id</span><span class="plain"> = </span><span class="identifier">Feeds::begin</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> &gt; </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">Feeds::feed_wording</span><span class="plain">(</span><span class="identifier">Wordings::up_to</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">-1));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">a_form</span><span class="plain">) &gt; 0) </span><span class="identifier">Feeds::feed_stream_expanding_strings</span><span class="plain">(</span><span class="identifier">a_form</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> &lt; </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">Feeds::feed_wording</span><span class="plain">(</span><span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1));</span>
<span class="identifier">AW</span><span class="plain"> = </span><span class="identifier">Feeds::end</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">);</span>
<span class="identifier">id</span><span class="plain"> = </span><span class="identifier">Feeds::begin</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> &gt; </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">Feeds::feed_wording</span><span class="plain">(</span><span class="identifier">Wordings::up_to</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">-1));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">b_form</span><span class="plain">) &gt; 0) </span><span class="identifier">Feeds::feed_stream_expanding_strings</span><span class="plain">(</span><span class="identifier">b_form</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> &lt; </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">Feeds::feed_wording</span><span class="plain">(</span><span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1));</span>
<span class="identifier">BW</span><span class="plain"> = </span><span class="identifier">Feeds::end</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2_1">&#167;3.2.1</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Parsing invocations. </b>So, then, at this point the excerpt parser has identified a phrase which it
thinks may be being invoked in some text. For example, it may have read:
</p>
<blockquote>
<p>advance the pawn by 2;</p>
</blockquote>
<p class="inwebparagraph">and guessed that this is an invocation of
</p>
<blockquote>
<p>To advance (the piece - a chess piece) by (N - a number): ...</p>
</blockquote>
<p class="inwebparagraph">An S-node will have been constructed for the possibility that this is correct,
identifying the text of any phrase options used (here there are none) and the
text of the tokens, "the pawn" and "2".
</p>
<p class="inwebparagraph">We now take over, and construct an invocation structure on this basis.
Note that there's no reason to suppose this will pass type-checking:
we would be just as happy with
</p>
<blockquote>
<p>advance "frangipane" by 10:21 PM;</p>
</blockquote>
<p class="inwebparagraph">because our only aim here is to document the possibility for later checking.
</p>
<p class="inwebparagraph">The invocation is marked as "unproven", meaning that the typechecker hasn't
yet vetted it, unless it's a fixed wording with nothing to check:
</p>
<blockquote>
<p>To shed my skin: ...</p>
</blockquote>
<p class="inwebparagraph">because then our purely textual match is sufficient.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Phrases::Parser::parse_against</span><span class="plain">(</span><span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"parse against null subtree"</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">WW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">OW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">token_text</span><span class="plain">[15]; </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_tokens</span><span class="plain"> = 0;</span>
&lt;<span class="cwebmacro">Extract all this text from the subtree</span> <span class="cwebmacronumber">4.1</span>&gt;<span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain"> = </span><span class="functiontext">Invocations::new</span><span class="plain">();</span>
<span class="functiontext">Invocations::set_word_range</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">WW</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">);</span>
<span class="functiontext">Dash::suspend_validation</span><span class="plain">(</span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">ph_type_data</span><span class="plain"> *</span><span class="identifier">phtd</span><span class="plain"> = &amp;(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;type_data</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_tokens</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span>&lt;<span class="cwebmacro">Parse the ith token into the invocation</span> <span class="cwebmacronumber">4.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">OW</span><span class="plain">)) </span><span class="functiontext">Invocations::set_phrase_options</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">OW</span><span class="plain">);</span>
<span class="functiontext">Dash::suspend_validation</span><span class="plain">(</span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">MATCHING</span><span class="plain">, </span><span class="string">"Parse against to invocation: $e\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">inv</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">inv</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Parser::parse_against is used in 10/cap (<a href="10-cap.html#SP12_1">&#167;12.1</a>).</p>
<p class="inwebparagraph"><a id="SP4_1"></a><b>&#167;4.1. </b>We will never actually hit the 15 tokens limit, because it's impossible to
register phrases with more than that number of tokens anyway.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Extract all this text from the subtree</span> <span class="cwebmacronumber">4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">WW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="identifier">p</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain"> &amp;&amp; (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">is_phrase_option_ANNOT</span><span class="plain">))) {</span>
<span class="identifier">OW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="identifier">p</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">for</span><span class="plain"> (; ((</span><span class="identifier">p</span><span class="plain">) &amp;&amp; (</span><span class="identifier">no_tokens</span><span class="plain">&lt;15)); </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="constant">UNKNOWN_NT</span><span class="plain">)</span>
<span class="identifier">token_text</span><span class="plain">[</span><span class="identifier">no_tokens</span><span class="plain">++] = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Unexpected production in phrase args"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_tokens</span><span class="plain"> &gt; </span><span class="constant">MAX_TOKENS_PER_PHRASE</span><span class="plain">)</span>
<span class="identifier">Problems::Fatal::issue</span><span class="plain">(</span><span class="string">"MAX_TOKENS_PER_PHRASE exceeded"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_2"></a><b>&#167;4.2. </b>As can be seen, the way we parse the token text depends on the context,
that is, depends on what we're expecting to find. (This is why the excerpt
parser needs our help in the first place.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Parse the ith token into the invocation</span> <span class="cwebmacronumber">4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">to_match</span><span class="plain"> = </span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;token_sequence</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.to_match</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">Articles::remove_the</span><span class="plain">(</span><span class="identifier">token_text</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;token_sequence</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.construct</span><span class="plain"> == </span><span class="constant">NEW_LOCAL_PT_CONSTRUCT</span><span class="plain">) {</span>
<span class="identifier">to_match</span><span class="plain"> = </span><span class="functiontext">Specifications::from_kind</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">);</span>
<span class="functiontext">Invocations::make_token</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">NEW_LOCAL_CONTEXT_NT</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;token_sequence</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.token_kind</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;token_sequence</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.construct</span><span class="plain"> == </span><span class="constant">EXISTING_LOCAL_PT_CONSTRUCT</span><span class="plain">) {</span>
<span class="identifier">to_match</span><span class="plain"> = </span><span class="functiontext">Specifications::from_kind</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">);</span>
<span class="functiontext">Invocations::make_token</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">LVALUE_LOCAL_CONTEXT_NT</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;token_sequence</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.token_kind</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;token_sequence</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.construct</span><span class="plain"> == </span><span class="constant">STORAGE_PT_CONSTRUCT</span><span class="plain">)</span>
<span class="functiontext">Invocations::make_token</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">LVALUE_CONTEXT_NT</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;token_sequence</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.construct</span><span class="plain"> == </span><span class="constant">TABLE_REFERENCE_PT_CONSTRUCT</span><span class="plain">)</span>
<span class="functiontext">Invocations::make_token</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">LVALUE_TR_CONTEXT_NT</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;token_sequence</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.construct</span><span class="plain"> == </span><span class="constant">CONDITION_PT_CONSTRUCT</span><span class="plain">)</span>
<span class="functiontext">Invocations::make_token</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">CONDITION_CONTEXT_NT</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phtd</span><span class="plain">-</span><span class="element">&gt;token_sequence</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.construct</span><span class="plain"> == </span><span class="constant">VOID_PT_CONSTRUCT</span><span class="plain">)</span>
<span class="functiontext">Invocations::make_token</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">VOID_CONTEXT_NT</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_kind_like</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">))</span>
<span class="functiontext">Invocations::make_token</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">RVALUE_CONTEXT_NT</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">))</span>
<span class="functiontext">Invocations::make_token</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">MATCHING_RVALUE_CONTEXT_NT</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">))</span>
<span class="functiontext">Invocations::make_token</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">SPECIFIC_RVALUE_CONTEXT_NT</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Invocations::make_token</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">RVALUE_CONTEXT_NT</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">); </span> <span class="comment">doesn't actually happen</span>
<span class="functiontext">Invocations::set_token_to_be_parsed_against</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">to_match</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">as_parsed</span><span class="plain"> = </span><span class="functiontext">Specifications::new_UNKNOWN</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">);</span>
<span class="functiontext">Invocations::set_token_as_parsed</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">as_parsed</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Parser::parse_within_inv</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">) {</span>
<span class="functiontext">ExParser::warn_expression_cache</span><span class="plain">();</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Invocations::get_no_tokens</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = 0; </span><span class="identifier">i</span><span class="plain"> &lt; </span><span class="identifier">N</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">to_match</span><span class="plain"> = </span><span class="functiontext">Invocations::get_token_to_be_parsed_against</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">cons</span><span class="plain"> = -1;</span>
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain"> = </span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain">) </span><span class="identifier">cons</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;type_data.token_sequence</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.construct</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">to_match</span><span class="plain">) || (</span><span class="identifier">cons</span><span class="plain"> == </span><span class="constant">CONDITION_PT_CONSTRUCT</span><span class="plain">) || (</span><span class="identifier">cons</span><span class="plain"> == </span><span class="constant">VOID_PT_CONSTRUCT</span><span class="plain">)) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">as_parsed</span><span class="plain"> = </span><span class="functiontext">Invocations::get_token_as_parsed</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">XW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">as_parsed</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">pto</span><span class="plain"> = </span><span class="identifier">permit_trying_omission</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Specifications::is_kind_like</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">), </span><span class="identifier">K_stored_action</span><span class="plain">))) {</span>
<span class="identifier">permit_trying_omission</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Parse the action in a try phrase</span> <span class="cwebmacronumber">5.1</span>&gt;<span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">permit_trying_omission</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
&lt;<span class="cwebmacro">Parse any other token</span> <span class="cwebmacronumber">5.2</span>&gt;<span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="plain">}</span>
<span class="identifier">permit_trying_omission</span><span class="plain"> = </span><span class="identifier">pto</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">as_parsed</span><span class="plain">, </span><span class="identifier">XW</span><span class="plain">);</span>
<span class="functiontext">Invocations::set_token_as_parsed</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">as_parsed</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Parser::parse_within_inv is used in 14/ds2 (<a href="14-ds2.html#SP11_9_1_1">&#167;11.9.1.1</a>).</p>
<p class="inwebparagraph"><a id="SP5_1"></a><b>&#167;5.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Parse the action in a try phrase</span> <span class="cwebmacronumber">5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">action</span><span class="plain">-</span><span class="identifier">pattern</span><span class="plain">&gt;(</span><span class="identifier">XW</span><span class="plain">))</span>
<span class="identifier">as_parsed</span><span class="plain"> = </span><span class="functiontext">Conditions::new_TEST_ACTION</span><span class="plain">(&lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;, </span><span class="identifier">XW</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">permit_trying_omission</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Parse any other token</span> <span class="cwebmacronumber">5.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_2"></a><b>&#167;5.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Parse any other token</span> <span class="cwebmacronumber">5.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">save_probable_noun_phrase_context</span><span class="plain"> = </span><span class="identifier">probable_noun_phrase_context</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">save_let_equation_mode</span><span class="plain"> = </span><span class="identifier">let_equation_mode</span><span class="plain">;</span>
<span class="identifier">probable_noun_phrase_context</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_kind_like</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">))</span>
<span class="identifier">probable_noun_phrase_context</span><span class="plain"> =</span>
<span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">);</span>
<span class="identifier">let_equation_mode</span><span class="plain"> = </span><span class="functiontext">Phrases::TypeData::is_a_let_equation</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">redundant assignment to keep <code class="display"><span class="extract">gcc</span></code> happy</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">to_match</span><span class="plain">))</span>
<span class="identifier">t</span><span class="plain"> = &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">&gt;(</span><span class="identifier">XW</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cons</span><span class="plain"> == </span><span class="constant">CONDITION_PT_CONSTRUCT</span><span class="plain">)</span>
<span class="identifier">t</span><span class="plain"> = &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">condition</span><span class="plain">&gt;(</span><span class="identifier">XW</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cons</span><span class="plain"> == </span><span class="constant">VOID_PT_CONSTRUCT</span><span class="plain">)</span>
<span class="identifier">t</span><span class="plain"> = &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">command</span><span class="plain">&gt;(</span><span class="identifier">XW</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">t</span><span class="plain"> = &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">&gt;(</span><span class="identifier">XW</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">) </span><span class="identifier">as_parsed</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">as_parsed</span><span class="plain"> = </span><span class="functiontext">Specifications::new_UNKNOWN</span><span class="plain">(</span><span class="identifier">XW</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">MATCHING</span><span class="plain">, </span><span class="string">"(%d/%d) Expected kind $u: parsed token %W (cons %d) to $P\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
<span class="identifier">i</span><span class="plain">+1, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">probable_noun_phrase_context</span><span class="plain">, </span><span class="identifier">XW</span><span class="plain">, </span><span class="identifier">cons</span><span class="plain">, </span><span class="identifier">as_parsed</span><span class="plain">);</span>
<span class="identifier">probable_noun_phrase_context</span><span class="plain"> = </span><span class="identifier">save_probable_noun_phrase_context</span><span class="plain">;</span>
<span class="identifier">let_equation_mode</span><span class="plain"> = </span><span class="identifier">save_let_equation_mode</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>, <a href="#SP5_1">&#167;5.1</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="25-in.html">Back to 'Invocations'</a></li><li><a href="25-ci.html">Continue with 'Compile Invocations'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>