[Encore] Parser

Kevin Jepson kevijeps at telusplanet.net
Mon May 7 16:59:55 MDT 2007


Hi Jean-Marc
 
I hope your year went well.
 
The parser is actually part of the server itself.
 
There is a good description of how it works in the LambdaMOO Programmers
Manual:
 
I've cut and pasted it below
 
Because the server first tries to have code in the DB execute you could use
a feature object or something to enable non-standard behaviours.
 
Ciao
KJ
===========
 
HYPERLINK
"http://www.encore-consortium.org/Barn/files/docs/lambdamoo/ProgrammersManua
l.html#SEC8"http://www.encore-consortium.org/Barn/files/docs/lambdamoo/Progr
ammersManual.html#SEC8HYPERLINK "file://ProgrammersManual.html#SEC8"

HYPERLINK
"file:///C:/DATA/moo/Docs/Lambda/ProgrammersManual_toc.html#SEC8"The
Built-in Command Parser


The MOO server is able to do a small amount of parsing on the commands that
a player enters. In particular, it can break apart commands that follow one
of the following forms: 

verb

verb direct-object

verb direct-object preposition indirect-object



Real examples of these forms, meaningful in the LambdaCore database, are as
follows: 

look

take yellow bird

put yellow bird in cuckoo clock



Note that English articles (i.e., `the', `a', and `an') are not generally
used in MOO commands; the parser does not know that they are not important
parts of objects' names. 

To have any of this make real sense, it is important to understand precisely
how the server decides what to do when a player types a command. 

First, the server checks whether or not the first non-blank character in the
command is one of the following: 

"        :        ;



If so, that character is replaced by the corresponding command below,
followed by a space: 

say      emote    eval



For example, the command 

"Hi, there.



is treated exactly as if it were as follows: 

say Hi, there.



The server next breaks up the command into words. In the simplest case, the
command is broken into words at every run of space characters; for example,
the command `foo bar baz' would be broken into the words `foo', `bar', and
`baz'. To force the server to include spaces in a "word", all or part of a
word can be enclosed in double-quotes. For example, the command 

foo "bar mumble" baz" "fr"otz" bl"o"rt



is broken into the words `foo', `bar mumble', `baz frotz', and `blort'.
Finally, to include a double-quote or a backslash in a word, they can be
preceded by a backslash, just like in MOO strings. 

Having thus broken the string into words, the server next checks to see if
the first word names any of the six "built-in" commands: `.program',
`PREFIX', `OUTPUTPREFIX', `SUFFIX', `OUTPUTSUFFIX', or the connection's
defined flush command, if any (`.flush' by default). The first one of these
is only available to programmers, the next four are intended for use by
client programs, and the last can vary from database to database or even
connection to connection; all six are described in the final chapter of this
document, "Server Commands and Database Assumptions". If the first word
isn't one of the above, then we get to the usual case: a normal MOO command.


The server next gives code in the database a chance to handle the command.
If the verb $do_command() exists, it is called with the words of the command
passed as its arguments and argstr set to the raw command typed by the user.
If $do_command() does not exist, or if that verb-call completes normally
(i.e., without suspending or aborting) and returns a false value, then the
built-in command parser is invoked to handle the command as described below.
Otherwise, it is assumed that the database code handled the command
completely and no further action is taken by the server for that command. 

If the built-in command parser is invoked, the server tries to parse the
command into a verb, direct object, preposition and indirect object. The
first word is taken to be the verb. The server then tries to find one of the
prepositional phrases listed at the end of the previous section, using the
match that occurs earliest in the command. For example, in the very odd
command `foo as bar to baz', the server would take `as' as the preposition,
not `to'. 

If the server succeeds in finding a preposition, it considers the words
between the verb and the preposition to be the direct object and those after
the preposition to be the indirect object. In both cases, the sequence of
words is turned into a string by putting one space between each pair of
words. Thus, in the odd command from the previous paragraph, there are no
words in the direct object (i.e., it is considered to be the empty string,
"") and the indirect object is "bar to baz". 

If there was no preposition, then the direct object is taken to be all of
the words after the verb and the indirect object is the empty string. 

The next step is to try to find MOO objects that are named by the direct and
indirect object strings. 

First, if an object string is empty, then the corresponding object is the
special object #-1 (aka $nothing in LambdaCore). If an object string has the
form of an object number (i.e., a hash mark (`#') followed by digits), and
the object with that number exists, then that is the named object. If the
object string is either "me" or "here", then the player object itself or its
location is used, respectively. 

Otherwise, the server considers all of the objects whose location is either
the player (i.e., the objects the player is "holding", so to speak) or the
room the player is in (i.e., the objects in the same room as the player); it
will try to match the object string against the various names for these
objects. 

The matching done by the server uses the `aliases' property of each of the
objects it considers. The value of this property should be a list of
strings, the various alternatives for naming the object. If it is not a
list, or the object does not have an `aliases' property, then the empty list
is used. In any case, the value of the `name' property is added to the list
for the purposes of matching. 

The server checks to see if the object string in the command is either
exactly equal to or a prefix of any alias; if there are any exact matches,
the prefix matches are ignored. If exactly one of the objects being
considered has a matching alias, that object is used. If more than one has a
match, then the special object #-2 (aka $ambiguous_match in LambdaCore) is
used. If there are no matches, then the special object #-3 (aka
$failed_match in LambdaCore) is used. 

So, now the server has identified a verb string, a preposition string, and
direct- and indirect-object strings and objects. It then looks at each of
the verbs defined on each of the following four objects, in order: 

1.	the player who typed the command, 
2.	the room the player is in, 
3.	the direct object, if any, and 
4.	the indirect object, if any. 

For each of these verbs in turn, it tests if all of the the following are
true: 

*	the verb string in the command matches one of the names for the
verb, 
*	the direct- and indirect-object values found by matching are allowed
by the corresponding argument specifiers for the verb, and 
*	the preposition string in the command is matched by the preposition
specifier for the verb. 

I'll explain each of these criteria in turn. 

Every verb has one or more names; all of the names are kept in a single
string, separated by spaces. In the simplest case, a verb-name is just a
word made up of any characters other than spaces and stars (i.e., ` ' and
`*'). In this case, the verb-name matches only itself; that is, the name
must be matched exactly. 

If the name contains a single star, however, then the name matches any
prefix of itself that is at least as long as the part before the star. For
example, the verb-name `foo*bar' matches any of the strings `foo', `foob',
`fooba', or `foobar'; note that the star itself is not considered part of
the name. 

If the verb name ends in a star, then it matches any string that begins with
the part before the star. For example, the verb-name `foo*' matches any of
the strings `foo', `foobar', `food', or `foogleman', among many others. As a
special case, if the verb-name is `*' (i.e., a single star all by itself),
then it matches anything at all. 

Recall that the argument specifiers for the direct and indirect objects are
drawn from the set `none', `any', and `this'. If the specifier is `none',
then the corresponding object value must be #-1 (aka $nothing in
LambdaCore); that is, it must not have been specified. If the specifier is
`any', then the corresponding object value may be anything at all. Finally,
if the specifier is `this', then the corresponding object value must be the
same as the object on which we found this verb; for example, if we are
considering verbs on the player, then the object value must be the player
object. 

Finally, recall that the argument specifier for the preposition is either
`none', `any', or one of several sets of prepositional phrases, given above.
A specifier of `none' matches only if there was no preposition found in the
command. A specifier of `any' always matches, regardless of what preposition
was found, if any. If the specifier is a set of prepositional phrases, then
the one found must be in that set for the specifier to match. 

So, the server considers several objects in turn, checking each of their
verbs in turn, looking for the first one that meets all of the criteria just
explained. If it finds one, then that is the verb whose program will be
executed for this command. If not, then it looks for a verb named `huh' on
the room that the player is in; if one is found, then that verb will be
called. This feature is useful for implementing room-specific command
parsing or error recovery. If the server can't even find a `huh' verb to
run, it prints an error message like `I couldn't understand that.' and the
command is considered complete. 

At long last, we have a program to run in response to the command typed by
the player. When the code for the program begins execution, the following
built-in variables will have the indicated values: 

player    an object, the player who typed the command

this      an object, the object on which this verb was found

caller    an object, the same as `player'

verb      a string, the first word of the command

argstr    a string, everything after the first word of the command

args      a list of strings, the words in `argstr'

dobjstr   a string, the direct object string found during parsing

dobj      an object, the direct object value found during matching

prepstr   a string, the prepositional phrase found during parsing

iobjstr   a string, the indirect object string

iobj      an object, the indirect object value



The value returned by the program, if any, is ignored by the server. 

 

-----Original Message-----
From: encore-bounces at encore-consortium.org
[mailto:encore-bounces at encore-consortium.org] On Behalf Of Jean-Marc Giffin
Sent: May 7, 2007 11:29 AM
To: encore at encore-consortium.org
Subject: [Encore] Parser



Encorers!

I haven't been around in a while, but I'm back in the MOO business for the
summer.

I've been wondering (I'm using enCore Version 4.01)... what object is it
that parses a command to see if it exists in the location, or on the player?

For example, if I type:

take book

Then it looks around my inventory, and then the room, to see if there's an
object called "book". But I want it to also include an object that may not
be in the room, nor my inventory, but in a special location that I have
specifically for the purpose of being able to do things to items that are
not technically in the room or inventory.

So, what object is it that takes the word "book" and then compares it to
your location and inventory?

Thanks!

Jean Of mArc 


No virus found in this incoming message.
Checked by AVG Free Edition.
Version: 7.5.467 / Virus Database: 269.6.5/792 - Release Date: 06/05/2007
9:01 PM





No virus found in this outgoing message.
Checked by AVG Free Edition. 
Version: 7.5.467 / Virus Database: 269.6.5/792 - Release Date: 06/05/2007
9:01 PM
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://encore-consortium.org/pipermail/encore_encore-consortium.org/attachments/20070507/a50cd982/attachment-0001.html 


More information about the Encore mailing list