Command Parser Reference
This page is the reference for the command parser: lexer attributes,
parser methods verbs use to read parsed arguments, the preposition
synonym table, and the verb search order. For the conceptual overview
(grammar, BNF, lexer behaviour, the $do_command hook), see
How Command Parsing Works.
Command splitting and verb-head conventions
Before tokenisation, the lexer scans the raw input for two structural rules:
Input feature |
Effect |
|---|---|
|
Splits the line into multiple commands; each is parsed and dispatched in turn. |
First token begins with |
Treated as part of the verb name. |
Verb names, object names, and aliases are all matched
case-insensitively. The player can type LOOK, look, or Look and
the same verb dispatches.
A dead-object reference (e.g. #5 for an Object that has been
recycled) raises NoSuchObjectError. The task runner classifies this
as a player-visible UserError and shows a clean “There is no #5”
message rather than a generic execution error.
Lexer
The lexer turns a raw command string into a structured Lexer
instance. It is internal plumbing; verb code never constructs one
directly. It’s described here for completeness — verbs interact with
the Parser instance attached to context.parser.
-
Lexer.command:
str The full, unparsed command string the player typed.
-
Lexer.words:
list[str] The tokenised words from the command, preserving quoted spans.
-
Lexer.dobj_str:
str|None The direct-object substring, or
Noneif the command had no direct object.
-
Lexer.dobj_spec_str:
str|None Any specifier on the direct object (
my,the, a possessive likeBill's). Empty string if no specifier was used;Noneif there was no direct object at all.
-
Lexer.prepositions:
dict Dict mapping each preposition that appeared in the command to a list of
[spec_str, obj_str, obj]triples.objisNoneat the lexer phase; the parser fills it in during dispatch.
Parser
Parser consumes a Lexer plus the caller object and resolves names
to Objects.
-
Parser.caller:
object The
Objectthat issued the command (the player who typed it).
-
Parser.command:
str The full, unparsed command string. Inherited from the lexer.
-
Parser.words:
list[str] The tokenised words from the command. Inherited from the lexer.
-
Parser.dobj_str:
str|None The direct-object substring. Inherited from the lexer.
-
Parser.dobj_spec_str:
str|None Direct-object specifier. Inherited from the lexer.
-
Parser.dobj:
object The resolved direct object as an
Object, orNoneif it could not be resolved or no direct object was given.
-
Parser.prepositions:
dict Dict mapping each preposition that appeared to
[spec_str, obj_str, obj]triples. After parsing,objis the resolvedObject(orNoneif it could not be resolved).
-
Parser.verb:
object The
Verbselected by dispatch, set afterget_verb()runs.
-
Parser.this:
object The Object the verb was matched on (last-match-wins; see Command Parser Reference).
Most of these are read internally during dispatch. The two things
verb code actually uses on context.parser are context.parser.command
(the original command string) and the argument-extraction methods,
listed next.
Parser methods
- Parser.get_dobj(lookup=False)
Return the direct object as an
Object. Use this when the argument refers to an existing game object.- Parameters:
lookup – if
True, fall back to a globalmoo.sdk.lookup()by name when no local match is found. Local matches always take precedence — this prevents@obvious cratefrom resolving to a faraway “wooden crate” when the player has their own crate in the room.- Raises:
NoSuchObjectError – if the direct object string didn’t resolve to a real object.
- Parser.get_dobj_str()
Return the direct object as a raw string. Use this when the argument is plain text (a message, a name to create, a code snippet) rather than a reference to an existing game object.
- Raises:
NoSuchObjectError – if no direct object string was given.
- Parser.has_dobj(lookup=False)
Return
Trueif the parser resolved a direct object to a realObject.
- Parser.has_dobj_str()
Return
Trueif a direct object string was given on the command line, regardless of whether it resolved to an object.
- Parser.get_pobj(prep, lookup=False)
Return the indirect object for
prepas anObject. Synonym prepositions (e.g.usingforwith) are resolved to their canonical form automatically.- Parameters:
prep – the preposition (canonical form or any synonym).
lookup – if
True, fall back to a globalmoo.sdk.lookup()by name when no local match is found.
- Raises:
NoSuchObjectError – if the indirect object string didn’t resolve to a real object.
NoSuchPrepositionError – if
prepwas not present in the command.
- Parser.get_pobj_str(prep, return_list=False)
Return the indirect object for
prepas a raw string. Use this when the argument is plain text rather than an object reference.- Parameters:
prep – the preposition (canonical form or any synonym).
return_list – if
Trueand multiple matches were given, return all of them as a list. Default returns the first.
- Raises:
NoSuchObjectError – if no indirect object string was given for this preposition.
NoSuchPrepositionError – if
prepwas not present in the command.
- Parser.get_pobj_spec_str(prep, return_list=False)
Return the specifier (
my,the, possessive form) used with the indirect object forprep. Useful when a verb wants to behave differently formy Xvs. plainX. Returns the empty string if no specifier was given.- Parameters:
prep – the preposition (canonical form or any synonym).
return_list – if
Trueand multiple matches were given, return all specifiers as a list.
- Raises:
NoSuchPrepositionError – if
prepwas not present in the command.
- Parser.has_pobj(prep)
Return
Trueif the parser resolved an indirect object forprepto a realObject. Synonym prepositions are resolved to their canonical form automatically.
- Parser.has_pobj_str(prep)
Return
Trueif an indirect object string was given forprep, regardless of whether it resolved to an object. Synonym prepositions are resolved to their canonical form automatically.
Use get_*_str() when the argument is plain text (a message, a name
to create, etc.). Use get_*() when you expect the argument to refer
to an existing game object — and let the exception propagate if it
doesn’t. The task runner shows a clean error to the player; you don’t
need a try/except just to report the failure. See
Creating MOO Verbs for the canonical patterns.
Object resolution
When the parser encounters a name in the command, it resolves it to an Object using these rules in order:
Form |
Resolution |
|---|---|
|
The caller (the player who typed the command). |
|
The caller’s location. |
|
The Object with that primary key. Raises |
|
Search the caller’s inventory for |
|
Find |
|
Search the caller’s location first; if no match, fall back to the caller’s inventory. |
All name and alias matches are case-insensitive. Hidden-placement
objects (placed under or behind something) are excluded from
location searches by name. They can only be reached by look under <target> or look behind <target>, which read the placement table
directly.
get_dobj(lookup=True) and get_pobj(prep, lookup=True) add a final
fallback to a global lookup() if no local match exists. Local
matches always win — @obvious crate matches the crate in your room
even when a “wooden crate” exists elsewhere in the world.
Preposition synonym groups
settings.PREPOSITIONS defines preposition synonym groups. Words in
the same group are interchangeable; the parser normalises every
synonym to the first (canonical) word in the group when storing the
parsed result.
Canonical |
Synonyms |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Verb authors should use the canonical (first) form in --ispec
shebang options and in parser API calls such as
get_pobj_str("with"). Synonyms also work transparently if passed
directly to those methods, but staying canonical avoids surprises.
Verb search
After resolving objects, the parser searches for a matching verb in this order:
The caller.
Objects in the caller’s inventory.
The caller’s location.
The direct object, if any.
The objects of any prepositions, if any.
For each candidate, dispatch checks:
The caller has
readpermission on the object.The object (or one of its ancestors) defines a verb whose name and argument specifiers match the command.
Verb name matching supports a single * for prefix matching
(foo*bar, foo*, *). See Verbs on Objects for the grammar.
Last match wins
The search iterates through every candidate and overwrites
parser.this on each match. The final match in the search order is
the one that executes. This is the “last match wins” rule.
When both the caller and the direct object are $player instances
(or both inherit the same verb from a common ancestor), the direct
object wins because it appears later in the search order. Inside the
executing verb:
@gag Player → this = Player (dobj), context.player = Wizard (caller)
page Player → this = Player (dobj), context.player = Wizard (caller)
Use context.player to identify who initiated a command. Only
use this when the verb is specifically designed to act on the
object it was dispatched on (a room’s accept verb, an exit’s go
verb, etc.). The LambdaMOO permission idiom
if player != this: return "Permission denied." is broken in
DjangoMOO for any verb with a dspec — it fires on every normal
invocation.