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

106 lines
15 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/np</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 '2/tai' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inflections</a></li><li><a href="index.html#2">Chapter 2: Machinery</a></li><li><b>Tries and Inflections</b></li></ul><p class="purpose">Using tries to inflect word endings.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Suffix inflections</a></li><li><a href="#SP2">&#167;2. General tries</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Suffix inflections. </b>The following inflects the ending of the supplied text. It does so by
running the text through an avinue (a sequence of tries), whose result
is an instruction on how to modify that text: for example, the result
<code class="display"><span class="extract">"3ize"</span></code> tells us to strike out the last 3 characters and add "ize".
The special character <code class="display"><span class="extract">+</span></code> means "duplicate the last character" and
is useful for inflections which double consonants, such as "big" to
"bigger", which can be done with the instruction <code class="display"><span class="extract">"0+er"</span></code>.
</p>
<p class="inwebparagraph">If there's no initial digit, the result replaces the original entirely;
if the result is null, i.e., if the avinue finds nothing, the result is
the same as the original.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Inflections::suffix_inflection</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">match_avinue</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">) {</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">result</span><span class="plain"> = </span><span class="identifier">Tries::search_avinue</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Inflections::follow_suffix_instruction</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">, </span><span class="identifier">result</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Inflections::follow_suffix_instruction</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">, </span><span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">instruction</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">success</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">instruction</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) { </span><span class="identifier">success</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="identifier">instruction</span><span class="plain"> = </span><span class="identifier">L</span><span class="string">"0"</span><span class="plain">; }</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">back</span><span class="plain"> = </span><span class="identifier">instruction</span><span class="plain">[0] - </span><span class="character">'0'</span><span class="plain">;</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">outcome</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">back</span><span class="plain"> &lt; 0) || (</span><span class="identifier">back</span><span class="plain"> &gt; 9)) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">outcome</span><span class="plain">, </span><span class="string">"%w"</span><span class="plain">, </span><span class="identifier">instruction</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = 0, </span><span class="identifier">len</span><span class="plain"> = </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">len</span><span class="plain">-</span><span class="identifier">back</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">outcome</span><span class="plain">, </span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> = 1;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">instruction</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] == </span><span class="character">'+'</span><span class="plain">) { </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">last</span><span class="plain"> = </span><span class="identifier">Str::get_last_char</span><span class="plain">(</span><span class="identifier">outcome</span><span class="plain">); </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">outcome</span><span class="plain">, </span><span class="identifier">last</span><span class="plain">); </span><span class="identifier">j</span><span class="plain">++; }</span>
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">instruction</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]; </span><span class="identifier">j</span><span class="plain">++) </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">outcome</span><span class="plain">, </span><span class="identifier">instruction</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]);</span>
<span class="plain">}</span>
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">outcome</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) == </span><span class="character">'+'</span><span class="plain">) </span><span class="identifier">PUT</span><span class="plain">(</span><span class="character">' '</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">));</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">outcome</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">success</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inflections::suffix_inflection is used in <a href="#SP2">&#167;2</a>, 3/plr (<a href="3-plr.html#SP4">&#167;4</a>), 3/ga (<a href="3-ga.html#SP2">&#167;2</a>, <a href="3-ga.html#SP3">&#167;3</a>), 3/pp (<a href="3-pp.html#SP2">&#167;2</a>).</p>
<p class="endnote">The function Inflections::follow_suffix_instruction is used in 3/dcl (<a href="3-dcl.html#SP3">&#167;3</a>).</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. General tries. </b>Here we take a word assemblage and apply suffix inflection to the first word
alone, preserving the rest. However, if the result of this inflection contains
any <code class="display"><span class="extract">+</span></code> signs, those become word boundaries. This allows for inflections which
do more than simply fiddle with the final letters.
</p>
<pre class="display">
<span class="identifier">word_assemblage</span><span class="plain"> </span><span class="functiontext">Inflections::apply_trie_to_wa</span><span class="plain">(</span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">wa</span><span class="plain">, </span><span class="identifier">match_avinue</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">) {</span>
<span class="identifier">vocabulary_entry</span><span class="plain"> **</span><span class="identifier">words</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_words</span><span class="plain">;</span>
<span class="identifier">WordAssemblages::as_array</span><span class="plain">(&amp;</span><span class="identifier">wa</span><span class="plain">, &amp;</span><span class="identifier">words</span><span class="plain">, &amp;</span><span class="identifier">no_words</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_words</span><span class="plain"> == 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">wa</span><span class="plain">;</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">unsuffixed</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">suffixed</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">unsuffixed</span><span class="plain">, </span><span class="string">"%V"</span><span class="plain">, </span><span class="identifier">words</span><span class="plain">[0]);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">s</span><span class="plain"> = </span><span class="functiontext">Inflections::suffix_inflection</span><span class="plain">(</span><span class="identifier">suffixed</span><span class="plain">, </span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">unsuffixed</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">s</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">unsuffixed</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) == </span><span class="character">'+'</span><span class="plain">) </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">suffixed</span><span class="plain">, </span><span class="character">' '</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">suffixed</span><span class="plain">, </span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">));</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">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">suffixed</span><span class="plain">);</span>
<span class="identifier">WordAssemblages::truncate</span><span class="plain">(&amp;</span><span class="identifier">wa</span><span class="plain">, 1);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">suffixed</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">unsuffixed</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">WordAssemblages::join</span><span class="plain">(</span><span class="identifier">WordAssemblages::from_wording</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">), </span><span class="identifier">wa</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inflections::apply_trie_to_wa is used in 2/nc (<a href="2-nc.html#SP4_1_1">&#167;4.1.1</a>), 3/vc (<a href="3-vc.html#SP4_2_1">&#167;4.2.1</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-np.html">Back to 'Non-Parsing Preform'</a></li><li><a href="2-nc.html">Continue with 'Name Clusters'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>