Section 29: Helping the parser out of trouble

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.