Contents
Back
Forward

29. Helping the parser out of trouble

/\ Once you begin programming the parser on a large scale, you soon reach the point where the parser's ordinary error messages no longer appear sensible. The ParserError entry point can change the rules even at this last hurdle: it takes one argument, the error type, and should return true to tell the parser to shut up, because a better error message has already been printed, or false, to tell the parser to print its usual message. The error types are all defined as constants:


STUCK_PE I didn't understand that sentence.
UPTO_PE I only understood you as far as...
NUMBER_PE I didn't understand that number.
CANTSEE_PE You can't see any such thing.
TOOLIT_PE You seem to have said too little!
NOTHELD_PE You aren't holding that!
MULTI_PE You can't use multiple objects with that verb.
MMULTI_PE You can only use multiple objects once on a line.
VAGUE_PE I'm not sure what 'it' refers to.
EXCEPT_PE You excepted something not included anyway!
ANIMA_PE You can only do that to something animate.
VERB_PE That's not a verb I recognise.
SCENERY_PE That's not something you need to refer to...
ITGONE_PE You can't see 'it' (the whatever) at the moment.
JUNKAFTER_PE I didn't understand the way that finished.
TOOFEW_PE Only five of those are available.
NOTHING_PE Nothing to do!
ASKSCOPE_PE whatever the scope routine prints
Each unsuccessful grammar line ends in one of these conditions. A verb may have many lines of grammar; so by the time the parser wants to print an error, all of them must have failed. The error message it prints is the most 'interesting' one: meaning, lowest down this list.

/\ The VAGUE_PE and ITGONE_PE apply to all pronouns (in English, "it'', "him'', "her'' and "them''). The variable vague_word contains the dictionary address of which is involved ('it', 'him', etc.).

You can find out the current setting of a pronoun using the library's PronounValue routine: for instance, PronounValue('it') would give the object which "it'' currently refers to (possibly nothing). Similarly SetPronoun('it', magic_ruby) would set "it'' to mean the magic ruby object. (When something like a magic ruby suddenly appears in the middle of a turn, players will habitually call it "it''.) A better way to adjust the pronouns is to call PronounNotice(magic_ruby), which sets whatever pronouns are appropriate. That is, it works out if the object is a thing or a person, of what number and gender, which pronouns apply to it in the parser's current language, and so on. In code predating Inform 6.1 you may see variables called itobj, himobj and herobj holding the English pronoun values: these still work properly, but please use the modern system in new games.

/\ The Inform parser resolves ambiguous inputs with a complicated algorithm based on practical experience. However, it can't have any expertise with newly-created verbs: here is how to provide it. If you define a routine
ChooseObjects(object, code)

then it's called in two circumstances. If code is 0 or 1, the parser is considering including the given object in an "all'': 0 means the parser has decided against, 1 means it has decided in favour. The routine should reply

0 (or false) to say "carry on'';
1 to force the object to be included; or
2 to force the object to be excluded.
It may want to decide using verb_word (the variable storing the current verb word, e.g., 'take') and action_to_be, which is the action which would happen if the current line of grammar were successfully matched.

The other circumstance is when code is 2. This means the parser is sorting through a list of items (those in scope which best matched the input), trying to decide which single one is most likely to have been intended. If it can't choose a best one, it will give up and ask the player. ChooseObjects should then return a number from 0 to 9 (0 being the default) to give the object a score for how appropriate it is.

For instance, some designers would prefer "take all'' not to attempt to take scenery objects (which Inform, and the parsers in most of the Infocom games, will do). Let us code this, and also teach the parser that edible things are more likely to be eaten than inedible ones:

[ ChooseObjects obj code;
  if (code<2) { if (obj has scenery) return 2; rfalse; }
  if (action_to_be==##Eat && obj has edible) return 3;
  if (obj hasnt scenery) return 2;
  return 1;
];
Scenery is now excluded from "all'' lists; and is further penalised in that non-scenery objects are always preferred over scenery, all else being equal. Most objects score 2 but edible things in the context of eating score 3, so "eat black'' will now always choose a Black Forest gateau in preference to a black rod with a rusty iron star on the end.

??/\EXERCISE 87:
(link to
the answer)
Allow "lock'' and "unlock'' to infer their second objects without being told, if there's an obvious choice (because the player's only carrying one key), but to issue a disambiguation question otherwise. (Use Extend, not ChooseObjects.)

*REFERENCES:
See 'Balances' for a usage of ParserError.

Contents / Back / Forward
Chapter I / Chapter II / Chapter III / Chapter IV / Chapter V / Chapter VI / Appendix
Mechanically translated to HTML from third edition as revised 16 May 1997. Copyright © Graham Nelson 1993, 1994, 1995, 1996, 1997: all rights reserved.