1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4
<title>DM4 §30: How verbs are parsed</title>
5
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6
<link rel="stylesheet" type="text/css" href="dm4.css">
10
<a href="index.html">home</a> /
11
<a href="contents.html">contents</a> /
12
<a href="ch4.html" title="Chapter IV: Describing and Parsing">chapter IV</a> /
13
<a href="s29.html" title="§29: Plural names for duplicated objects">prev</a> /
14
<a href="s31.html" title="§31: Tokens of grammar">next</a> /
15
<a href="dm4index.html">index</a>
18
<a id="p225" name="p225"></a>
19
<h2>§30 How verbs are parsed</h2>
21
<blockquote>“…I can see that the grammar gets tucked into
22
the tales and poetry as one gives pills in jelly.”<br>
23
— Louisa May Alcott (1832–1888), <i>Little Women</i></blockquote>
25
<p class="normal"><span class="atleft"><img src="dm4-225_1.jpg" alt=""></span>
26
Here is how the parser reads in a whole command. Given a stream of
29
<p class="syntax"><tt>saint</tt> / <tt>peter</tt> / <tt>,</tt> /
30
<tt>take</tt> / <tt>the</tt> / <tt>keys</tt> / <tt>from</tt> /
33
<p class="normal">it first breaks it into words, as shown, and then
34
calls the entry point routine <code>BeforeParsing</code> (which you
35
can provide, if you want to, in order to meddle with the text stream
36
before parsing gets underway). The parser then works out who is being
37
addressed, if anyone, by looking for a comma, and trying out the text
38
up to there as a noun matching an <code>animate</code> or
39
<code>talkable</code> object: in this case St Peter. This person is
40
called the “actor”, since he or she is going to perform
41
the action, and is most often the player (thus, typing “myself,
42
go north” is equivalent to typing “go north”).
43
The next word, in this case <code>'take'</code>, is the “verb
44
word”. An Inform verb usually has several English verb words
45
attached, which are called synonyms of each other: for instance, the
46
library is set up with</p>
48
<p class="syntax">“take” = “carry”
49
= “hold”</p>
51
<p class="normal">all referring to the same Inform verb.</p>
53
<p class="aside"><span class="warning">▲</span>
54
The parser sets up variables <code>actor</code> and <code>verb_word</code>
55
while working. (In the example above, their values would be the St Peter
56
object and <code>'take'</code>, respectively.)</p>
58
<p class="aside"><span class="warning">▲</span>
59
This brief discussion is simplified in two ways. Firstly, it leaves
60
out directions, because Inform considers that the name of a direction-object
61
implies “go”: thus “north” means “go
62
north”. Secondly, it misses out the grammar property described
63
in <a href="s18.html">§18</a>, which can cause different actors
64
to recognise different grammars.</p>
66
<a id="ex81" name="ex81"></a>
67
<p class="aside"><span class="warning"><b>•</b>▲
68
<b><a href="sa6.html#ans81">EXERCISE 81</a></b></span><br>
69
Use <code>BeforeParsing</code> to implement a lamp which, when rubbed,
70
produces a genie who casts a spell to make the player confuse the
71
words “white” and “black”.</p>
73
<p class="dotbreak">� � � � �</p>
75
<a id="p226" name="p226"></a>
76
<p class="normal">This section is about verbs, which are defined
77
with “grammar”, meaning usages of the directives <code>Verb</code>
78
and <code>Extend</code>. The library contains a substantial amount
79
of grammar as it is, and this forms (most of) the library file
80
<tt>"Grammar.h"</tt>. Grammar defined in your own code can
81
either build on this or selectively knock it down, but either way it
82
should be made after the inclusion of <tt>"Grammar.h"</tt>.</p>
84
<p class="indent">For instance, making a new synonym for an existing
87
<p class="lynxonly"></p>
88
<pre class="code">Verb 'steal' 'acquire' 'grab' = 'take';</pre>
90
<p class="normal">Now “steal”, “acquire” and
91
“grab” are synonyms for “take”.</p>
93
<p class="aside"><span class="warning">▲</span>
94
One can also prise synonyms apart, as will appear later.</p>
96
<p class="dotbreak">� � � � �</p>
98
<p class="normal">To return to the text above, the parser has now
99
recognised the English word “take” as one of those which
100
can refer to a particular Inform verb. It has reached word 5 and still
101
has “the keys from paul” left to understand.</p>
103
<p class="indent">Every Inform verb has a “grammar” which
104
consists of a list of one or more “grammar lines”, each
105
of them a pattern which the rest of the text might match. The parser
106
tries the first, then the second and so on, and accepts the earliest
107
one that matches, without ever considering later ones.</p>
109
<p class="indent">A line is a row of “tokens”. Typical
110
tokens might mean ‘the name of a nearby object’, ‘the
111
word <code>'from'</code>’ or ‘somebody's name’. To
112
match a line, the parser must match against each token in sequence.
113
Continuing the example, the parser accepts the line of three tokens</p>
115
<p class="syntax">‹<span class="token">one or more nouns</span>›
116
‹<span class="token">the word <tt>from</tt></span>›
117
‹<span class="token">a noun</span>›</p>
119
<p class="normal">as matching “the keys from paul”.</p>
121
<p class="indent">Every grammar line has the name of an action attached,
122
and in this case it is <code>Remove</code>: so the parser has ground
123
up the original text into just four quantities, ending up with</p>
125
<p class="syntax"><tt>actor = StPeter</tt>
126
<tt>action = Remove</tt> <tt>noun = gold_keys</tt>
127
<tt>second = StPaul</tt></p>
129
<p class="normal">The parser's job is now complete, and the rest of
130
the Inform library can get on with processing the action or, as in
131
this case, an order being addressed to somebody other than the player.</p>
133
<p class="aside"><span class="warning">▲</span>
134
The action for the line currently being worked through is stored in
135
the variable <code>action_to_be</code>; or, at earlier stages when
136
the verb hasn't been deciphered yet, it holds the value <code>NULL</code>.</p>
138
<a id="p227" name="p227"></a>
139
<p class="dotbreak">� � � � �</p>
141
<p class="normal">The <code>Verb</code> directive creates Inform
142
verbs, giving them some English verb words and a grammar. The library's
143
<tt>"Grammar.h"</tt> file consists almost exclusively of
144
<code>Verb</code> directives: here is an example simplified from one
147
<p class="lynxonly"></p>
149
Verb 'take' 'get' 'carry' 'hold'
152
* multiinside 'from' noun -> Remove
153
* 'in' noun -> Enter
154
* multiinside 'off' noun -> Remove
155
* 'off' held -> Disrobe
156
* 'inventory' -> Inv;
159
<p class="normal">(You can look at the grammar being used in a game
160
with the debugging verb “showverb”: see
161
<a href="s7.html">§7</a>.) Each line of grammar begins with a
162
<code>*</code>, gives a list of tokens as far as <code>-></code> and
163
then the action which the line produces. The first line can only be
164
matched by something like “get out”, the second might
167
<p class="output">“take the banana”<br>
168
“get all the fruit except the apple”</p>
170
<p class="normal">and so on. A full list of tokens will be given
171
later: briefly, <span class="grammartoken"><code>'out'</code></span>
172
means the literal word “out”, <span class="grammartoken"><code>multi</code></span>
173
means one or more objects nearby, <span class="grammartoken"><code>noun</code></span>
174
means just one and <span class="grammartoken"><code>multiinside</code></span>
175
means one or more objects inside the second noun. In this book, grammar
176
tokens are written in the style <span class="grammartoken"><code>noun</code></span>
177
to prevent confusion (as there is also a variable called <code>noun</code>).</p>
179
<p class="aside"><span class="warning">▲</span>
180
Some verbs are marked as <code>meta</code> – these are the verbs
181
leading to Group 1 actions, those which are not really part of the
182
game's world: for example, “save”, “score”
183
and “quit”. For example:</p>
185
<p class="lynxonly"></p>
186
<pre class="code">Verb meta 'score' * -> Score;</pre>
188
<p class="aside">and any debugging verbs you create would probably work
189
better this way, since meta-verbs are protected from interference by
190
the game and take up no game time.</p>
192
<p class="dotbreak">� � � � �</p>
194
<p class="normal">After the <code>-></code> in each line is the
195
name of an action. Giving a name in this way is what creates an action,
196
and if you give the name of one which doesn't already
197
<a id="p228" name="p228"></a>
199
must also write a routine to execute the action, even if it's one which
200
doesn't do very much. The name of the routine is always the name of
201
the action with <code>Sub</code> appended. For instance:</p>
203
<p class="lynxonly"></p>
205
[ XyzzySub; "Nothing happens."; ];
206
Verb 'xyzzy' * -> Xyzzy;
209
<p class="normal">will make a new magic-word verb “xyzzy”,
210
which always says “Nothing happens” – always, that
211
is, unless some before rule gets there first, as it might do in
212
certain magic places. <code>Xyzzy</code> is now an action just as
213
good as all the standard ones: <code>##Xyzzy</code> gives its action
214
number, and you can write <code>before</code> rules for it in
215
<code>Xyzzy:</code> fields just as you would for, say, <code>Take</code>.</p>
217
<p class="aside"><span class="warning">▲</span>
218
Finally, the line can end with the word <code>reverse</code>. This
219
is only useful if there are objects or numbers in the line which
220
occur in the wrong order. An example from the library's grammar:</p>
222
<p class="lynxonly"></p>
224
Verb 'show' 'present' 'display'
225
* creature held -> Show reverse
226
* held 'to' creature -> Show;
229
<p class="aside">The point is that the <code>Show</code> action expects
230
the first parameter to be an item, and the second to be a person.
231
When the text “show him the shield” is typed in, the
232
parser must reverse the two parameters “him” and
233
“the shield” before causing a <code>Show</code> action.
234
On the other hand, in “show the shield to him” the
235
parameters are in the right order already.</p>
237
<p class="dotbreak">� � � � �</p>
239
<p class="normal">The library defines grammars for the 100 or so English
240
verbs most often used by adventure games. However, in practice you
241
quite often need to alter these, usually to add extra lines of grammar
242
but sometimes to remove existing ones. For instance, suppose you
243
would like “drop charges” to be a command in a
244
detection game (or a naval warfare game). This means adding a new
245
grammar line to the “drop” verb. The <code>Extend</code>
246
directive is provided for exactly this purpose:</p>
248
<p class="lynxonly"></p>
249
<pre class="code">Extend 'drop' * 'charges' -> DropCharges;</pre>
251
<p class="normal">Normally, extra lines of grammar are added at the
252
bottom of those already there, so that this will be the very last grammar
253
line tested by the parser. This may not be what you want. For instance,
254
“take” has a grammar line reading</p>
256
<p class="lynxonly"></p>
257
<pre class="code">* multi -> Take</pre>
259
<a id="p229" name="p229"></a>
260
<p class="normal">quite early on. So if you want to add a grammar line
261
diverting “take ‹<span class="token">food</span>›” to
262
a different action, like so:</p>
264
<p class="lynxonly"></p>
265
<pre class="code">* edible -> Eat</pre>
267
<p class="normal">(<span class="grammartoken"><code>edible</code></span>
268
being a token matching anything which has the attribute <code>edible</code>)
269
then it's no good adding this at the bottom of the <code>Take</code>
270
grammar, because the earlier line will always be matched first. What you
271
need is for the new line to go in at the top, not the bottom:</p>
273
<p class="lynxonly"></p>
279
<p class="normal">You might even want to throw away the old grammar completely,
280
not just add a line or two. For this, use</p>
282
<p class="lynxonly"></p>
284
Extend 'press' replace
285
* 'charges' -> PressCharges;
288
<p class="normal">and now the verb “press” has no other
289
sense but this, and can't be used in the sense of pressing down on
290
objects any more, because those grammar lines are gone. To sum
291
up, <code>Extend</code> can optionally take one of three keywords:</p>
293
<p class="lynxonly"></p>
294
<div class="inset"><table>
295
<tr><td><code>replace</code></td><td> replace the old grammar with this one;</td></tr>
296
<tr><td><code>first</code></td><td> insert the new grammar at the top;</td></tr>
297
<tr><td><code>last</code></td><td> insert the new grammar at the bottom;</td></tr>
300
<p class="normal">with <code>last</code> being the default.</p>
302
<p class="aside"><span class="warning">▲</span>
303
In library grammar, some verbs have many synonyms: for instance,</p>
305
<p class="lynxonly"></p>
307
'attack' 'break' 'smash' 'hit' 'fight' 'wreck' 'crack'
308
'destroy' 'murder' 'kill' 'torture' 'punch' 'thump'
311
<p class="aside">are all treated as identical. But you might want
312
to distinguish between murder and lesser crimes. For this, try</p>
314
<p class="lynxonly"></p>
316
Extend only 'murder' 'kill' replace
317
* animate -> Murder;
320
<p class="aside">The keyword only tells Inform to extract the two
321
verbs “murder" and “kill". These then become
322
a new verb which is initially an identical copy of the old one, but
323
then <code>replace</code> tells Inform to throw that away in favour of
324
an entirely new grammar. Similarly,</p>
326
<p class="lynxonly"></p>
327
<pre class="code">Extend only 'run' * 'program' -> Compute;</pre>
329
<p class="aside">makes “run" behave exactly like “go"
330
and “walk”, as these three words are ordinarily synonymous
331
to the library, except that it also recognises “program",
332
so that “run program" activates a computer but “walk
333
program" doesn't. Other good pairs to separate might be “cross”
334
and “enter”, “drop” and “throw”,
335
“give” and “feed”, “swim”
336
and “dive”, “kiss” and “hug”,
337
“cut” and “prune”. Bear in mind that once a
338
pair has been split apart like this, any subsequent change to one will
339
not also change the other.</p>
341
<a id="p230" name="p230"></a>
342
<p class="aside"><span class="warning">▲▲</span>
343
Occasionally verb definition commands are not enough. For example,
344
in the original ‘Advent’, the player could type the name
345
of an adjacent place which had previously been visited, and be taken
346
there. (This feature isn't included in the Inform example version
347
of the game in order to keep the source code as simple as possible.)
348
There are several laborious ways to code this, but here's a concise
349
way. The library calls the <code>UnknownVerb</code> entry point routine
350
(if you provide one) when the parser can't even get past the first
351
word. This has two options: it can return <code>false</code>, in which
352
case the parser just goes on to complain as it would have done anyway.
353
Otherwise, it can return a verb word which is substituted for what
354
the player actually typed. Here is one way the ‘Advent’
355
room-naming might work. Suppose that every room has been given a
356
property called <code>go_verb</code> listing the words which refer
357
to it, so for instance the well house might be defined along these
360
<p class="lynxonly"></p>
362
AboveGround Inside_Building "Inside Building"
364
"You are inside a building, a well house for a
366
go_verb 'well' 'house' 'inside' 'building',
370
<p class="aside">The <code>UnknownVerb</code> routine then looks
371
through the possible compass directions for already-visited
372
rooms, checking against words stored in this new property:</p>
374
<p class="lynxonly"></p>
376
Global go_verb_direction;
377
[ UnknownVerb word room direction adjacent;
378
room = real_location;
379
objectloop (direction in compass) {
380
adjacent = room.(direction.door_dir);
381
if (adjacent ofclass Object && adjacent has visited
382
&& adjacent provides go_verb
383
&& WordInProperty(word, adjacent, go_verb)) {
384
go_verb_direction = direction;
388
if (room provides go_verb
389
&& WordInProperty(word, room, go_verb)) {
390
go_verb_direction = "You're already there!";
393
objectloop (room provides go_verb && room has visited
394
&& WordInProperty(word, room, go_verb)) {
395
go_verb_direction = "You can't get there from here!";
397
}<a id="p231" name="p231"></a>
398
objectloop (room provides go_verb && room hasnt visited
399
&& WordInProperty(word, room, go_verb)) {
400
go_verb_direction = "But you don't know the way there!";
407
<p class="aside">When successful, this routine stores either a compass
408
direction (an object belonging to the compass) in the variable
409
<code>go_verb_direction</code>, or else a string to print. (Note that
410
an <code>UnknownVerb</code> routine shouldn't print anything itself,
411
as this might be inappropriate in view of subsequent parsing, or if
412
the actor isn't the player.) The routine then tells the parser to
413
treat the verb as if it were <code>'go.verb'</code>, and as this doesn't
414
exist yet, we must define it:</p>
416
<p class="lynxonly"></p>
419
if (go_verb_direction ofclass String)
420
print_ret (string) go_verb_direction;
421
<<Go go_verb_direction>>;
423
Verb 'go.verb' * -> Go_Verb;
426
<a id="ex82" name="ex82"></a>
427
<p class="aside"><span class="warning"><b>•</b>▲▲
428
<b><a href="sa6.html#ans82">EXERCISE 82</a></b></span><br>
429
A minor deficiency with the above system is that the parser may print
430
out strange responses like “I only understood you as far as
431
wanting to go.verb.” if the player types something odd
432
like “bedquilt the nugget”. How can we ensure that the
433
parser will always say something like “I only understood you
434
as far as wanting to go to Bedquilt.”?</p>
436
<p class="aside"><span class="warning"><b>•</b>
437
<b>REFERENCES</b></span><br>
438
‘Advent’ makes a string of simple <code>Verb</code> definitions;
439
‘Alice Through the Looking-Glass’ uses <code>Extend</code> a
441
<span class="warning"><b>•</b></span>‘Balances’ has a
442
large extra grammar and also uses the <code>UnknownVerb</code> and
443
<code>PrintVerb</code> entry points.
444
<span class="warning"><b>•</b></span>Irene Callaci's <tt>"AskTellOrder.h"</tt>
445
library extension file makes an elegant use of <code>BeforeParsing</code> to
446
convert commands in the form “ask mr darcy to dance” or
447
“tell jack to go north” to Inform's preferred form
448
“mr darcy, dance” and “jack, go north”.</p>
452
<a href="index.html">home</a> /
453
<a href="contents.html">contents</a> /
454
<a href="ch4.html" title="Chapter IV: Describing and Parsing">chapter IV</a> /
455
<a href="s29.html" title="§29: Plural names for duplicated objects">prev</a> /
456
<a href="s31.html" title="§31: Tokens of grammar">next</a> /
457
<a href="dm4index.html">index</a>