mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
772 lines
138 KiB
HTML
772 lines
138 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Loading Preform</title>
|
|
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
|
|
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<script>
|
|
function togglePopup(material_id) {
|
|
var popup = document.getElementById(material_id);
|
|
popup.classList.toggle("show");
|
|
}
|
|
</script>
|
|
|
|
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Preform-Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
|
|
</head>
|
|
<body class="commentary-font">
|
|
<nav role="navigation">
|
|
<h1><a href="../index.html">
|
|
<img src="../docs-assets/Inform.png" height=72">
|
|
</a></h1>
|
|
<ul><li><a href="../index.html">home</a></li>
|
|
</ul><h2>Compiler</h2><ul>
|
|
<li><a href="../structure.html">structure</a></li>
|
|
<li><a href="../inbuildn.html">inbuild</a></li>
|
|
<li><a href="../inform7n.html">inform7</a></li>
|
|
<li><a href="../intern.html">inter</a></li>
|
|
<li><a href="../services.html">services</a></li>
|
|
<li><a href="../secrets.html">secrets</a></li>
|
|
</ul><h2>Other Tools</h2><ul>
|
|
<li><a href="../inblorbn.html">inblorb</a></li>
|
|
<li><a href="../indocn.html">indoc</a></li>
|
|
<li><a href="../inform6.html">inform6</a></li>
|
|
<li><a href="../inpolicyn.html">inpolicy</a></li>
|
|
<li><a href="../inrtpsn.html">inrtps</a></li>
|
|
</ul><h2>Resources</h2><ul>
|
|
<li><a href="../extensions.html">extensions</a></li>
|
|
<li><a href="../kits.html">kits</a></li>
|
|
</ul><h2>Repository</h2><ul>
|
|
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
|
|
</ul><h2>Related Projects</h2><ul>
|
|
<li><a href="../../../inweb/docs/index.html">inweb</a></li>
|
|
<li><a href="../../../intest/docs/index.html">intest</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'Loading Preform' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../services.html">Services</a></li><li><a href="index.html">words</a></li><li><a href="index.html#4">Chapter 4: Parsing</a></li><li><b>Loading Preform</b></li></ul></div>
|
|
<p class="purpose">To read in structural definitions of natural language written in the meta-language Preform.</p>
|
|
|
|
<ul class="toc"><li><a href="4-lp.html#SP1">§1. Reading Preform syntax from a file or text</a></li><li><a href="4-lp.html#SP5">§5. Reserved words in Preform</a></li><li><a href="4-lp.html#SP7">§7. Parsing Preform</a></li><li><a href="4-lp.html#SP8">§8. Production lists</a></li><li><a href="4-lp.html#SP11">§11. Productions and ptokens</a></li><li><a href="4-lp.html#SP14">§14. Reading productions</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. Reading Preform syntax from a file or text. </b>The parser reads source text against a specific language only, if
|
|
<span class="extract"><span class="extract-syntax">primary_Preform_language</span></span> is set; or, if it isn't, from any language.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">default</span> <span class="constant-syntax">NATURAL_LANGUAGE_WORDS_TYPE</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="constant-syntax">NATURAL_LANGUAGE_WORDS_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">primary_Preform_language</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LoadPreform::load</span><span class="plain-syntax">(</span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="constant-syntax">NATURAL_LANGUAGE_WORDS_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">primary_Preform_language</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-lp.html#SP7" class="function-link"><span class="function-syntax">LoadPreform::parse</span></a><span class="plain-syntax">(</span><a href="4-lp.html#SP2" class="function-link"><span class="function-syntax">LoadPreform::feed_from_Preform_file</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">), </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. </b>We simply feed the lines one at a time. Preform is parsed with the same
|
|
lexer as is used for Inform itself, but using the following set of characters
|
|
as word-breaking punctuation marks:
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PREFORM_PUNCTUATION_MARKS</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="string-syntax">"{}[]_^?&\\"</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="function-syntax">LoadPreform::feed_from_Preform_file</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">LoadPreform::feed_from_Preform_file</span></span>:<br/><a href="4-lp.html#SP1">§1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">feed_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">id</span><span class="plain-syntax"> = </span><a href="3-fds.html#SP2" class="function-link"><span class="function-syntax">Feeds::begin</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><a href="4-lp.html#SP2" class="function-link"><span class="function-syntax">LoadPreform::load_helper</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Unable to open Preform definition"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-fds.html#SP2" class="function-link"><span class="function-syntax">Feeds::end</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LoadPreform::load_helper</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">item_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">unused_state</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">item_name</span><span class="plain-syntax">, </span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="3-fds.html#SP3" class="function-link"><span class="function-syntax">Feeds::feed_text_punctuated</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">item_name</span><span class="plain-syntax">, </span><span class="constant-syntax">PREFORM_PUNCTUATION_MARKS</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. </b>It is also possible to load additional Preform declarations from source
|
|
text in Inform, and when that happens, the following is called:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LoadPreform::parse_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">wd</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><a href="3-fds.html#SP3" class="function-link"><span class="function-syntax">Feeds::feed_text_punctuated</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wd</span><span class="plain-syntax">, </span><span class="constant-syntax">PREFORM_PUNCTUATION_MARKS</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-lp.html#SP7" class="function-link"><span class="function-syntax">LoadPreform::parse</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">primary_Preform_language</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. </b>Either way, then, all that remains is to write <a href="4-lp.html#SP7" class="internal">LoadPreform::parse</a>. But
|
|
before we can get to that, we have to create the...
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. Reserved words in Preform. </b>The ideal tool with which to parse Preform definitions would be Preform, but
|
|
then how would we define the grammar required? So we will have to do this
|
|
by hand, and in particular, we have to define Preform's syntactic punctuation
|
|
marks explicitly. These are, in effect, the reserved words of the Preform
|
|
notational language. (Note the absence of the <span class="extract"><span class="extract-syntax">==></span></span> marker: that's stripped
|
|
out by <a href="../../../inweb/docs/index.html" class="internal">inweb</a> and never reaches the <span class="extract"><span class="extract-syntax">Syntax.preform</span></span> file.)
|
|
</p>
|
|
|
|
<p class="commentary">The bare letters K and L are snuck in here for convenience. They aren't
|
|
actually used by anything in <a href="index.html" class="internal">words</a>, but are used for kind variables in
|
|
<a href="../kinds-module/index.html" class="internal">kinds</a>.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">AMPERSAND_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">BACKSLASH_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CARET_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">COLONCOLONEQUALS_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">QUESTIONMARK_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">QUOTEQUOTE_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SIXDOTS_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">THREEASTERISKS_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">THREEDOTS_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">THREEHASHES_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">UNDERSCORE_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">language_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">internal_V</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CAPITAL_K_V</span><span class="plain-syntax">;</span>
|
|
<span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CAPITAL_L_V</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LoadPreform::create_punctuation</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">LoadPreform::create_punctuation</span></span>:<br/>Words Module - <a href="1-wm.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">AMPERSAND_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"&"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">BACKSLASH_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"\\"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CARET_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"^"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">COLONCOLONEQUALS_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">":"</span><span class="plain-syntax"> </span><span class="string-syntax">":="</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">QUESTIONMARK_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"?"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">QUOTEQUOTE_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"\"\""</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">SIXDOTS_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"......"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">THREEASTERISKS_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"***"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">THREEDOTS_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"..."</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">THREEHASHES_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"###"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">UNDERSCORE_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"_"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">language_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"language"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"internal"</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CAPITAL_K_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"k"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CAPITAL_L_V</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP15" class="function-link"><span class="function-syntax">Vocabulary::entry_for_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="string-syntax">"l"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. Parsing Preform. </b>The syntax of the <span class="extract"><span class="extract-syntax">Syntax.preform</span></span> is, fortunately, very simple. At any given
|
|
time, we are parsing definitions for a given natural language <span class="extract"><span class="extract-syntax">L</span></span>: for example,
|
|
English.
|
|
</p>
|
|
|
|
<p class="commentary">Note that Preform can contain comments in square brackets; but that the Lexer
|
|
has already removed any such.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LoadPreform::parse</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">LoadPreform::parse</span></span>:<br/><a href="4-lp.html#SP1">§1</a>, <a href="4-lp.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="constant-syntax">NATURAL_LANGUAGE_WORDS_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">NATURAL_LANGUAGE_WORDS_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">current_natural_language</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">declarations</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">) == </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-wrd.html#SP7" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) >= </span><span class="identifier-syntax">wn</span><span class="plain-syntax">+1) && (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">) == </span><span class="identifier-syntax">language_V</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP7_1" class="named-paragraph-link"><span class="named-paragraph">Parse a definition language switch</span><span class="named-paragraph-number">7.1</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-wrd.html#SP7" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) >= </span><span class="identifier-syntax">wn</span><span class="plain-syntax">+1) && (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">+1) == </span><span class="identifier-syntax">internal_V</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP7_2" class="named-paragraph-link"><span class="named-paragraph">Parse an internal nonterminal declaration</span><span class="named-paragraph-number">7.2</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-wrd.html#SP7" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) >= </span><span class="identifier-syntax">wn</span><span class="plain-syntax">+2) && (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">+1) == </span><span class="identifier-syntax">COLONCOLONEQUALS_V</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP7_3" class="named-paragraph-link"><span class="named-paragraph">Parse a regular nonterminal declaration</span><span class="named-paragraph-number">7.3</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="4-pu.html#SP7" class="function-link"><span class="function-syntax">PreformUtilities::production_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"syntax error in Preform declarations"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="4-to.html#SP7" class="function-link"><span class="function-syntax">Optimiser::optimise_counts</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">declarations</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP7_1" class="paragraph-anchor"></a><b>§7.1. </b>We either switch to an existing natural language, or create a new one.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse a definition language switch</span><span class="named-paragraph-number">7.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">lname</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">lname</span><span class="plain-syntax">, </span><span class="string-syntax">"%W"</span><span class="plain-syntax">, </span><a href="3-wrd.html#SP5" class="function-link"><span class="function-syntax">Wordings::one_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">+1));</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">NATURAL_LANGUAGE_WORDS_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PREFORM_LANGUAGE_FROM_NAME_WORDS_CALLBACK</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PREFORM_LANGUAGE_FROM_NAME_WORDS_CALLBACK</span><span class="plain-syntax">(</span><span class="identifier-syntax">lname</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nl</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Missing: %S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">lname</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-pu.html#SP7" class="function-link"><span class="function-syntax">PreformUtilities::production_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"tried to define for missing language"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">lname</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">current_natural_language</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nl</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP7">§7</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP7_2" class="paragraph-anchor"></a><b>§7.2. </b>Internal declarations appear as single lines in <span class="extract"><span class="extract-syntax">Syntax.preform</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse an internal nonterminal declaration</span><span class="named-paragraph-number">7.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax"> = </span><a href="4-nnt.html#SP8" class="function-link"><span class="function-syntax">Nonterminals::find</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">first_pl</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="4-pu.html#SP7" class="function-link"><span class="function-syntax">PreformUtilities::production_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"nonterminal internal in one definition and regular in another"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">marked_internal</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">declarations</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP7">§7</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP7_3" class="paragraph-anchor"></a><b>§7.3. </b>Regular declarations are much longer and continue until the end of the text,
|
|
or until we reach a paragraph break. The body of such a declaration is a list
|
|
of productions divided by stroke symbols.
|
|
</p>
|
|
|
|
<p class="commentary">Note that an empty production is not recorded: e.g., if there are two consecutive
|
|
strokes, the gap between them will not be considered as a production, and the
|
|
second stroke will simply be ignored. I suppose this is arguably a syntax error
|
|
and could be rejected as such, but it does no harm.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse a regular nonterminal declaration</span><span class="named-paragraph-number">7.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax"> = </span><a href="4-nnt.html#SP8" class="function-link"><span class="function-syntax">Nonterminals::find</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">marked_internal</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="4-pu.html#SP7" class="function-link"><span class="function-syntax">PreformUtilities::production_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"nonterminal internal in one definition and regular in another"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><a href="4-lp.html#SP9" class="function-link"><span class="function-syntax">LoadPreform::find_list_for_language</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">current_natural_language</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> += </span><span class="constant-syntax">2</span><span class="plain-syntax">; </span><span class="comment-syntax"> advance past the ID word and the </span><span class="extract"><span class="extract-syntax">::=</span></span><span class="comment-syntax"> word</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax"> = </span><span class="identifier-syntax">wn</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">x</span><span class="plain-syntax"> <= </span><a href="3-wrd.html#SP7" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) && (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">x</span><span class="plain-syntax">) != </span><span class="identifier-syntax">STROKE_V</span><span class="plain-syntax">) &&</span>
|
|
<span class="plain-syntax"> (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">x</span><span class="plain-syntax">) != </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">)) </span><span class="identifier-syntax">x</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> < </span><span class="identifier-syntax">x</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">PW</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP5" class="function-link"><span class="function-syntax">Wordings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">, </span><span class="identifier-syntax">x</span><span class="plain-syntax">-1); </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">x</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="4-lp.html#SP10" class="function-link"><span class="function-syntax">LoadPreform::add_production</span></a><span class="plain-syntax">(</span><a href="4-lp.html#SP14" class="function-link"><span class="function-syntax">LoadPreform::new_production</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PW</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pc</span><span class="plain-syntax">++), </span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> > </span><a href="3-wrd.html#SP7" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) || (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">x</span><span class="plain-syntax">) == </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">)) </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> reached end</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">++; </span><span class="comment-syntax"> advance past the stroke and continue</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">--;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">declarations</span><span class="plain-syntax">++;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP7">§7</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. Production lists. </b>Regular nonterminals are defined by a list of alternative possibilities
|
|
divided by vertical stroke characters; these are called "productions", for
|
|
reasons going back to computer science history.
|
|
</p>
|
|
|
|
<p class="commentary">However, the same nonterminal can have multiple lists, one for each language
|
|
where it's defined: for example, <competitor> could have one English and
|
|
one French definition both in memory at the same time. Each would be an
|
|
independent <a href="4-lp.html#SP8" class="internal">production_list</a> object.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">NATURAL_LANGUAGE_WORDS_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">definition_language</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_pl</span><span class="plain-syntax">; </span><span class="comment-syntax"> in the list of PLs for a NT</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_pr</span><span class="plain-syntax">; </span><span class="comment-syntax"> start of linked list of productions</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">match_avinue</span><span class="plain-syntax"> *</span><span class="identifier-syntax">as_avinue</span><span class="plain-syntax">; </span><span class="comment-syntax"> when compiled to a trie rather than for Preform</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">production_list</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure production_list is accessed in 4/to, 4/le, 4/ni, 4/prf, 4/ins, 4/pu and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="function-syntax">LoadPreform::find_list_for_language</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">LoadPreform::find_list_for_language</span></span>:<br/><a href="4-lp.html#SP7_3">§7.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">NATURAL_LANGUAGE_WORDS_TYPE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">first_pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax">; </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="element-syntax">next_pl</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="element-syntax">definition_language</span><span class="plain-syntax"> == </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">production_list</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="element-syntax">definition_language</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="element-syntax">first_pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="element-syntax">as_avinue</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP9_1" class="named-paragraph-link"><span class="named-paragraph">Place the new production list within the nonterminal</span><span class="named-paragraph-number">9.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP9_1" class="paragraph-anchor"></a><b>§9.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Place the new production list within the nonterminal</span><span class="named-paragraph-number">9.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">first_pl</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="element-syntax">first_pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nt</span><span class="plain-syntax">-></span><span class="identifier-syntax">first_pl</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="element-syntax">next_pl</span><span class="plain-syntax">)) </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="element-syntax">next_pl</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="identifier-syntax">next_pl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP9">§9</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>§10. </b>It is undeniably clumsy that the linked list of PLs, and also of productions
|
|
within each PL, is managed by hand rather than by using <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>. But
|
|
speed is critical when parsing Inform text from these productions, and we want
|
|
to minimise overhead.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LoadPreform::add_production</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">LoadPreform::add_production</span></span>:<br/><a href="4-lp.html#SP7_3">§7.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="reserved-syntax">production_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pl</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="element-syntax">first_pr</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="element-syntax">first_pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pl</span><span class="plain-syntax">-></span><span class="element-syntax">first_pr</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="element-syntax">next_pr</span><span class="plain-syntax">)) </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="element-syntax">next_pr</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-></span><span class="identifier-syntax">next_pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>§11. Productions and ptokens. </b>So now we reach the production, which encodes a typical "row" of grammar:
|
|
for example,
|
|
</p>
|
|
|
|
<pre class="Preform-displayed-code all-displayed-code code-font">
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">runner</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">no</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax"><cardinal-number></span>
|
|
</pre>
|
|
<p class="commentary">is a production. This is implemented as still another list, of "ptokens" (the
|
|
"p" is silent): that example has three ptokens. Note that the stroke sign and
|
|
the defined-by sign are not ptokens; they divide up productions, but aren't
|
|
part of them.
|
|
</p>
|
|
|
|
<p class="commentary"><a href="4-to.html" class="internal">The Optimiser</a> calculates data on productions just as it does on nonterminals.
|
|
For example, it can see that the above can only match a text if it has exactly
|
|
3 words, so it sets both <span class="extract"><span class="Preform-extract-syntax">pr_extremes.min_words</span></span> and <span class="extract"><span class="Preform-extract-syntax">pr_extremes.max_words</span></span> to 3. For the meaning
|
|
of the remaining data, and for what "struts" are, see <a href="4-to.html" class="internal">The Optimiser</a>: it
|
|
only confuses the picture here.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="Preform-constant-syntax">MAX_STRUTS_PER_PRODUCTION</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">10</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_pt</span><span class="plain-syntax">; </span><span class="comment-syntax"> the linked list of ptokens</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">match_number</span><span class="plain-syntax">; </span><span class="comment-syntax"> 0 for </span><span class="extract"><span class="extract-syntax">/a/</span></span><span class="comment-syntax">, 1 for </span><span class="extract"><span class="extract-syntax">/b/</span></span><span class="comment-syntax"> and so on: see </span><a href="4-ap.html" class="internal">About Preform</a>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_ranges</span><span class="plain-syntax">; </span><span class="comment-syntax"> actually one more, since range 0 is reserved</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production_optimisation_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">opt</span><span class="plain-syntax">; </span><span class="comment-syntax"> see </span><a href="4-to.html" class="internal">The Optimiser</a>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production_instrumentation_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">ins</span><span class="plain-syntax">; </span><span class="comment-syntax"> see </span><a href="4-ins.html" class="internal">Instrumentation</a>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_pr</span><span class="plain-syntax">; </span><span class="comment-syntax"> within its production list</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">production</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure production is accessed in 4/nnt, 4/to, 4/le, 4/ni, 4/prf, 4/ins, 4/pu and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>§12. </b>And at the bottom of God's great chain, the lowly ptoken. Even this can spawn
|
|
another list, though: the token <span class="extract"><span class="extract-syntax">fried/green/tomatoes</span></span> is a list of three ptokens
|
|
joined by the <span class="extract"><span class="extract-syntax">alternative_ptoken</span></span> links.
|
|
</p>
|
|
|
|
<p class="commentary">There are really only three kinds of ptoken, wildcards, fixed words, and
|
|
nonterminals, but it's fractionally quicker to differentiate the sorts of
|
|
wildcard here, so we'll actually divide them into five. The remaining wildcard,
|
|
the <span class="extract"><span class="extract-syntax">......</span></span> form of <span class="extract"><span class="extract-syntax">...</span></span>, is represented as <span class="extract"><span class="extract-syntax">MULTIPLE_WILDCARD_PTC</span></span> but with
|
|
the <span class="extract"><span class="extract-syntax">balanced_wildcard</span></span> flag set.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">SINGLE_WILDCARD_PTC</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">MULTIPLE_WILDCARD_PTC</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">POSSIBLY_EMPTY_WILDCARD_PTC</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">NONTERMINAL_PTC</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> How to parse text against this ptoken</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ptoken_category</span><span class="plain-syntax">; </span><span class="comment-syntax"> one of the </span><span class="extract"><span class="extract-syntax">*_PTC</span></span><span class="comment-syntax"> values</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">balanced_wildcard</span><span class="plain-syntax">; </span><span class="comment-syntax"> for </span><span class="extract"><span class="extract-syntax">MULTIPLE_WILDCARD_PTC</span></span><span class="comment-syntax"> ptokens: brackets balanced?</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">negated_ptoken</span><span class="plain-syntax">; </span><span class="comment-syntax"> the </span><span class="extract"><span class="extract-syntax">^</span></span><span class="comment-syntax"> modifier applies</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">disallow_unexpected_upper</span><span class="plain-syntax">; </span><span class="comment-syntax"> the </span><span class="extract"><span class="extract-syntax">_</span></span><span class="comment-syntax"> modifier applies</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt_pt</span><span class="plain-syntax">; </span><span class="comment-syntax"> for </span><span class="extract"><span class="extract-syntax">NONTERMINAL_PTC</span></span><span class="comment-syntax"> ptokens</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve_pt</span><span class="plain-syntax">; </span><span class="comment-syntax"> for </span><span class="extract"><span class="extract-syntax">FIXED_WORD_PTC</span></span><span class="comment-syntax"> ptokens</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alternative_ptoken</span><span class="plain-syntax">; </span><span class="comment-syntax"> linked list of other vocabulary ptokens</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> What results from a successful match against this ptoken</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">result_index</span><span class="plain-syntax">; </span><span class="comment-syntax"> for </span><span class="extract"><span class="extract-syntax">NONTERMINAL_PTC</span></span><span class="comment-syntax"> ptokens: what result number, counting from 1?</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">range_starts</span><span class="plain-syntax">; </span><span class="comment-syntax"> 1, 2, 3, ... if word range 1, 2, 3, ... starts with this</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">range_ends</span><span class="plain-syntax">; </span><span class="comment-syntax"> 1, 2, 3, ... if word range 1, 2, 3, ... ends with this</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">ptoken_optimisation_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">opt</span><span class="plain-syntax">; </span><span class="comment-syntax"> see </span><a href="4-to.html" class="internal">The Optimiser</a>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">ptoken_instrumentation_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">ins</span><span class="plain-syntax">; </span><span class="comment-syntax"> see </span><a href="4-ins.html" class="internal">Instrumentation</a>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_pt</span><span class="plain-syntax">; </span><span class="comment-syntax"> within its production list</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure ptoken is accessed in 4/nnt, 4/to, 4/le, 4/ni, 4/prf, 4/ins, 4/pu and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>§13. </b>Each ptoken has a <span class="extract"><span class="extract-syntax">range_starts</span></span> and <span class="extract"><span class="extract-syntax">range_ends</span></span> number. This is either -1,
|
|
or marks that the ptoken occurs as the first or last in a range (or both). For
|
|
example, in the production
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">make</span><span class="plain-syntax"> ... </span><span class="identifier-syntax">from</span><span class="plain-syntax"> {</span><span class="identifier-syntax">rice</span><span class="plain-syntax"> ... </span><span class="identifier-syntax">onions</span><span class="plain-syntax">} </span><span class="identifier-syntax">and</span><span class="plain-syntax"> </span><span class="identifier-syntax">peppers</span>
|
|
</pre>
|
|
<p class="commentary">the first <span class="extract"><span class="extract-syntax">...</span></span> ptoken has start and end set to 1; <span class="extract"><span class="extract-syntax">rice</span></span> has start 2; <span class="extract"><span class="extract-syntax">onions</span></span>
|
|
has end 2. Note that the second <span class="extract"><span class="extract-syntax">...</span></span>, inside the braces, doesn't start or
|
|
end anything; it normally would, but the wider range consumes it.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>§14. Reading productions. </b>We read the wording <span class="extract"><span class="extract-syntax">W</span></span> of a production for the nonterminal <span class="extract"><span class="extract-syntax">nt</span></span>, with <span class="extract"><span class="extract-syntax">pc</span></span>
|
|
or "production count" being 0 for the first one defined, 1 for the second,
|
|
and so on.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="function-syntax">LoadPreform::new_production</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">LoadPreform::new_production</span></span>:<br/><a href="4-lp.html#SP7_3">§7.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">production</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">match_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax">; </span><span class="comment-syntax"> "production count": 0 for first in defn, and so on</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">next_pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">no_ranges</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="comment-syntax"> so that they count from 1; range 0 is unused</span>
|
|
|
|
<span class="plain-syntax"> </span><a href="4-to.html#SP4" class="function-link"><span class="function-syntax">Optimiser::initialise_production_data</span></a><span class="plain-syntax">(&(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><a href="4-ins.html#SP5" class="function-link"><span class="function-syntax">Instrumentation::initialise_production_data</span></a><span class="plain-syntax">(&(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">ins</span><span class="plain-syntax">));</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">head</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">tail</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP14_1" class="named-paragraph-link"><span class="named-paragraph">Parse the row of production tokens into a linked list of ptokens</span><span class="named-paragraph-number">14.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">first_pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">head</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP14_1" class="paragraph-anchor"></a><b>§14.1. </b>So, then, we have to turn a wording like:
|
|
</p>
|
|
|
|
<pre class="Preform-displayed-code all-displayed-code code-font">
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">make</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">from</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{rice</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">onions/shallots}</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">and</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">peppers</span>
|
|
</pre>
|
|
<p class="commentary">into a sequence of ptokens, setting <span class="extract"><span class="Preform-extract-syntax">head</span></span> to the first and <span class="extract"><span class="Preform-extract-syntax">tail</span></span> to the last.
|
|
This particular example will produce two word ranges: one for the initial <span class="extract"><span class="Preform-extract-syntax">...</span></span>,
|
|
one for the matter in the braces. Because of that, we need to keep track of
|
|
whether we're in braces or not. (Braces cannot be nested.)
|
|
</p>
|
|
|
|
<p class="commentary">The alternative <span class="extract"><span class="Preform-extract-syntax">onions/shallots</span></span> is called a "slashed chain" in the code below.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="Preform-constant-syntax">OUTSIDE_PTBRACE</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">0</span>
|
|
<span class="definition-keyword">define</span> <span class="Preform-constant-syntax">ABOUT_TO_OPEN_PTBRACE</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">1</span>
|
|
<span class="definition-keyword">define</span> <span class="Preform-constant-syntax">INSIDE_PTBRACE</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">2</span>
|
|
</pre>
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the row of production tokens into a linked list of ptokens</span><span class="named-paragraph-number">14.1</span></span><span class="Preform-comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">result_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">negation_modifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">lower_case_modifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bracing_mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">OUTSIDE_PTBRACE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">bracing_begins_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">token_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP14_1_1" class="named-paragraph-link"><span class="named-paragraph">Parse the token modifier symbols</span><span class="named-paragraph-number">14.1.1</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><a href="4-lp.html#SP15" class="function-link"><span class="function-syntax">LoadPreform::parse_slashed_chain</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">NONTERMINAL_PTC</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP14_1_3" class="named-paragraph-link"><span class="named-paragraph">Assign a result number</span><span class="named-paragraph-number">14.1.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP14_1_2" class="named-paragraph-link"><span class="named-paragraph">Modify the new ptoken according to the current modifier settings</span><span class="named-paragraph-number">14.1.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP14_1_4" class="named-paragraph-link"><span class="named-paragraph">Add the new ptoken to the production</span><span class="named-paragraph-number">14.1.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP14">§14</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP14_1_1" class="paragraph-anchor"></a><b>§14.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the token modifier symbols</span><span class="named-paragraph-number">14.1.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CARET_V</span><span class="plain-syntax">) { </span><span class="identifier-syntax">negation_modifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">UNDERSCORE_V</span><span class="plain-syntax">) { </span><span class="identifier-syntax">lower_case_modifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">BACKSLASH_V</span><span class="plain-syntax">) { </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bracing_mode</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">OUTSIDE_PTBRACE:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">OPENBRACE_V</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">bracing_mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">ABOUT_TO_OPEN_PTBRACE</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INSIDE_PTBRACE:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CLOSEBRACE_V</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bracing_begins_at</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP14_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Set a word range to end here</span><span class="named-paragraph-number">14.1.1.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">bracing_mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">OUTSIDE_PTBRACE</span><span class="plain-syntax">; </span><span class="identifier-syntax">bracing_begins_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP14_1">§14.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP14_1_1_1" class="paragraph-anchor"></a><b>§14.1.1.1. </b>A bracing can be followed by <span class="extract"><span class="extract-syntax">? N</span></span> to make it have the number <span class="extract"><span class="extract-syntax">N</span></span>, rather
|
|
than the next number counting upwards; see <a href="4-ap.html" class="internal">About Preform</a>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Set a word range to end here</span><span class="named-paragraph-number">14.1.1.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rnum</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">no_ranges</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2 <= </span><a href="3-wrd.html#SP7" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) && (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">+1) == </span><span class="identifier-syntax">QUESTIONMARK_V</span><span class="plain-syntax">) &&</span>
|
|
<span class="plain-syntax"> (</span><a href="2-vcb.html#SP10" class="function-link"><span class="function-syntax">Vocabulary::test_flags</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2, </span><span class="constant-syntax">NUMBER_MC</span><span class="plain-syntax">))) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">rnum</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP8" class="function-link"><span class="function-syntax">Vocabulary::get_literal_number_value</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2));</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> += </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">rnum</span><span class="plain-syntax"> < </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">rnum</span><span class="plain-syntax"> >= </span><span class="constant-syntax">MAX_RANGES_PER_PRODUCTION</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><a href="4-pu.html#SP7" class="function-link"><span class="function-syntax">PreformUtilities::production_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"range number out of range"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">rnum</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">bracing_begins_at</span><span class="plain-syntax">-></span><span class="element-syntax">range_starts</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rnum</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tail</span><span class="plain-syntax">-></span><span class="identifier-syntax">range_ends</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rnum</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP14_1_1">§14.1.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP14_1_2" class="paragraph-anchor"></a><b>§14.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Modify the new ptoken according to the current modifier settings</span><span class="named-paragraph-number">14.1.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">negation_modifier</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lower_case_modifier</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="identifier-syntax">disallow_unexpected_upper</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">negation_modifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">lower_case_modifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bracing_mode</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">OUTSIDE_PTBRACE:</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">SINGLE_WILDCARD_PTC</span><span class="plain-syntax">) ||</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">MULTIPLE_WILDCARD_PTC</span><span class="plain-syntax">) ||</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">POSSIBLY_EMPTY_WILDCARD_PTC</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rnum</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">no_ranges</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">rnum</span><span class="plain-syntax"> < </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">rnum</span><span class="plain-syntax"> >= </span><span class="constant-syntax">MAX_RANGES_PER_PRODUCTION</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><a href="4-pu.html#SP7" class="function-link"><span class="function-syntax">PreformUtilities::production_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"range number out of range"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">rnum</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">range_starts</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rnum</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">range_ends</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rnum</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ABOUT_TO_OPEN_PTBRACE:</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">bracing_begins_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">bracing_mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">INSIDE_PTBRACE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP14_1">§14.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP14_1_3" class="paragraph-anchor"></a><b>§14.1.3. </b>A nonterminal can be followed by <span class="extract"><span class="extract-syntax">? N</span></span> to make it have result number <span class="extract"><span class="extract-syntax">N</span></span>,
|
|
rather than the next number counting upwards; see <a href="4-ap.html" class="internal">About Preform</a>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Assign a result number</span><span class="named-paragraph-number">14.1.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">result_count</span><span class="plain-syntax"> < </span><span class="constant-syntax">MAX_RESULTS_PER_PRODUCTION</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2 <= </span><a href="3-wrd.html#SP7" class="function-link"><span class="function-syntax">Wordings::last_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) && (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">+1) == </span><span class="identifier-syntax">QUESTIONMARK_V</span><span class="plain-syntax">) &&</span>
|
|
<span class="plain-syntax"> (</span><a href="2-vcb.html#SP10" class="function-link"><span class="function-syntax">Vocabulary::test_flags</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2, </span><span class="constant-syntax">NUMBER_MC</span><span class="plain-syntax">))) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">result_index</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP8" class="function-link"><span class="function-syntax">Vocabulary::get_literal_number_value</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">+2));</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">result_index</span><span class="plain-syntax"> < </span><span class="constant-syntax">0</span><span class="plain-syntax">) ||</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">result_index</span><span class="plain-syntax"> >= </span><span class="constant-syntax">MAX_RESULTS_PER_PRODUCTION</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><a href="4-pu.html#SP7" class="function-link"><span class="function-syntax">PreformUtilities::production_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"result number out of range"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">result_index</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> += </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">result_index</span><span class="plain-syntax"> = </span><span class="identifier-syntax">result_count</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result_count</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><a href="4-pu.html#SP7" class="function-link"><span class="function-syntax">PreformUtilities::production_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"too many nonterminals for one production to hold"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP14_1">§14.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP14_1_4" class="paragraph-anchor"></a><b>§14.1.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add the new ptoken to the production</span><span class="named-paragraph-number">14.1.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">token_count</span><span class="plain-syntax">++ < </span><span class="constant-syntax">MAX_PTOKENS_PER_PRODUCTION</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">head</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">head</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">tail</span><span class="plain-syntax">-></span><span class="element-syntax">next_pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">tail</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><a href="4-pu.html#SP7" class="function-link"><span class="function-syntax">PreformUtilities::production_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"too many tokens on production for nonterminal"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP14_1">§14.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>§15. </b>Here we porse what is, to the Lexer, a single word (at word number <span class="extract"><span class="extract-syntax">wn</span></span>),
|
|
but which might actually be a row of possibilities divided by slashes:
|
|
for example, <span class="extract"><span class="extract-syntax">onions/shallots</span></span>.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="function-syntax">LoadPreform::parse_slashed_chain</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">LoadPreform::parse_slashed_chain</span></span>:<br/><a href="4-lp.html#SP14_1">§14.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">production</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP5" class="function-link"><span class="function-syntax">Wordings::one_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP15_1" class="named-paragraph-link"><span class="named-paragraph">Expand the word range if the token text is slashed</span><span class="named-paragraph-number">15.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP15_2" class="named-paragraph-link"><span class="named-paragraph">Parse the word range into a linked list of alternative ptokens</span><span class="named-paragraph-number">15.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP15_1" class="paragraph-anchor"></a><b>§15.1. </b>Should we detect a slash used to indicate alternatives, we have to ask the
|
|
Lexer to have another try, but with <span class="extract"><span class="extract-syntax">/</span></span> as a word-breaking character this time.
|
|
So, for example, <span class="extract"><span class="extract-syntax">AW</span></span> might then end up as <span class="extract"><span class="extract-syntax">onions</span></span>, <span class="extract"><span class="extract-syntax">/</span></span>, <span class="extract"><span class="extract-syntax">shallots</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Expand the word range if the token text is slashed</span><span class="named-paragraph-number">15.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word_raw_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">, </span><span class="identifier-syntax">breakme</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP15_1_1" class="named-paragraph-link"><span class="named-paragraph">Look out for production match numbers</span><span class="named-paragraph-number">15.1.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k</span><span class="plain-syntax">=0; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">]) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+1]); </span><span class="identifier-syntax">k</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">k</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">] == </span><span class="character-syntax">'/'</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">breakme</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">breakme</span><span class="plain-syntax">) </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><a href="3-fds.html#SP4" class="function-link"><span class="function-syntax">Feeds::feed_C_string_full</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"/"</span><span class="plain-syntax">); </span><span class="comment-syntax"> break only at slashes</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP15">§15</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15_1_1" class="paragraph-anchor"></a><b>§15.1.1. </b>Intercept <span class="extract"><span class="extract-syntax">/a/</span></span> to <span class="extract"><span class="extract-syntax">/z/</span></span> and <span class="extract"><span class="extract-syntax">/aa/</span></span> to <span class="extract"><span class="extract-syntax">/zz/</span></span>, which don't make ptokens at
|
|
all, but simply change the production's match number.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Look out for production match numbers</span><span class="named-paragraph-number">15.1.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">[0] == </span><span class="character-syntax">'/'</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">Characters::islower</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[1])) &&</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[2] == </span><span class="character-syntax">'/'</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[3] == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">match_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">[1] - </span><span class="character-syntax">'a'</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> i.e., contribute no token</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">[0] == </span><span class="character-syntax">'/'</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">Characters::islower</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[1])) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[2] == </span><span class="identifier-syntax">p</span><span class="plain-syntax">[1]) &&</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[3] == </span><span class="character-syntax">'/'</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[4] == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">match_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">[1] - </span><span class="character-syntax">'a'</span><span class="plain-syntax"> + </span><span class="constant-syntax">26</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> i.e., contribute no token</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP15_1">§15.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15_2" class="paragraph-anchor"></a><b>§15.2. </b>And then we string together the ptokens made into a linked list with links
|
|
provided by <span class="extract"><span class="extract-syntax">->alternative_ptoken</span></span>, and return the head of this list.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the word range into a linked list of alternative ptokens</span><span class="named-paragraph-number">15.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (; </span><a href="3-wrd.html#SP11" class="function-link"><span class="function-syntax">Wordings::nonempty</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">); </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><a href="3-wrd.html#SP8" class="function-link"><span class="function-syntax">Wordings::trim_first_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><a href="3-wrd.html#SP7" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">)) != </span><span class="identifier-syntax">FORWARDSLASH_V</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-wrd.html#SP7" class="function-link"><span class="function-syntax">Wordings::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">) > </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">latest</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><a href="4-lp.html#SP16" class="function-link"><span class="function-syntax">LoadPreform::new_ptoken</span></a><span class="plain-syntax">(</span><a href="3-lxr.html#SP19" class="function-link"><span class="function-syntax">Lexer::word</span></a><span class="plain-syntax">(</span><a href="3-wrd.html#SP7" class="function-link"><span class="function-syntax">Wordings::first_wn</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">AW</span><span class="plain-syntax">)),</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-></span><span class="element-syntax">match_number</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">alt</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">latest</span><span class="plain-syntax">; </span><span class="comment-syntax"> thus making </span><span class="extract"><span class="extract-syntax">pt</span></span><span class="comment-syntax"> the head</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">alt</span><span class="plain-syntax">-></span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">latest</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">latest</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP15">§15</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>§16. </b>Finally, then, the bottom-most function here parses what is definitely a
|
|
single word into what will definitely be a single ptoken.
|
|
</p>
|
|
|
|
<p class="commentary">In "escaped" mode, where a backslash has made the text literal, it just
|
|
becomes a fixed word; otherwise it could be any of the five categories.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="function-syntax">LoadPreform::new_ptoken</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">LoadPreform::new_ptoken</span></span>:<br/><a href="4-lp.html#SP15_2">§15.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">vocabulary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">, </span><span class="reserved-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ptoken</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">ptoken</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP16_1" class="named-paragraph-link"><span class="named-paragraph">Begin with a blank ptoken</span><span class="named-paragraph-number">16.1</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="2-vcb.html#SP7" class="function-link"><span class="function-syntax">Vocabulary::get_exemplar</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[0] == </span><span class="character-syntax">'<'</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">Wide::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)-1] == </span><span class="character-syntax">'>'</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP16_2" class="named-paragraph-link"><span class="named-paragraph">This word is a nonterminal name</span><span class="named-paragraph-number">16.2</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-lp.html#SP16_3" class="named-paragraph-link"><span class="named-paragraph">This word is not a nonterminal name</span><span class="named-paragraph-number">16.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP16_1" class="paragraph-anchor"></a><b>§16.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Begin with a blank ptoken</span><span class="named-paragraph-number">16.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">next_pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">balanced_wildcard</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">negated_ptoken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">disallow_unexpected_upper</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ve_pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">nt_pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">alternative_ptoken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">result_index</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">range_starts</span><span class="plain-syntax"> = -1; </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">range_ends</span><span class="plain-syntax"> = -1;</span>
|
|
|
|
<span class="plain-syntax"> </span><a href="4-to.html#SP6" class="function-link"><span class="function-syntax">Optimiser::initialise_ptoken_data</span></a><span class="plain-syntax">(&(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">opt</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> </span><a href="4-ins.html#SP7" class="function-link"><span class="function-syntax">Instrumentation::initialise_ptoken_data</span></a><span class="plain-syntax">(&(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ins</span><span class="plain-syntax">));</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP16">§16</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP16_2" class="paragraph-anchor"></a><b>§16.2. </b>If the text refers to a nonterminal which doesn't yet exist, then this
|
|
creates it; that's how we deal with forward references. <a href="4-nnt.html#SP8" class="internal">Nonterminals::find</a>
|
|
never returns <span class="extract"><span class="extract-syntax">NULL</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">This word is a nonterminal name</span><span class="named-paragraph-number">16.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">nt_pt</span><span class="plain-syntax"> = </span><a href="4-nnt.html#SP8" class="function-link"><span class="function-syntax">Nonterminals::find</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">NONTERMINAL_PTC</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP16">§16</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP16_3" class="paragraph-anchor"></a><b>§16.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">This word is not a nonterminal name</span><span class="named-paragraph-number">16.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ve_pt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ve</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">unescaped</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> == </span><span class="identifier-syntax">SIXDOTS_V</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">MULTIPLE_WILDCARD_PTC</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">balanced_wildcard</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> == </span><span class="identifier-syntax">THREEDOTS_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">MULTIPLE_WILDCARD_PTC</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> == </span><span class="identifier-syntax">THREEHASHES_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">SINGLE_WILDCARD_PTC</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ve</span><span class="plain-syntax"> == </span><span class="identifier-syntax">THREEASTERISKS_V</span><span class="plain-syntax">) </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> = </span><span class="constant-syntax">POSSIBLY_EMPTY_WILDCARD_PTC</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-></span><span class="element-syntax">ptoken_category</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIXED_WORD_PTC</span><span class="plain-syntax">) </span><a href="4-nnt.html#SP13" class="function-link"><span class="function-syntax">Nonterminals::note_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ve</span><span class="plain-syntax">, </span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pc</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-lp.html#SP16">§16</a>.</li></ul>
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="4-nnt.html">❮</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-wm.html">1</a></li><li class="progresschapter"><a href="2-vcb.html">2</a></li><li class="progresschapter"><a href="3-lxr.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-ap.html">ap</a></li><li class="progresssection"><a href="4-nnt.html">nnt</a></li><li class="progresscurrent">lp</li><li class="progresssection"><a href="4-to.html">to</a></li><li class="progresssection"><a href="4-le.html">le</a></li><li class="progresssection"><a href="4-ni.html">ni</a></li><li class="progresssection"><a href="4-prf.html">prf</a></li><li class="progresssection"><a href="4-bn.html">bn</a></li><li class="progresssection"><a href="4-ins.html">ins</a></li><li class="progresssection"><a href="4-pu.html">pu</a></li><li class="progressnext"><a href="4-to.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|