[I6] Why does parsing fail after "which do you mean..." for DM4 Ex 77?

Looking at DM4’s Exercise 77 (about using “#” as a “wildcard” for “any single object”), and using the example solution provided along with a simple world:

Constant Story "DM4 Exercise 077";
Constant Headline "^from p. 210^";

! EXERCISE 77
! How could the word "#" be made a wild-card, meaning
! "match any single object"?

Include "Parser";
Include "VerbLib";

[ ParseNoun;
    if (NextWord() == '#//')
        return 1;
    wn--;
    return -1;
];

Include "Grammar";

Class Room
    has light;

Room Start "Starting Point"
    with    description
                "An uninteresting room.";

Object -> pebble "pebble"
    with    name 'pebble';

Object -> rock "rock"
    with    name 'rock';

[ Initialise ;

    location = Start;

];

This is what happens under Inform 6.31:

Starting Point
An uninteresting room.

You can see a pebble and a rock here.

>get #
Which do you mean, the north, the south, the east, the west, the northeast,
the northwest, the southeast, the southwest, the up above, the ground,
the inside, the outside, yourself, the pebble or the rock?

>rock
I only understood you as far as wanting to get the rock.

What doesn’t the parser understand here? Per DM4 p. 242, the parser
should be attempting to reparse “>GET ROCK #” at this point, so I
suppose that the word 2 in the trace output is “rock”. I would expect
that the rock object scores 2 for parsing now (1 for ‘rock’ and 1
for ‘#’) and therefore wins against the pebble (scoring 1 for ‘#’),
but this doesn’t seem to be the case.

I note that with “trace 3” set, the following block is included in
the debug output after choosing “rock”:

[line 1 * multi -> Take]
 [line 1 token 1 word 2 : multi]
  [Object list from word 2]
  [Calling NounDomain on location and actor]
  [ND returned the rock]
  [token resulted in success]
 [line 1 token 2 word 3 : END]

The noun token succeeds, but perhaps the grammar line doesn’t? Does
“[line 1 token 2 word 3 : END]” mean that wn is left at 3 after the
noun token is completed, so the grammar line fails because no more
words are allowed? The exact same behavior occurs if the command
is originally entered as “>GET ROCK #”, so that’s at least consistent.

Is there something special going on with ParseNoun() being involved
here? I note that, if ParseNoun() is removed and both pebble and rock
include ‘#//’ in their name properties, then the issue doesn’t occur.

I haven’t run any tests, but it looks like that ParseNoun routine can’t accept multiple words. That is, “rock #” or “# rock” aren’t going to be recognized. You’d have to modify it to deal with that possibility.

1 Like

@zarf, I appreciate that you took a look at the above, but I’m not sure that I made myself clear in my question. I’m trying to understand why exactly the parsing process fails. (Note that the definition of ParseNoun() in my question is exactly the example solution provided for the exercise in DM4.)

Am I correct in understanding that the sequence of events is:

  1. player enters command >GET #
  2. parser identifies ‘get’ as meaning the ‘take’ command
  3. parser sees the “‘Take’ multi” grammar line and tries to match it
  4. since ParseNoun() is defined, this gets priority over normal matching based on the name property, and every object in scope gets a score of 1
  5. as a result of ParseNoun() behavior, parser sees all objects as equally relevant but ##PluralFound was not set, so it tries to disambiguate automatically
  6. finding no way to automatically disambiguate, it asks the player which object is meant
  7. player enters “rock” so command is restructured as >GET ROCK # and parsing starts over
  8. parser again identifies verb word and tries to match the “‘Take’ multi” grammar line
  9. ParseNoun() has no response to “rock” so it returns -1
  10. parser does normal name-property recognition of objects and scores 1 for the rock object only
  11. since it’s in normal scoring mode, the “#” doesn’t register for any object since it’s not part of any name properties
  12. the multi token considers itself successful and says so, leaving wn set a 3 (pointing to “#”)
  13. the parser sees that there is still more input to be dealt with but the “Take multi” line has no provision for more input, so that line fails
  14. no other grammar line matches in full, so it ends up with an UPTO_PE error, and that generates the error message

If the above correct, all of that makes sense, but, if it’s correct, then I don’t see what possible use could be had from the example solution for the exercise. It would always fail to do anything useful unless the player object was the only one in scope, wouldn’t it?

You can just say that I’m being an idiot. :)

I don’t have the I6 library on this laptop, but I think that’s an accurate description of the sequence of events.

The DM4 exercises never had test cases, so the solutions occasionally turn up as buggy. Or less useful or more limited than the exercise definition implies. Not much to be done about it except write down errata somewhere.

(I started doing DM4 exercise test cases in this repository: GitHub - erkyrath/Inform6Lib-Testing: Collection of unit tests for the Inform 6 library . But I didn’t get to Ex77, I’m afraid.)