mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 14:04:24 +03:00
447 lines
47 KiB
HTML
447 lines
47 KiB
HTML
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>5/ps2</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 '6/st' generated by 7-->
|
||
|
<ul class="crumbs"><li><a href="../webs.html">★</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#6">Chapter 6: Handling Inform Source Text</a></li><li><b>Source Text</b></li></ul><p class="purpose">Code for reading Inform 7 source text, which Inbuild uses for both extensions and projects.</p>
|
||
|
|
||
|
<ul class="toc"><li><a href="#SP10">§10. Sentence division</a></li></ul><hr class="tocbar">
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. </b>This short function is a bridge to the lexer, and is used for reading
|
||
|
text files of source into either projects or extensions. Note that it
|
||
|
doesn't attach the fed text to the copy: the copy may need to contain text
|
||
|
from multiple files and indeed from elsewhere.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">currently_lexing_into</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
||
|
|
||
|
<span class="identifier">source_file</span><span class="plain"> *</span><span class="functiontext">SourceText::read_file</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">synopsis</span><span class="plain">,</span>
|
||
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">documentation_only</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">primary</span><span class="plain">) {</span>
|
||
|
<span class="identifier">currently_lexing_into</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">;</span>
|
||
|
<span class="identifier">general_pointer</span><span class="plain"> </span><span class="identifier">ref</span><span class="plain"> = </span><span class="identifier">STORE_POINTER_inbuild_copy</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
|
||
|
<span class="reserved">FILE</span><span class="plain"> *</span><span class="identifier">handle</span><span class="plain"> = </span><span class="identifier">Filenames::fopen</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="string">"r"</span><span class="plain">);</span>
|
||
|
<span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">sf</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">handle</span><span class="plain">) {</span>
|
||
|
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">leaf</span><span class="plain"> = </span><span class="identifier">Filenames::get_leafname</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">);</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">primary</span><span class="plain">) </span><span class="identifier">leaf</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"main source text"</span><span class="plain">;</span>
|
||
|
<span class="identifier">sf</span><span class="plain"> = </span><span class="identifier">TextFromFiles::feed_open_file_into_lexer</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">handle</span><span class="plain">,</span>
|
||
|
<span class="identifier">leaf</span><span class="plain">, </span><span class="identifier">documentation_only</span><span class="plain">, </span><span class="identifier">ref</span><span class="plain">);</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
||
|
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Copies::new_error_on_file</span><span class="plain">(</span><span class="constant">OPEN_FAILED_CE</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">));</span>
|
||
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
||
|
<span class="identifier">fclose</span><span class="plain">(</span><span class="identifier">handle</span><span class="plain">);</span>
|
||
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">documentation_only</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><<span class="cwebmacro">Tell console output about the file</span> <span class="cwebmacronumber">1.1</span>><span class="plain">;</span>
|
||
|
<span class="plain">#</span><span class="identifier">endif</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="identifier">currently_lexing_into</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
||
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sf</span><span class="plain">;</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function SourceText::read_file is used in 5/es (<a href="5-es.html#SP5">§5</a>), 5/ps (<a href="5-ps.html#SP4">§4</a>).</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP1_1"></a><b>§1.1. </b>This is where messages like
|
||
|
</p>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="plain">I've also read Standard Rules by Graham Nelson, which is 27204 words long.</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph">are printed to <code class="display"><span class="extract">stdout</span></code> (not <code class="display"><span class="extract">stderr</span></code>), in something of an affectionate nod
|
||
|
to TeX's traditional console output, though occasionally I think silence is
|
||
|
golden and that these messages could go. It's a moot point for almost all users,
|
||
|
though, because the console output is concealed from them by the Inform
|
||
|
application.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<p class="macrodefinition"><code class="display">
|
||
|
<<span class="cwebmacrodefn">Tell console output about the file</span> <span class="cwebmacronumber">1.1</span>> =
|
||
|
</code></p>
|
||
|
|
||
|
|
||
|
<pre class="displaydefn">
|
||
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">wc</span><span class="plain">;</span>
|
||
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">;</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">primary</span><span class="plain">) </span><span class="identifier">message</span><span class="plain"> = </span><span class="string">"I've now read %S, which is %d words long.\</span><span class="plain">n</span><span class="string">"</span><span class="plain">;</span>
|
||
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">message</span><span class="plain"> = </span><span class="string">"I've also read %S, which is %d words long.\</span><span class="plain">n</span><span class="string">"</span><span class="plain">;</span>
|
||
|
<span class="identifier">wc</span><span class="plain"> = </span><span class="identifier">TextFromFiles::total_word_count</span><span class="plain">(</span><span class="identifier">sf</span><span class="plain">);</span>
|
||
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="identifier">message</span><span class="plain">, </span><span class="identifier">synopsis</span><span class="plain">, </span><span class="identifier">wc</span><span class="plain">);</span>
|
||
|
<span class="identifier">STREAM_FLUSH</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">);</span>
|
||
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="identifier">message</span><span class="plain">, </span><span class="identifier">synopsis</span><span class="plain">, </span><span class="identifier">wc</span><span class="plain">);</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">This code is used in <a href="#SP1">§1</a>.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b></p>
|
||
|
|
||
|
|
||
|
<pre class="definitions">
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">LEXER_PROBLEM_HANDLER</span><span class="plain"> </span><span class="functiontext">SourceText::lexer_problem_handler</span>
|
||
|
</pre>
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceText::lexer_problem_handler</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">err</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">desc</span><span class="plain">, </span><span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">word</span><span class="plain">) {</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">err</span><span class="plain"> == </span><span class="identifier">MEMORY_OUT_LEXERERROR</span><span class="plain">)</span>
|
||
|
<span class="identifier">Errors::fatal</span><span class="plain">(</span><span class="string">"Out of memory: unable to create lexer workspace"</span><span class="plain">);</span>
|
||
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">);</span>
|
||
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">err</span><span class="plain">) {</span>
|
||
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">STRING_TOO_LONG_LEXERERROR</span><span class="plain">:</span>
|
||
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"Too much text in quotation marks: %w"</span><span class="plain">, </span><span class="identifier">word</span><span class="plain">);</span>
|
||
|
<span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">WORD_TOO_LONG_LEXERERROR</span><span class="plain">:</span>
|
||
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"Word too long: %w"</span><span class="plain">, </span><span class="identifier">word</span><span class="plain">);</span>
|
||
|
<span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">I6_TOO_LONG_LEXERERROR</span><span class="plain">:</span>
|
||
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"I6 inclusion too long: %w"</span><span class="plain">, </span><span class="identifier">word</span><span class="plain">);</span>
|
||
|
<span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">STRING_NEVER_ENDS_LEXERERROR</span><span class="plain">:</span>
|
||
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"Quoted text never ends: %S"</span><span class="plain">, </span><span class="identifier">desc</span><span class="plain">);</span>
|
||
|
<span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">COMMENT_NEVER_ENDS_LEXERERROR</span><span class="plain">:</span>
|
||
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"Square-bracketed text never ends: %S"</span><span class="plain">, </span><span class="identifier">desc</span><span class="plain">);</span>
|
||
|
<span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">I6_NEVER_ENDS_LEXERERROR</span><span class="plain">:</span>
|
||
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"I6 inclusion text never ends: %S"</span><span class="plain">, </span><span class="identifier">desc</span><span class="plain">);</span>
|
||
|
<span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="reserved">default</span><span class="plain">:</span>
|
||
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unknown lexer error"</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">currently_lexing_into</span><span class="plain">) {</span>
|
||
|
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">LEXER_CE</span><span class="plain">, </span><span class="identifier">erm</span><span class="plain">);</span>
|
||
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>error_subcategory</span><span class="plain"> = </span><span class="identifier">err</span><span class="plain">;</span>
|
||
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">desc</span><span class="plain">);</span>
|
||
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>word</span><span class="plain"> = </span><span class="identifier">word</span><span class="plain">;</span>
|
||
|
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">currently_lexing_into</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function SourceText::lexer_problem_handler appears nowhere else.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b></p>
|
||
|
|
||
|
|
||
|
<pre class="definitions">
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">COPY_FILE_TYPE</span><span class="plain"> </span><span class="reserved">inbuild_copy</span>
|
||
|
</pre>
|
||
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b></p>
|
||
|
|
||
|
|
||
|
<pre class="definitions">
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">SYNTAX_PROBLEM_HANDLER</span><span class="plain"> </span><span class="functiontext">SourceText::syntax_problem_handler</span>
|
||
|
</pre>
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceText::syntax_problem_handler</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">err_no</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="reserved">void</span><span class="plain"> *</span><span class="identifier">ref</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">) {</span>
|
||
|
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = (</span><span class="reserved">inbuild_copy</span><span class="plain"> *) </span><span class="identifier">ref</span><span class="plain">;</span>
|
||
|
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
||
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>error_subcategory</span><span class="plain"> = </span><span class="identifier">err_no</span><span class="plain">;</span>
|
||
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details_W</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
|
||
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details_N</span><span class="plain"> = </span><span class="identifier">k</span><span class="plain">;</span>
|
||
|
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function SourceText::syntax_problem_handler appears nowhere else.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>Sentences in the source text are of five categories: dividing sentences,
|
||
|
which divide up the source into segments; structural sentences, which split
|
||
|
the source into different forms (standard text, tables, equations, I6 matter,
|
||
|
and so on); nonstructural sentences, which make grammatical definitions and
|
||
|
give Inform other more or less direct instructions; rule declarations; and
|
||
|
regular sentences, those which use the standard verbs. Examples:
|
||
|
</p>
|
||
|
|
||
|
<blockquote>
|
||
|
<p>Volume II [dividing]</p>
|
||
|
|
||
|
</blockquote>
|
||
|
|
||
|
<blockquote>
|
||
|
<p>Include Locksmith by Emily Short [structural]</p>
|
||
|
|
||
|
</blockquote>
|
||
|
|
||
|
<blockquote>
|
||
|
<p>Release along with a website [nonstructural]</p>
|
||
|
|
||
|
</blockquote>
|
||
|
|
||
|
<blockquote>
|
||
|
<p>Instead of looking [rule]</p>
|
||
|
|
||
|
</blockquote>
|
||
|
|
||
|
<blockquote>
|
||
|
<p>The cushion is on the wooden chair [regular]</p>
|
||
|
|
||
|
</blockquote>
|
||
|
|
||
|
<p class="inwebparagraph">Dividing sentences are always read, whereas the others may be skipped in
|
||
|
sections of source not being included for one reason or another. Dividing
|
||
|
sentences must match the following. Note that the extension end markers are
|
||
|
only read in extensions, so they can never accidentally match in the main
|
||
|
source text.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="definitions">
|
||
|
<span class="definitionkeyword">enum</span> <span class="constant">ExtMultipleBeginsHere_SYNERROR</span>
|
||
|
<span class="definitionkeyword">enum</span> <span class="constant">ExtBeginsAfterEndsHere_SYNERROR</span>
|
||
|
<span class="definitionkeyword">enum</span> <span class="constant">ExtEndsWithoutBegins_SYNERROR</span>
|
||
|
<span class="definitionkeyword">enum</span> <span class="constant">ExtMultipleEndsHere_SYNERROR</span>
|
||
|
</pre>
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="plain"><</span><span class="identifier">dividing</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">> ::=</span>
|
||
|
<span class="plain"><</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">start</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="identifier">paragraph</span><span class="plain">> <</span><span class="reserved">heading</span><span class="plain">> | ==> </span><span class="identifier">R</span><span class="plain">[2]</span>
|
||
|
<span class="plain"><</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">end</span><span class="plain">-</span><span class="identifier">marker</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">> ==> </span><span class="identifier">R</span><span class="plain">[1]</span>
|
||
|
|
||
|
<span class="plain"><</span><span class="reserved">heading</span><span class="plain">> ::=</span>
|
||
|
<span class="identifier">volume</span><span class="plain"> ... | ==> 1</span>
|
||
|
<span class="identifier">book</span><span class="plain"> ... | ==> 2</span>
|
||
|
<span class="identifier">part</span><span class="plain"> ... | ==> 3</span>
|
||
|
<span class="identifier">chapter</span><span class="plain"> ... | ==> 4</span>
|
||
|
<span class="identifier">section</span><span class="plain"> ... ==> 5</span>
|
||
|
|
||
|
<span class="plain"><</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">end</span><span class="plain">-</span><span class="identifier">marker</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">> ::=</span>
|
||
|
<span class="plain">... </span><span class="identifier">begin</span><span class="plain">/</span><span class="identifier">begins</span><span class="plain"> </span><span class="identifier">here</span><span class="plain"> | ==> -1; </span><<span class="cwebmacro">Check we can begin an extension here</span> <span class="cwebmacronumber">5.1</span>><span class="plain">;</span>
|
||
|
<span class="plain">... </span><span class="identifier">end</span><span class="plain">/</span><span class="identifier">ends</span><span class="plain"> </span><span class="identifier">here</span><span class="plain"> ==> -2; </span><<span class="cwebmacro">Check we can end an extension here</span> <span class="cwebmacronumber">5.2</span>><span class="plain">;</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP5_1"></a><b>§5.1. </b><code class="display">
|
||
|
<<span class="cwebmacrodefn">Check we can begin an extension here</span> <span class="cwebmacronumber">5.1</span>> =
|
||
|
</code></p>
|
||
|
|
||
|
|
||
|
<pre class="displaydefn">
|
||
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">sfsm_extension_position</span><span class="plain">) {</span>
|
||
|
<span class="reserved">case</span><span class="plain"> 1: </span><span class="identifier">sfsm_extension_position</span><span class="plain">++; </span><span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="reserved">case</span><span class="plain"> 2: </span><span class="constant">SYNTAX_PROBLEM_HANDLER</span><span class="plain">(</span><span class="constant">ExtMultipleBeginsHere_SYNERROR</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">sfsm_copy</span><span class="plain">, 0); </span><span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="reserved">case</span><span class="plain"> 3: </span><span class="constant">SYNTAX_PROBLEM_HANDLER</span><span class="plain">(</span><span class="constant">ExtBeginsAfterEndsHere_SYNERROR</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">sfsm_copy</span><span class="plain">, 0); </span><span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">This code is used in <a href="#SP5">§5</a>.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP5_2"></a><b>§5.2. </b><code class="display">
|
||
|
<<span class="cwebmacrodefn">Check we can end an extension here</span> <span class="cwebmacronumber">5.2</span>> =
|
||
|
</code></p>
|
||
|
|
||
|
|
||
|
<pre class="displaydefn">
|
||
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">sfsm_extension_position</span><span class="plain">) {</span>
|
||
|
<span class="reserved">case</span><span class="plain"> 1: </span><span class="constant">SYNTAX_PROBLEM_HANDLER</span><span class="plain">(</span><span class="constant">ExtEndsWithoutBegins_SYNERROR</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">sfsm_copy</span><span class="plain">, 0); </span><span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="reserved">case</span><span class="plain"> 2: </span><span class="identifier">sfsm_extension_position</span><span class="plain">++; </span><span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="reserved">case</span><span class="plain"> 3: </span><span class="constant">SYNTAX_PROBLEM_HANDLER</span><span class="plain">(</span><span class="constant">ExtMultipleEndsHere_SYNERROR</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">sfsm_copy</span><span class="plain">, 0); </span><span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">This code is used in <a href="#SP5">§5</a>.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP_1"></a><b>§.1. </b><code class="display">
|
||
|
<<span class="cwebmacrodefn">Detect a dividing sentence</span> <span class="cwebmacronumber">.1</span>> =
|
||
|
</code></p>
|
||
|
|
||
|
|
||
|
<pre class="displaydefn">
|
||
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">dividing</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) {</span>
|
||
|
<span class="reserved">switch</span><span class="plain"> (<<</span><span class="identifier">r</span><span class="plain">>>) {</span>
|
||
|
<span class="reserved">case</span><span class="plain"> -1: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sfsm_extension_position</span><span class="plain"> > 0) </span><span class="identifier">begins_or_ends</span><span class="plain"> = 1;</span>
|
||
|
<span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="reserved">case</span><span class="plain"> -2:</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sfsm_extension_position</span><span class="plain"> > 0) </span><span class="identifier">begins_or_ends</span><span class="plain"> = -1;</span>
|
||
|
<span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="reserved">default</span><span class="plain">:</span>
|
||
|
<span class="identifier">heading_level</span><span class="plain"> = <<</span><span class="identifier">r</span><span class="plain">>>;</span>
|
||
|
<span class="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">This code is never used.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>Structural sentences are defined as follows. (The asterisk notation isn't
|
||
|
known to most Inform users: it increases output to the debugging log.)
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="definitions">
|
||
|
<span class="definitionkeyword">enum</span> <span class="constant">BIBLIOGRAPHIC_NT</span><span class="plain"> </span> <span class="comment">For the initial title sentence</span>
|
||
|
<span class="definitionkeyword">enum</span> <span class="constant">ROUTINE_NT</span><span class="plain"> </span> <span class="comment">"Instead of taking something, ..."</span>
|
||
|
<span class="definitionkeyword">enum</span> <span class="constant">INFORM6CODE_NT</span><span class="plain"> </span> <span class="comment">"Include (- ... -)</span>
|
||
|
<span class="definitionkeyword">enum</span> <span class="constant">TABLE_NT</span><span class="plain"> </span> <span class="comment">"Table 1 - Counties of England"</span>
|
||
|
<span class="definitionkeyword">enum</span> <span class="constant">EQUATION_NT</span><span class="plain"> </span> <span class="comment">"Equation 2 - Newton's Second Law"</span>
|
||
|
<span class="definitionkeyword">enum</span> <span class="constant">TRACE_NT</span><span class="plain"> </span> <span class="comment">A sentence consisting of an asterisk and optional quoted text</span>
|
||
|
<span class="definitionkeyword">enum</span> <span class="constant">INVOCATION_LIST_NT</span><span class="plain"> </span> <span class="comment">Single invocation of a (possibly compound) phrase</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">list_node_type</span><span class="plain"> </span><span class="constant">ROUTINE_NT</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">list_entry_node_type</span><span class="plain"> </span><span class="constant">INVOCATION_LIST_NT</span>
|
||
|
</pre>
|
||
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b></p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceText::node_metadata</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
||
|
<span class="identifier">ParseTree::md</span><span class="plain">((</span><span class="identifier">parse_tree_node_type</span><span class="plain">) { </span><span class="constant">BIBLIOGRAPHIC_NT</span><span class="plain">, </span><span class="string">"BIBLIOGRAPHIC_NT"</span><span class="plain">, 0, 0, </span><span class="identifier">L2_NCAT</span><span class="plain">, 0 });</span>
|
||
|
<span class="identifier">ParseTree::md</span><span class="plain">((</span><span class="identifier">parse_tree_node_type</span><span class="plain">) { </span><span class="constant">ROUTINE_NT</span><span class="plain">, </span><span class="string">"ROUTINE_NT"</span><span class="plain">, 0, </span><span class="identifier">INFTY</span><span class="plain">, </span><span class="identifier">L2_NCAT</span><span class="plain">, 0 });</span>
|
||
|
<span class="identifier">ParseTree::md</span><span class="plain">((</span><span class="identifier">parse_tree_node_type</span><span class="plain">) { </span><span class="constant">INFORM6CODE_NT</span><span class="plain">, </span><span class="string">"INFORM6CODE_NT"</span><span class="plain">, 0, 0, </span><span class="identifier">L2_NCAT</span><span class="plain">, 0 });</span>
|
||
|
<span class="identifier">ParseTree::md</span><span class="plain">((</span><span class="identifier">parse_tree_node_type</span><span class="plain">) { </span><span class="constant">TABLE_NT</span><span class="plain">, </span><span class="string">"TABLE_NT"</span><span class="plain">, 0, 0, </span><span class="identifier">L2_NCAT</span><span class="plain">, </span><span class="identifier">TABBED_CONTENT_NFLAG</span><span class="plain"> });</span>
|
||
|
<span class="identifier">ParseTree::md</span><span class="plain">((</span><span class="identifier">parse_tree_node_type</span><span class="plain">) { </span><span class="constant">EQUATION_NT</span><span class="plain">, </span><span class="string">"EQUATION_NT"</span><span class="plain">, 0, 0, </span><span class="identifier">L2_NCAT</span><span class="plain">, 0 });</span>
|
||
|
<span class="identifier">ParseTree::md</span><span class="plain">((</span><span class="identifier">parse_tree_node_type</span><span class="plain">) { </span><span class="constant">TRACE_NT</span><span class="plain">, </span><span class="string">"TRACE_NT"</span><span class="plain">, 0, 0, </span><span class="identifier">L2_NCAT</span><span class="plain">, 0 });</span>
|
||
|
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
|
||
|
<span class="identifier">ParseTree::md</span><span class="plain">((</span><span class="identifier">parse_tree_node_type</span><span class="plain">) { </span><span class="constant">INVOCATION_LIST_NT</span><span class="plain">, </span><span class="string">"INVOCATION_LIST_NT"</span><span class="plain">, 0, </span><span class="identifier">INFTY</span><span class="plain">, </span><span class="identifier">L2_NCAT</span><span class="plain">, 0 });</span>
|
||
|
<span class="plain">#</span><span class="identifier">endif</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function SourceText::node_metadata appears nowhere else.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b></p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="plain"><</span><span class="identifier">structural</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">> ::=</span>
|
||
|
<span class="plain"><</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">start</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="identifier">source</span><span class="plain">-</span><span class="identifier">text</span><span class="plain">> <</span><span class="identifier">quoted</span><span class="plain">-</span><span class="identifier">text</span><span class="plain">> | ==> 0; </span><span class="identifier">ssnt</span><span class="plain"> = </span><span class="constant">BIBLIOGRAPHIC_NT</span><span class="plain">;</span>
|
||
|
<span class="plain"><</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">start</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="identifier">source</span><span class="plain">-</span><span class="identifier">text</span><span class="plain">> <</span><span class="identifier">quoted</span><span class="plain">-</span><span class="identifier">text</span><span class="plain">> ... | ==> 0; </span><span class="identifier">ssnt</span><span class="plain"> = </span><span class="constant">BIBLIOGRAPHIC_NT</span><span class="plain">;</span>
|
||
|
<span class="plain"><</span><span class="identifier">language</span><span class="plain">-</span><span class="identifier">modifying</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">> | ==> </span><span class="identifier">R</span><span class="plain">[1]</span>
|
||
|
<span class="plain">* | ==> 0; </span><span class="identifier">ssnt</span><span class="plain"> = </span><span class="constant">TRACE_NT</span><span class="plain">;</span>
|
||
|
<span class="plain">* <</span><span class="identifier">quoted</span><span class="plain">-</span><span class="identifier">text</span><span class="plain">-</span><span class="identifier">without</span><span class="plain">-</span><span class="identifier">subs</span><span class="plain">> | ==> 0; </span><span class="identifier">ssnt</span><span class="plain"> = </span><span class="constant">TRACE_NT</span><span class="plain">;</span>
|
||
|
<span class="plain"><</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">start</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="identifier">paragraph</span><span class="plain">> </span><span class="identifier">table</span><span class="plain"> ... | ==> 0; </span><span class="identifier">ssnt</span><span class="plain"> = </span><span class="constant">TABLE_NT</span><span class="plain">;</span>
|
||
|
<span class="plain"><</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">start</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="identifier">paragraph</span><span class="plain">> </span><span class="identifier">equation</span><span class="plain"> ... | ==> 0; </span><span class="identifier">ssnt</span><span class="plain"> = </span><span class="constant">EQUATION_NT</span><span class="plain">;</span>
|
||
|
<span class="identifier">include</span><span class="plain"> </span><span class="identifier">the</span><span class="plain"> ... </span><span class="identifier">by</span><span class="plain"> ... | ==> 0; </span><span class="identifier">ssnt</span><span class="plain"> = </span><span class="identifier">INCLUDE_NT</span><span class="plain">;</span>
|
||
|
<span class="identifier">include</span><span class="plain"> ... </span><span class="identifier">by</span><span class="plain"> ... | ==> 0; </span><span class="identifier">ssnt</span><span class="plain"> = </span><span class="identifier">INCLUDE_NT</span><span class="plain">;</span>
|
||
|
<span class="identifier">include</span><span class="plain"> (- ... ==> 0; </span><span class="identifier">ssnt</span><span class="plain"> = </span><span class="constant">INFORM6CODE_NT</span><span class="plain">;</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. </b>Properly speaking, despite the definition above, language modifying sentences
|
||
|
are nonstructural. So what are they doing here? The answer is that we need to
|
||
|
read them early on, because they affect the way that they parse all other
|
||
|
sentences. Whereas other nonstructural sentences can wait, these can't.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="plain"><</span><span class="identifier">language</span><span class="plain">-</span><span class="identifier">modifying</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">> ::=</span>
|
||
|
<span class="identifier">include</span><span class="plain"> (- ### </span><span class="identifier">in</span><span class="plain"> </span><span class="identifier">the</span><span class="plain"> </span><span class="identifier">preform</span><span class="plain"> </span><span class="identifier">grammar</span><span class="plain"> | ==> -2; </span><span class="identifier">ssnt</span><span class="plain"> = </span><span class="constant">INFORM6CODE_NT</span><span class="plain">;</span>
|
||
|
<span class="identifier">use</span><span class="plain"> ... </span><span class="identifier">language</span><span class="plain"> </span><span class="identifier">element</span><span class="plain">/</span><span class="identifier">elements</span><span class="plain"> ==> -1</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. Sentence division. </b>Sentence division can happen either early in Inform's run, when the vast bulk
|
||
|
of the source text is read, or at intermittent periods later when fresh text
|
||
|
is generated internally. New sentences need to be parsed as they arise, not
|
||
|
saved up to be parsed later, so we will use the following:
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="definitions">
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">SENTENCE_ANNOTATION_FUNCTION</span><span class="plain"> </span><span class="functiontext">SourceText::annotate_new_sentence</span>
|
||
|
</pre>
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">text_loaded_from_source</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
||
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceText::declare_source_loaded</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
||
|
<span class="identifier">text_loaded_from_source</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||
|
<span class="plain">}</span>
|
||
|
|
||
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceText::annotate_new_sentence</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">new</span><span class="plain">) {</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">text_loaded_from_source</span><span class="plain">) {</span>
|
||
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">new</span><span class="plain">, </span><span class="identifier">sentence_unparsed_ANNOT</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
||
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
|
||
|
<span class="identifier">Sentences::VPs::seek</span><span class="plain">(</span><span class="identifier">new</span><span class="plain">);</span>
|
||
|
<span class="plain">#</span><span class="identifier">endif</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function SourceText::declare_source_loaded appears nowhere else.</p>
|
||
|
|
||
|
<p class="endnote">The function SourceText::annotate_new_sentence appears nowhere else.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. </b></p>
|
||
|
|
||
|
|
||
|
<pre class="definitions">
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">NEW_BEGINEND_HANDLER</span><span class="plain"> </span><span class="functiontext">SourceText::new_beginend</span>
|
||
|
</pre>
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceText::new_beginend</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">new</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
|
||
|
<span class="reserved">inform_extension</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">ExtensionManager::from_copy</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">new</span><span class="plain">) == </span><span class="identifier">BEGINHERE_NT</span><span class="plain">)</span>
|
||
|
<span class="functiontext">Inclusions::check_begins_here</span><span class="plain">(</span><span class="identifier">new</span><span class="plain">, </span><span class="identifier">E</span><span class="plain">);</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">new</span><span class="plain">) == </span><span class="identifier">ENDHERE_NT</span><span class="plain">)</span>
|
||
|
<span class="functiontext">Inclusions::check_ends_here</span><span class="plain">(</span><span class="identifier">new</span><span class="plain">, </span><span class="identifier">E</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function SourceText::new_beginend appears nowhere else.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. </b></p>
|
||
|
|
||
|
|
||
|
<pre class="definitions">
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">NEW_LANGUAGE_HANDLER</span><span class="plain"> </span><span class="functiontext">SourceText::new_language</span>
|
||
|
<span class="definitionkeyword">enum</span> <span class="constant">UseElementWithdrawn_SYNERROR</span>
|
||
|
</pre>
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceText::new_language</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="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
||
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>error_subcategory</span><span class="plain"> = </span><span class="constant">UseElementWithdrawn_SYNERROR</span><span class="plain">;</span>
|
||
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details_node</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
|
||
|
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">sfsm_copy</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function SourceText::new_language appears nowhere else.</p>
|
||
|
|
||
|
<hr class="tocbar">
|
||
|
<ul class="toc"><li><i>(This section begins Chapter 6: Handling Inform Source Text.)</i></li><li><a href="6-hdn.html">Continue with 'Headings'</a></li></ul><hr class="tocbar">
|
||
|
<!--End of weave-->
|
||
|
</body>
|
||
|
</html>
|
||
|
|