1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/core-module/10-cad.html
2019-04-22 15:42:10 +01:00

904 lines
105 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>10/pl</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 '10/cad' 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#10">Chapter 10: The S-Parser</a></li><li><b>Constants and Descriptions</b></li></ul><p class="purpose">To parse noun phrases in constant contexts, which specify values either explicitly or by describing them more or less vaguely.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Constant values</a></li><li><a href="#SP8">&#167;8. Adjective lists</a></li><li><a href="#SP19">&#167;19. Descriptions</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Constant values. </b>As we've seen, not all of the names Inform knows are literals. The following
nonterminal covers constants in general, a wider category.
</p>
<p class="inwebparagraph">The word "nothing" needs special treatment later on. Sometimes it means
the dummy value "not an object", and is genuinely a constant value;
but at other times it behaves more like a determiner, as in "if nothing
is on the table". For now, though, we treat it as a noun.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">constant</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="identifier">nothing</span><span class="plain"> | ==&gt; </span><span class="functiontext">Rvalues::new_nothing_object_constant</span><span class="plain">();</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">miscellaneous</span><span class="plain">-</span><span class="identifier">proper</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">outcome</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; </span><span class="identifier">outcome</span><span class="plain"> | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">use</span><span class="plain">-</span><span class="identifier">option</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; </span><span class="identifier">option</span><span class="plain"> | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="identifier">verb</span><span class="plain"> &lt;</span><span class="reserved">instance</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="identifier">verb</span><span class="plain">&gt; | ==&gt; </span>&lt;<span class="cwebmacro">Compose verb ML</span> <span class="cwebmacronumber">1.1</span>&gt;
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; </span><span class="identifier">response</span><span class="plain"> ( &lt;</span><span class="identifier">response</span><span class="plain">-</span><span class="identifier">letter</span><span class="plain">&gt; ) ==&gt; </span>&lt;<span class="cwebmacro">Compose response ML</span> <span class="cwebmacronumber">1.2</span>&gt;
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP1_1"></a><b>&#167;1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compose verb ML</span> <span class="cwebmacronumber">1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">verb_form</span><span class="plain"> *</span><span class="identifier">vf</span><span class="plain"> = (</span><span class="identifier">verb_form</span><span class="plain"> *) (</span><span class="identifier">RP</span><span class="plain">[1]);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="functiontext">Rvalues::from_verb_form</span><span class="plain">(</span><span class="identifier">vf</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">spec</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP1_2"></a><b>&#167;1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compose response ML</span> <span class="cwebmacronumber">1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1];</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_response</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">response_code_ANNOT</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">[2]);</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">spec</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Screening for this saves time.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">CONSTANT_VAL_BITMAP</span><span class="plain"> (</span><span class="constant">RULE_MC</span><span class="plain"> + </span><span class="constant">RULEBOOK_MC</span><span class="plain"> + </span><span class="constant">NAMED_CONSTANT_MC</span><span class="plain"> + </span><span class="constant">ACTIVITY_MC</span><span class="plain"> +</span>
<span class="constant">TABLE_MC</span><span class="plain"> + </span><span class="constant">EQUATION_MC</span><span class="plain"> + </span><span class="constant">PHRASE_CONSTANT_MC</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>To be a little less vague, the "miscellaneous proper nouns" are: rule
and rulebook names; action names, as nouns; relation names; instances of
kinds; activity names; table names; equation names; and names of phrases
being used as nouns for functional-programming purposes.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">miscellaneous</span><span class="plain">-</span><span class="identifier">proper</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; </span><span class="identifier">internal</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="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="identifier">MISCELLANEOUS_MC</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">p</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Rvalues::is_CONSTANT_of_kind</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">K_action_name</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">CON_relation</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">CON_rule</span><span class="plain">))) {</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">p</span><span class="plain"> = </span><span class="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="constant">VARIABLE_MC</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">p</span><span class="plain">) {</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="functiontext">Lvalues::get_nonlocal_variable_if_any</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="functiontext">NonlocalVariables::is_constant</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">)) {</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Vocabulary::disjunction_of_flags</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) &amp; </span><span class="constant">CONSTANT_VAL_BITMAP</span><span class="plain">) {</span>
<span class="identifier">p</span><span class="plain"> = </span><span class="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="constant">CONSTANT_VAL_BITMAP</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">p</span><span class="plain">) { *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">; }</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Named constants are handled separately.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">named</span><span class="plain">-</span><span class="identifier">constant</span><span class="plain">&gt; </span><span class="identifier">internal</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="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="constant">VARIABLE_MC</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">p</span><span class="plain">) {</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="functiontext">Lvalues::get_nonlocal_variable_if_any</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="functiontext">NonlocalVariables::is_constant</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">)) {</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>There's actually nothing special about rulebook outcome names or use option
names; but because they are stored internally without the compulsory words
"outcome" and "option", they need nonterminals of their own.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">outcome</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; </span><span class="identifier">internal</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="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="identifier">MISCELLANEOUS_MC</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="functiontext">Rvalues::is_CONSTANT_of_kind</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">K_rulebook_outcome</span><span class="plain">)) {</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">use</span><span class="plain">-</span><span class="identifier">option</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; </span><span class="identifier">internal</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="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="identifier">MISCELLANEOUS_MC</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="functiontext">Rvalues::is_CONSTANT_of_kind</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">K_use_option</span><span class="plain">)) {</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; </span><span class="identifier">internal</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="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="identifier">MISCELLANEOUS_MC</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="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">CON_rule</span><span class="plain">)) {</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>We will also sometimes need a nonterminal which can only produce table
column names, and similarly for property names. These don't fall under
"miscellaneous proper nouns" above, and they aren't in general valid
as constants.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">column</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; </span><span class="identifier">internal</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="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="constant">TABLE_COLUMN_MC</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">p</span><span class="plain">) { *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">; }</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>In order to resolve a subtle distinction of usage later on, we want not
only to parse a property name but also to record whether it was used in
the explicit syntax ("the property open" rather than "open", say).
The internal &lt;s-property-name&gt; uses &lt;property-name-as-noun-phrase&gt;
to do this.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">as</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">-</span><span class="reserved">phrase</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">definite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">&gt; &lt;</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">construction</span><span class="plain">&gt; |</span>
<span class="plain">&lt;</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">construction</span><span class="plain">&gt;</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; </span><span class="identifier">internal</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="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="constant">PROPERTY_MC</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">p</span><span class="plain">) {</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">as</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">-</span><span class="reserved">phrase</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">))</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">property_name_used_as_noun_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">property_name_used_as_noun_ANNOT</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Adjective lists. </b>"I first tried to write a story when I was about seven. It was about a dragon.
I remember nothing about it except a philological fact. My mother said nothing
about the dragon, but pointed out that one could not say "a green great dragon",
but had to say "a great green dragon". I wondered why, and still do" (Tolkien
to Auden, 1955). We are going to allow lists of adjectives such as "green great"
or "great green" in any order: although some have suggested conceptual
hierarchies for adjectives (e.g., that size always precedes material) these
are too tendentious to enforce.
</p>
<p class="inwebparagraph">The first nonterminal looks quite unnecessary; but it takes the result of
parsing an adjective list and transforms the result to make it a description
(even though there is no actual noun). Inform has to work hard at this sort
of thing, mostly because of deficiencies in English to do with words like
"scenery" and "clothing" which can't be used as count nouns even though,
logically, they should be. Inform implements them adjectivally, but this means
that "scenery" &mdash; an adjective list with one entry &mdash; is sometimes a
description on a par with "door" &mdash; a common noun. In effect, "scenery"
is read as if it were "scenery thing".
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">as</span><span class="plain">-</span><span class="identifier">desc</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; ==&gt; </span><span class="functiontext">ParseTree::AdjectiveLists::add_adjlist</span><span class="plain">(</span><span class="functiontext">Descriptions::from_proposition</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">), </span><span class="identifier">RP</span><span class="plain">[1])</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>So now we test whether an excerpt is a list of adjectives; for example,
this matches
</p>
<blockquote>
<p>exciting transparent green fixed in place</p>
</blockquote>
<p class="inwebparagraph">as a list of four adjectives.
</p>
<p class="inwebparagraph">Perhaps surprisingly, the word "not" is allowed in such lists. Since this
looks as if it negates the verb, it ought to belong to the verb phrase, and
surely doesn't belong to the grammar of nouns and their adjectives. But there
are several problems with that analysis. Firstly, English does strange things
with the placing of "not":
</p>
<blockquote>
<p>The blue door is open and not transparent.</p>
</blockquote>
<blockquote>
<p>A door is usually not open.</p>
</blockquote>
<p class="inwebparagraph">Note that neither of these sentences places "not" adjacent to the verb, so
if we're going to say it's part of the verb phrase then this has to be a
non-contiguous sequence of words able to grab material from possibly distant
NPs. This isn't easy to go along with. Secondly, we also want to provide a
way to write the negation of an adjective. For instance,
</p>
<blockquote>
<p>exciting not transparent fixed in place</p>
</blockquote>
<p class="inwebparagraph">is valid. Though in this case it would be equivalent to write "opaque" in
place of "not transparent", some adjectives do not have named negations.
</p>
<p class="inwebparagraph">The grammar for adjective lists also allows the presence of an indefinite
article, less controversially, but that then leads to an interesting and
very arcane de Morgan-law-like point, affecting only a tiny number of
assertion sentences. If we write:
</p>
<blockquote>
<p>a not great green dragon</p>
</blockquote>
<p class="inwebparagraph">Inform considers that "not" applies only to "great"; the dragon is still
to be green. But if we write
</p>
<blockquote>
<p>not a great green dragon</p>
</blockquote>
<p class="inwebparagraph">then Inform requires it to be neither great nor green. It's terrible style
to write this sort of thing as a description outside of a condition like
the following:
</p>
<blockquote>
<p>if Smaug is not a great green dragon, ...</p>
</blockquote>
<p class="inwebparagraph">and conditions like this are parsed with "is not" as the verb and "great
green dragon" as the description, with the adjective list being just "great
green". So this awkward point about "not a..." only comes in when writing
assertion sentences like:
</p>
<blockquote>
<p>A hairless chimp is not a hairy animal.</p>
</blockquote>
<p class="inwebparagraph">(This was submitted as a bug report.) In assertions, Inform has to know for
definite what the truth is, so it can't afford to read this as saying that
the chimp is either not hairy or not an animal.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; ::=</span>
<span class="identifier">not</span><span class="plain"> &lt;</span><span class="identifier">indefinite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">unarticled</span><span class="plain">&gt; | ==&gt; 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">ParseTree::AdjectiveLists::make_adjlist</span><span class="plain">(</span><span class="functiontext">ParseTree::AdjectiveLists::negate_adjlist</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[2]), </span><span class="identifier">W</span><span class="plain">)</span>
<span class="plain">&lt;</span><span class="identifier">indefinite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">unarticled</span><span class="plain">&gt; | ==&gt; 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">ParseTree::AdjectiveLists::make_adjlist</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[2], </span><span class="identifier">W</span><span class="plain">)</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">unarticled</span><span class="plain">&gt; ==&gt; 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">ParseTree::AdjectiveLists::make_adjlist</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1], </span><span class="identifier">W</span><span class="plain">)</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">unarticled</span><span class="plain">&gt; ::=</span>
<span class="identifier">not</span><span class="plain"> &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">&gt; | ==&gt; 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">ParseTree::AdjectiveLists::negate_adjlist</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1])</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">&gt; | ==&gt; 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="identifier">not</span><span class="plain"> &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">unarticled</span><span class="plain">&gt; | ==&gt; 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">ParseTree::AdjectiveLists::join_adjlist</span><span class="plain">(</span><span class="functiontext">ParseTree::AdjectiveLists::negate_adjlist</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1]), </span><span class="identifier">RP</span><span class="plain">[2])</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">unarticled</span><span class="plain">&gt; ==&gt; 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">ParseTree::AdjectiveLists::join_adjlist</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1], </span><span class="identifier">RP</span><span class="plain">[2])</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>That reduces us to an internal nonterminal, which matches the longest
possible adjective name it can see.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">&gt; </span><span class="identifier">internal</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="identifier">ExParser::parse_excerpt_maximal</span><span class="plain">(</span><span class="identifier">ADJECTIVE_MC</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">p</span><span class="plain">) {</span>
<span class="identifier">adjective_usage</span><span class="plain"> *</span><span class="identifier">ale</span><span class="plain"> = </span><span class="identifier">AdjectiveUsages::new</span><span class="plain">(</span>
<span class="identifier">RETRIEVE_POINTER_adjectival_phrase</span><span class="plain">(</span><span class="identifier">ExcerptMeanings::data</span><span class="plain">(</span><span class="identifier">ParseTree::get_meaning</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">))),</span>
<span class="identifier">TRUE</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">Descriptions::from_proposition</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="functiontext">Descriptions::add_to_adjective_list</span><span class="plain">(</span><span class="identifier">ale</span><span class="plain">, *</span><span class="identifier">XP</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">sc</span><span class="plain"> = </span><span class="identifier">ParseTree::get_score</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">sc</span><span class="plain"> == 0) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Length-scored maximal parse with length 0"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) + </span><span class="identifier">sc</span><span class="plain"> - 1;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b></p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">ParseTree::AdjectiveLists::join_adjlist</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">B</span><span class="plain">) {</span>
<span class="identifier">adjective_usage</span><span class="plain"> *</span><span class="identifier">au</span><span class="plain">;</span>
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">au_prop</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_ADJECTIVE_LIST</span><span class="plain">(</span><span class="identifier">au</span><span class="plain">, </span><span class="identifier">au_prop</span><span class="plain">, </span><span class="identifier">B</span><span class="plain">)</span>
<span class="functiontext">Descriptions::add_to_adjective_list</span><span class="plain">(</span><span class="identifier">AdjectiveUsages::copy</span><span class="plain">(</span><span class="identifier">au</span><span class="plain">), </span><span class="identifier">A</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">A</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">ParseTree::AdjectiveLists::join_adjlist_w</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">B</span><span class="plain">) {</span>
<span class="identifier">adjective_usage</span><span class="plain"> *</span><span class="identifier">au</span><span class="plain">;</span>
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">au_prop</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_ADJECTIVE_LIST</span><span class="plain">(</span><span class="identifier">au</span><span class="plain">, </span><span class="identifier">au_prop</span><span class="plain">, </span><span class="identifier">B</span><span class="plain">)</span>
<span class="functiontext">Descriptions::add_to_adjective_list_w</span><span class="plain">(</span><span class="identifier">AdjectiveUsages::copy</span><span class="plain">(</span><span class="identifier">au</span><span class="plain">), </span><span class="identifier">A</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">A</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">ParseTree::AdjectiveLists::make_adjlist</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">A</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">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">A</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">ParseTree::AdjectiveLists::negate_adjlist</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">) {</span>
<span class="identifier">adjective_usage</span><span class="plain"> *</span><span class="identifier">au</span><span class="plain">;</span>
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">au_prop</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_ADJECTIVE_LIST</span><span class="plain">(</span><span class="identifier">au</span><span class="plain">, </span><span class="identifier">au_prop</span><span class="plain">, </span><span class="identifier">A</span><span class="plain">)</span>
<span class="identifier">AdjectiveUsages::flip_parity</span><span class="plain">(</span><span class="identifier">au</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">A</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::AdjectiveLists::join_adjlist is used in <a href="#SP9">&#167;9</a>, <a href="#SP12">&#167;12</a>.</p>
<p class="endnote">The function ParseTree::AdjectiveLists::join_adjlist_w is used in <a href="#SP12">&#167;12</a>.</p>
<p class="endnote">The function ParseTree::AdjectiveLists::make_adjlist is used in <a href="#SP9">&#167;9</a>.</p>
<p class="endnote">The function ParseTree::AdjectiveLists::negate_adjlist is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b></p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">ParseTree::AdjectiveLists::add_adjlist</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">adjlist</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">adjlist</span><span class="plain">) {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_object_instance</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I</span><span class="plain">) </span><span class="identifier">spec</span><span class="plain"> = </span><span class="functiontext">Descriptions::from_instance</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
<span class="functiontext">ParseTree::AdjectiveLists::join_adjlist</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">adjlist</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">ParseTree::AdjectiveLists::add_adjlist_w</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">adjlist</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">adjlist</span><span class="plain">) {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_object_instance</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I</span><span class="plain">) </span><span class="identifier">spec</span><span class="plain"> = </span><span class="functiontext">Descriptions::from_instance</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
<span class="functiontext">ParseTree::AdjectiveLists::join_adjlist_w</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">adjlist</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::AdjectiveLists::add_adjlist is used in <a href="#SP8">&#167;8</a>, <a href="#SP19">&#167;19</a>, <a href="#SP19_1">&#167;19.1</a>.</p>
<p class="endnote">The function ParseTree::AdjectiveLists::add_adjlist_w is used in <a href="#SP19">&#167;19</a>, <a href="#SP19_1">&#167;19.1</a>.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>And this makes a more semantic check:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">ParseTree::AdjectiveLists::adjlist_applies_to_kind</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="identifier">adjective_usage</span><span class="plain"> *</span><span class="identifier">au</span><span class="plain">;</span>
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">au_prop</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_ADJECTIVE_LIST</span><span class="plain">(</span><span class="identifier">au</span><span class="plain">, </span><span class="identifier">au_prop</span><span class="plain">, </span><span class="identifier">A</span><span class="plain">) {</span>
<span class="identifier">adjectival_phrase</span><span class="plain"> *</span><span class="identifier">aph</span><span class="plain"> = </span><span class="identifier">AdjectiveUsages::get_aph</span><span class="plain">(</span><span class="identifier">au</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Adjectives::Meanings::applicable_to</span><span class="plain">(</span><span class="identifier">aph</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::AdjectiveLists::adjlist_applies_to_kind is used in <a href="#SP18">&#167;18</a>.</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>The following global is needed only to pass a parameter from one Preform token
to another one parsed immediately after it has been matched; it has no
significance the rest of the time.
</p>
<pre class="display">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">s_adj_domain</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>This prevents doubled issue of the same problem message.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PM_DefiniteCommonNoun_issued_at</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PM_SpecificCalling_issued_at</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PM_PastSubordinate_issued_at</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>When they appear in descriptions, these adjectives serve as "qualifiers":
they qualify their nouns. For example, "open door" consists of "open",
a qualifier, followed by "door", a noun.
</p>
<p class="inwebparagraph">Not every value known to Inform can be qualified as a noun: in fact, very few
can be. This prevents us from writing "even 3", that is, the number 3 as
a noun qualified by the adjective "even"; doctrinally, Inform takes the
line that adjectives applied to values like 3 will never vary in their
applicability &mdash; 3 is always odd &mdash; so that it makes no sense to test for
them with conditions like
</p>
<blockquote>
<p>if N is an even 3, ...</p>
</blockquote>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">qualifiable</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">kind</span><span class="plain">&gt; | ==&gt; </span><span class="functiontext">Specifications::from_kind</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1]); </span><span class="identifier">s_adj_domain</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1];</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="reserved">instance</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]; </span><span class="identifier">s_adj_domain</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">qualifiable</span><span class="plain">-</span><span class="identifier">common</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">kind</span><span class="plain">&gt; ==&gt; </span><span class="functiontext">Specifications::from_kind</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1]); </span><span class="identifier">s_adj_domain</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1];</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">qualifiable</span><span class="plain">-</span><span class="identifier">proper</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="reserved">instance</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]; </span><span class="identifier">s_adj_domain</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. </b>&lt;s-instance-name&gt; parses text exactly as if it were &lt;instance-of-object&gt;, but
is just a little faster written as an internal like this.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="reserved">instance</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; </span><span class="identifier">internal</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="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="identifier">NOUN_MC</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">p</span><span class="plain">) {</span>
<span class="identifier">noun</span><span class="plain"> *</span><span class="identifier">nt</span><span class="plain"> = </span><span class="identifier">Nouns::disambiguate</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">MAX_NOUN_PRIORITY</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">nt</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Nouns::priority</span><span class="plain">(</span><span class="identifier">nt</span><span class="plain">) == </span><span class="identifier">LOW_NOUN_PRIORITY</span><span class="plain">)) {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_object_instance</span><span class="plain">(</span>
<span class="identifier">RETRIEVE_POINTER_parse_node</span><span class="plain">(</span><span class="identifier">Nouns::tag_holder</span><span class="plain">(</span><span class="identifier">nt</span><span class="plain">)));</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">Rvalues::from_instance</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">); </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. </b>The following is used only in combination with a qualifiable noun: it
simply provides a filter on &lt;s-adjective-list&gt; to require that each
adjective listed must be one which applies to the noun. For example,
"empty room" won't be parsed as "empty" qualifying "room" because
(perhaps curiously) the Standard Rules don't define "empty" for rooms;
whereas "empty rulebook" will work.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">applicable</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]; </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">s_adj_domain</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">ParseTree::AdjectiveLists::adjlist_applies_to_kind</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1], </span><span class="identifier">s_adj_domain</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. Descriptions. </b>In most programming languages, commands are like imperative verbs, but their
noun phrases are specific. <code class="display"><span class="extract">print X</span></code>, say, prints an unambiguously determined
quantity <code class="display"><span class="extract">X</span></code>. Sometimes wildcards are allowed, as when the Unix shell allows
<code class="display"><span class="extract">ls *.txt</span></code> to list all text files in the current directory. Inform goes
further, and &mdash; in some circumstances at least &mdash; permits the <code class="display"><span class="extract">X</span></code> to be a more
or less vague description of a collection of values, such that only at run-time
can it be determined what values <code class="display"><span class="extract">X</span></code> refers to.
</p>
<p class="inwebparagraph">It might look as if a description is a generalisation of a value: that is,
every value is a description. In fact, that isn't true, because the noun part
of a description has to be "qualifiable" in the sense above: so "100", for
instance, is a value but not a description.
</p>
<p class="inwebparagraph">Grammatically, a description is a sequence of the following five elements, some
of which are optional:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) specifier, which will be a determiner and/or an article (optional);
</li></ul>
<ul class="items"><li>(b) qualifier, which for Inform means adjectives of the various kinds
described above (optional);
</li></ul>
<ul class="items"><li>(c) qualifiable noun (sometimes optional, sometimes compulsory); and
</li></ul>
<ul class="items"><li>(d) subordinate clause, such as "in ..." or "which are on ..."
(optional).
</li></ul>
<p class="inwebparagraph">For the most part the sequence must be (a), (b), (c), (d), as in:
</p>
<blockquote>
<p>six of the / open / containers / in the Attic</p>
</blockquote>
<p class="inwebparagraph">but the composite words made up from quantifiers and kinds &mdash; something,
anywhere, everybody, and such &mdash; force us to make an exception to this:
</p>
<blockquote>
<p>something / open / in the Attic</p>
</blockquote>
<p class="inwebparagraph">which takes the sequence (a) and (c), (b), (d). We will call words like
"something" and "everywhere" specifying nouns, since they are both
noun and specifier in one.
</p>
<p class="inwebparagraph">Simpler readings beat more complicated ones. Thus we won't match a
subordinate clause if there's a way to read the text which doesn't need to;
and similarly for specifiers.
</p>
<p class="inwebparagraph">In cases of ambiguity, the earliest split wins: that is, the one
maximising the length of the noun. This means that if the source text
actually names a dark room, the text "dark room" will not be confused
with "dark (i.e., the property) room (i.e, the kind)", since that
splits later.
</p>
<p class="inwebparagraph">In the grammar for &lt;s-description&gt;, the noun is compulsory.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">uncomposite</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">np</span><span class="plain">-</span><span class="identifier">with</span><span class="plain">-</span><span class="identifier">relative</span><span class="plain">-</span><span class="identifier">clause</span><span class="plain">&gt; ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">uncomposite</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">uncomposite</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">&gt; ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">uncomposite</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">uncalled</span><span class="plain">&gt; ( </span><span class="identifier">called</span><span class="plain"> &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">calling</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; ) | ==&gt; </span>&lt;<span class="cwebmacro">Glue on the calling ML</span> <span class="cwebmacronumber">19.2</span>&gt;
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">uncalled</span><span class="plain">&gt; ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">uncalled</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">specifier</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; | ==&gt; </span>&lt;<span class="cwebmacro">Glue on the quantification ML</span> <span class="cwebmacronumber">19.3</span>&gt;
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">specifying</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">specifying</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; | ==&gt; </span><span class="functiontext">ParseTree::AdjectiveLists::add_adjlist_w</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1], </span><span class="identifier">RP</span><span class="plain">[2])</span>
<span class="plain">&lt;</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">trying</span><span class="plain">-</span><span class="identifier">omission</span><span class="plain">-</span><span class="identifier">permitted</span><span class="plain">&gt; &lt;</span><span class="identifier">definite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">common</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[3]</span>
<span class="plain">^&lt;</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">trying</span><span class="plain">-</span><span class="identifier">omission</span><span class="plain">-</span><span class="identifier">permitted</span><span class="plain">&gt; ^&lt;</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">multiplicitous</span><span class="plain">&gt; &lt;</span><span class="identifier">definite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">common</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_DefiniteCommonNoun problem</span> <span class="cwebmacronumber">19.4</span>&gt;
<span class="plain">&lt;</span><span class="identifier">definite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">proper</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[2]</span>
<span class="plain">&lt;</span><span class="identifier">indefinite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[2]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">qualifiable</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">applicable</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">qualifiable</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; ==&gt; </span><span class="functiontext">ParseTree::AdjectiveLists::add_adjlist</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[2], </span><span class="identifier">RP</span><span class="plain">[1])</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">common</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">qualifiable</span><span class="plain">-</span><span class="identifier">common</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">applicable</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">qualifiable</span><span class="plain">-</span><span class="identifier">common</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; ==&gt; </span><span class="functiontext">ParseTree::AdjectiveLists::add_adjlist</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[2], </span><span class="identifier">RP</span><span class="plain">[1])</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">proper</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">qualifiable</span><span class="plain">-</span><span class="identifier">proper</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">applicable</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">qualifiable</span><span class="plain">-</span><span class="identifier">proper</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; ==&gt; </span><span class="functiontext">ParseTree::AdjectiveLists::add_adjlist</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[2], </span><span class="identifier">RP</span><span class="plain">[1])</span>
<span class="plain">&lt;</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">trying</span><span class="plain">-</span><span class="identifier">omission</span><span class="plain">-</span><span class="identifier">permitted</span><span class="plain">&gt; </span><span class="identifier">internal</span><span class="plain"> 0 {</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">permit_trying_omission</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">&lt;</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">multiplicitous</span><span class="plain">&gt; </span><span class="identifier">internal</span><span class="plain"> 0 {</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">-</span><span class="identifier">uncached</span><span class="plain">&gt;-&gt;</span><span class="identifier">multiplicitous</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP19_1"></a><b>&#167;19.1. </b>The grammar for &lt;s-description-nounless&gt; is almost exactly the same
except that the noun is optional. The only difference is right at the bottom.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">nounless</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">nounless</span><span class="plain">-</span><span class="identifier">uncomposite</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">np</span><span class="plain">-</span><span class="identifier">with</span><span class="plain">-</span><span class="identifier">relative</span><span class="plain">-</span><span class="identifier">clause</span><span class="plain">&gt; ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">nounless</span><span class="plain">-</span><span class="identifier">uncomposite</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">nounless</span><span class="plain">-</span><span class="identifier">uncalled</span><span class="plain">&gt; ( </span><span class="identifier">called</span><span class="plain"> &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">calling</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; ) | ==&gt; </span>&lt;<span class="cwebmacro">Glue on the calling ML</span> <span class="cwebmacronumber">19.2</span>&gt;
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">nounless</span><span class="plain">-</span><span class="identifier">uncalled</span><span class="plain">&gt; ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">nounless</span><span class="plain">-</span><span class="identifier">uncalled</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">specifier</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">nounless</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; | ==&gt; </span>&lt;<span class="cwebmacro">Glue on the quantification ML</span> <span class="cwebmacronumber">19.3</span>&gt;
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">specifying</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">specifying</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; | ==&gt; </span><span class="functiontext">ParseTree::AdjectiveLists::add_adjlist_w</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1], </span><span class="identifier">RP</span><span class="plain">[2])</span>
<span class="plain">&lt;</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">trying</span><span class="plain">-</span><span class="identifier">omission</span><span class="plain">-</span><span class="identifier">permitted</span><span class="plain">&gt; &lt;</span><span class="identifier">definite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">common</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[3]</span>
<span class="plain">^&lt;</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">trying</span><span class="plain">-</span><span class="identifier">omission</span><span class="plain">-</span><span class="identifier">permitted</span><span class="plain">&gt; ^&lt;</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">multiplicitous</span><span class="plain">&gt; &lt;</span><span class="identifier">definite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">common</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_DefiniteCommonNoun problem</span> <span class="cwebmacronumber">19.4</span>&gt;
<span class="plain">&lt;</span><span class="identifier">indefinite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">nounless</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[2]</span>
<span class="plain">&lt;</span><span class="identifier">definite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">proper</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[2]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">nounless</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">-</span><span class="identifier">nounless</span><span class="plain">-</span><span class="identifier">unspecified</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">qualifiable</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">applicable</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">qualifiable</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; | ==&gt; </span><span class="functiontext">ParseTree::AdjectiveLists::add_adjlist</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[2], </span><span class="identifier">RP</span><span class="plain">[1])</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">adjective</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; ==&gt; </span><span class="functiontext">ParseTree::AdjectiveLists::add_adjlist</span><span class="plain">(</span><span class="functiontext">Descriptions::from_proposition</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">), </span><span class="identifier">RP</span><span class="plain">[1])</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP19_2"></a><b>&#167;19.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Glue on the calling ML</span> <span class="cwebmacronumber">19.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1];</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[2];</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PM_SpecificCalling_issued_at</span><span class="plain"> != </span><span class="identifier">current_sentence</span><span class="plain">) {</span>
<span class="identifier">PM_SpecificCalling_issued_at</span><span class="plain"> = </span><span class="identifier">current_sentence</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_SpecificCalling</span><span class="plain">),</span>
<span class="string">"a 'called' name can only be given to something "</span>
<span class="string">"which is described vaguely"</span><span class="plain">,</span>
<span class="string">"and can't be given to a definite object or value. "</span>
<span class="string">"So 'if a thing (called the gadget) is carried' is "</span>
<span class="string">"allowed, but 'if the X-Ray Zapper (called the gadget) "</span>
<span class="string">"is carried' isn't allowed - if it's the X-Ray Zapper, "</span>
<span class="string">"then call it that."</span><span class="plain">);</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="functiontext">Frames::current_stack_frame</span><span class="plain">()) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">C</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">);</span>
<span class="functiontext">Descriptions::attach_calling</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="functiontext">LocalVariables::ensure_called_local</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP19">&#167;19</a>, <a href="#SP19_1">&#167;19.1</a>.</p>
<p class="inwebparagraph"><a id="SP19_3"></a><b>&#167;19.3. </b>Determiners make sense in the context of a common noun, e.g., "three doors",
but not usually for proper nouns ("all 5"). But we allow existence in the
context of a proper noun, as in "some tea", because it may be confusion of
"some" the determiner with "some" the indefinite article.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Glue on the quantification ML</span> <span class="cwebmacronumber">19.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[2];</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">annotation</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1];</span>
<span class="identifier">quantifier</span><span class="plain"> *</span><span class="identifier">quant</span><span class="plain"> = </span><span class="identifier">ParseTree::get_quant</span><span class="plain">(</span><span class="identifier">annotation</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">quant</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">p</span><span class="plain">)) {</span>
<span class="functiontext">Descriptions::quantify</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">,</span>
<span class="identifier">quant</span><span class="plain">, </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">annotation</span><span class="plain">, </span><span class="constant">quantification_parameter_ANNOT</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">quant</span><span class="plain"> == </span><span class="identifier">exists_quantifier</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">))))</span>
<span class="identifier">p</span><span class="plain"> = </span><span class="functiontext">Specifications::new_UNKNOWN</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP19">&#167;19</a>, <a href="#SP19_1">&#167;19.1</a>.</p>
<p class="inwebparagraph"><a id="SP19_4"></a><b>&#167;19.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_DefiniteCommonNoun problem</span> <span class="cwebmacronumber">19.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[4];</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">PM_DefiniteCommonNoun_issued_at</span><span class="plain"> != </span><span class="identifier">current_sentence</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">PM_DefiniteCommonNoun_issued_at</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) {</span>
<span class="identifier">PM_DefiniteCommonNoun_issued_at</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DefiniteCommonNoun</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In %1, I'm not able to understand what specific thing is meant "</span>
<span class="string">"by the phrase '%2'. You use the definite article 'the', which "</span>
<span class="string">"suggests you have a particular thing in mind, but then you go "</span>
<span class="string">"on to refer to a kind rather than something definite. Quite "</span>
<span class="string">"likely a human reading this sentence would find it obvious what "</span>
<span class="string">"you mean, but I don't. %P"</span>
<span class="string">"This often arises when writing something like: 'Instead of "</span>
<span class="string">"opening a door when the door is closed' - where clearly a human "</span>
<span class="string">"would understand that 'the door' refers to the same one in 'a "</span>
<span class="string">"door' earlier. I can make sense of this only if you help: for "</span>
<span class="string">"example, 'Instead of opening a door (called the portal) when "</span>
<span class="string">"the portal is closed' would work. So would 'Instead of opening "</span>
<span class="string">"a closed door'; or 'Instead of opening a door which is closed'. "</span>
<span class="string">"All of these alternatives help me by making clear that only one "</span>
<span class="string">"door is being talked about."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP19">&#167;19</a>, <a href="#SP19_1">&#167;19.1</a>.</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. </b>This simply wraps up a calling name into S-grammar form.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">calling</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">article</span><span class="plain">&gt; ... | ==&gt; </span><span class="identifier">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">UNKNOWN_NT</span><span class="plain">, </span><span class="identifier">WR</span><span class="plain">[1])</span>
<span class="plain">... ==&gt; </span><span class="identifier">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">UNKNOWN_NT</span><span class="plain">, </span><span class="identifier">WR</span><span class="plain">[1])</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. </b>The following is written as an internal, voracious nonterminal for speed.
It matches text like
</p>
<blockquote>
<p>all</p>
</blockquote>
<blockquote>
<p>six of the</p>
</blockquote>
<blockquote>
<p>most</p>
</blockquote>
<p class="inwebparagraph">and so on. Note that an article can follow a determiner, as in "six of the
people", where "six of" is a determiner. At this point we don't need to
notice whether the article is definite or not, and we're similarly turning a
blind eye to singular vs plural.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">specifier</span><span class="plain">&gt; </span><span class="identifier">internal</span><span class="plain"> ? {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">which_N</span><span class="plain"> = -1; </span><span class="identifier">quantifier</span><span class="plain"> *</span><span class="identifier">quantifier_used</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">x1</span><span class="plain"> = </span><span class="identifier">Quantifiers::parse_against_text</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, &amp;</span><span class="identifier">which_N</span><span class="plain">, &amp;</span><span class="identifier">quantifier_used</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">x1</span><span class="plain"> &gt;= 0) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">x1</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">Preform::test_word</span><span class="plain">(</span><span class="identifier">x1</span><span class="plain">, &lt;</span><span class="identifier">article</span><span class="plain">&gt;))) </span><span class="identifier">x1</span><span class="plain">++;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">qp</span><span class="plain"> = </span><span class="functiontext">Specifications::new_UNKNOWN</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">x1</span><span class="plain">-1));</span>
<span class="identifier">ParseTree::set_quant</span><span class="plain">(</span><span class="identifier">qp</span><span class="plain">, </span><span class="identifier">quantifier_used</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">qp</span><span class="plain">, </span><span class="constant">quantification_parameter_ANNOT</span><span class="plain">, </span><span class="identifier">which_N</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">qp</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">x1</span><span class="plain">-1;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. </b>Similarly, this nonterminal matches specifying nouns like "somebody" or
"everywhere". Doctrinally, "something" is not taken to refer explicitly
to the kind "thing", whereas "somebody" does refer to people and
"everywhere" to places: English is slippery on this.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">specifying</span><span class="plain">-</span><span class="identifier">noun</span><span class="plain">&gt; </span><span class="identifier">internal</span><span class="plain"> ? {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">DW</span><span class="plain"> = </span><span class="identifier">Wordings::first_word</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">quantifier</span><span class="plain"> *</span><span class="identifier">quantifier_used</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">some_kind</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="functiontext">Plugins::Call::parse_composite_NQs</span><span class="plain">(&amp;</span><span class="identifier">W</span><span class="plain">, &amp;</span><span class="identifier">DW</span><span class="plain">, &amp;</span><span class="identifier">quantifier_used</span><span class="plain">, &amp;</span><span class="identifier">some_kind</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">some_kind</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="functiontext">Descriptions::from_kind</span><span class="plain">(</span><span class="identifier">some_kind</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">quantifier_used</span><span class="plain">)</span>
<span class="functiontext">Descriptions::quantify</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">quantifier_used</span><span class="plain">, -1);</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) - 1;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<hr class="tocbar">
<ul class="toc"><li><a href="10-pl.html">Back to 'Parse Literals'</a></li><li><a href="10-teav.html">Continue with 'Type Expressions and Values'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>