Broken grammar in Inform 6.42

I have just upgraded my Inform 6 compiler from version 6.41 to 6.42 and grammar that I’ve been using for years is now broken. There is no mention of any grammar changes in the release notes. Here are a few examples:

Example 1
Extend only 'pry' 'prise' 'prize' 'lever' 'jemmy' 'force' replace

When compiled, this gives the error:
Warning: Verb declaration no longer has any verbs associated. Use "Extend replace" instead of "Extend only"?
in the library, not in my code. By looking at the library, I can see that these are all the verbs defined for pry, so I should delete only. Once I’ve done that, I still get an error:
Error: Expected 'replace', 'last', 'first' or '*' but found dict word 'prise'
so I delete all the verbs except the first one and ended up with:
Extend 'pry' replace

It now compiles.

Example 2
Extend only 'answer' replace

When compiled, this gives the same error as example 1.

The standard library uses four synonyms:
Verb 'answer' 'say' 'shout' 'speak'

The PunyInform library uses only three:
Verb 'answer' 'say' 'speak'

I want to replace ‘answer’ and leave the others as is. This looks to be impossible to do after applying the rules discovered in example 1. So, how do I do it?

It’s not an error, but a warning.

The relevant line in the release notes is (this pull request):

  • Grammar table lines entries which have no verb are now omitted. When this occurs a warning is printed, as this most likely indicates an oversight in the game’s source code.

As I understand it, taking your first example. The definition in the library (6.12.6) is:

Verb 'pry' 'prise' 'prize' 'lever' 'jemmy' 'force'
    * noun 'with' held                          -> Unlock
    * 'apart'/'open' noun 'with' held           -> Unlock
    * noun 'apart'/'open' 'with' held           -> Unlock;

if you use your line:

Extend only 'pry' 'prise' 'prize' 'lever' 'jemmy' 'force' replace;

or more correct, replace the verbs with something:

Extend only 'pry' 'prise' 'prize' 'lever' 'jemmy' 'force' replace;
    * noun 'with' held                          -> Unlock;

You get this warning because the two grammar lines

    * 'apart'/'open' noun 'with' held           -> Unlock
    * noun 'apart'/'open' 'with' held           -> Unlock;

no longer has any verb associated with them.

Ifd you don’t extend all the verb with all it synonyms, for example:

Extend only 'pry' 'prise' 'prize' 'lever' 'jemmy' replace;
    * noun 'with' held                          -> Unlock;

Is equal with the definition:

Verb 'pry' 'prise' 'prize' 'lever' 'jemmy'
    * noun 'with' held                          -> Unlock
    * 'apart'/'open' noun 'with' held           -> Unlock
    * noun 'apart'/'open' 'with' held           -> Unlock;

Verb 'force'
    * noun 'with' held                          -> Unlock

Taking your question (still using standard library), the definition of 'answer' is:

Verb 'answer' 'say' 'shout' 'speak'
    * topic 'to' creature                       -> Answer;

If you use:

Extend only 'answer' replace
    * 'the' 'question'                          -> Answer;

You’ll end up with the definition:

Verb 'say' 'shout' 'speak'
    * topic 'to' creature                       -> Answer;

Verb 'answer'
    * 'the' 'question'                          -> Answer;

(I don’t get any warning in the above example.)

1 Like

The errors are related to the first line of the definition only. I did not show the other lines for brevity. Obviously, I am replacing them with something, otherwise the error would be completely different.

Here is a more concrete version of example 2.

The library definition (standard library and PunyInform) is:

Verb 'answer' 'say' 'speak'
  * topic 'to' creature -> Answer;

I extend it with:

Extend only 'answer' replace
  * noun -> Take;

The rationale is that there are no NPCs, but there is a telephone. When the telephone rings, you want to GET, TAKE, PICK UP or ANSWER the telephone.

However, this grammar definition results in the following error:
Warning: Verb declaration no longer has any verbs associated. Use "Extend replace" instead of "Extend only"?

The error message is misleading. Extend replace is invalid syntax that results in another error. replace must come at the end of the definition.

Let’s not quibble over the words ‘error’ and ‘warning’. If you get a warning, it indicates that something is wrong. I will not issue games that were compiled with warnings.

Incidentally, an example of this usage in the DM4 is in §30: How verbs are parsed. Although I haven’t tried it, it looks to me like this example will no longer compile without a warning.

Extend only 'murder' 'kill' replace
  * animate -> Murder;

I pasted this code into minimal.inf (Puny 5.3.1) and compiled with 6.42 without any warnings. Do you have any other changes in your code?

I’ve nothing significant to add to the discussion, but I did encounter this warning shortly after upgrading to 6.42. Unfortunately I did not keep a note of the example, but I did find the warning message rather unhelpful and spent several hours trying to figure out what I’d done wrong and how to change my grammar to eliminate the warning.

I mean no criticism, I’m sure the warning message makes perfect sense. However, I’m very much a beginner and was rather thrown by it. I suspect a re-read of DM4 is indicated for me.

Jeremy

1 Like

No, not related to ‘answer’. Here’s another example in the same game:

Extend only 'pick' first
  * noun -> Pick
  * noun 'with' noun -> Pick;

This is so that you can pick a lock. The resultant warning is:
Warning: Verb declaration no longer has any verbs associated. Use "Extend replace" instead of "Extend only"?

Remember that these errors are detected in grammar.h (PunyInform in this case), so I don’t know where the error is actually occurring. It’s not in the PunyInform library. I have other examples of exactly the same syntax in the grammar lines that do not cause a warning, so what’s going on?

Here are all the grammar definitions related to ‘answer’, ‘say’ and ‘speak’:

Extend only 'answer' replace
  * noun -> Take;

Extend only 'say' first
  * topic -> Say;

Extend only 'speak' replace
  * -> Talk
  * creature -> Talk
  * noun -> Talk
  * 'to'/'with' creature -> Talk
  * 'to'/'with' noun -> Talk
  * 'to'/'with' creature 'about' topic -> Ask
  * 'to'/'with' noun 'about' topic -> Ask;

You will note that ‘answer’ and ‘speak’ are being replaced in their entirety, but ‘say’ is being extended. This all happens after the grammar.h file is included, so why does the compiler think that all verb definitons are gone in grammar.h? It doesn’t make sense.

The compiled game works fine in version 6.41. I haven’t yet tested it in 6.42 because of the warnings.

The following is my interpretation on what’s happening…

You should use extend only 'verb' when you want to break out a couple of synonyms and give them different grammar.

You should use extend 'verb' when you want to add a grammar to an already defined verb (with its synonyms).

You should use extend 'verb' replace when you want to replace already defined grammars for a verb and its synonyms with a new set of grammars.

The orginial definition of 'pick' is:

Verb 'pick'
	* 'up' multi                                -> Take
	* multi 'up'                                -> Take;

When you use

Extend only 'pick' first
  * noun -> Pick
  * noun 'with' noun -> Pick;

You end up with then grammar lines

	* 'up' multi                                -> Take
	* multi 'up'                                -> Take;

hanging without any verb connected to them.

The use of the token first in your definition indicates to me that you want to add grammar lines to the already defined grammar for 'pick' instead of replacing them. My interpretation is that you would want to use:

Extend 'pick' first
  * noun -> Pick
  * noun 'with' noun -> Pick;

so that you end up with the following definition of ‘pick’:

Verb 'pick'
	* noun -> Pick
	* noun 'with' noun -> Pick;
	* 'up' multi                                -> Take
	* multi 'up'                                -> Take;

In my understanding you shouldn’t use the token only if you want to extend 'say' and keep the original definitions and add to them.

The code should work the same in 6.41 and 6.42. The only change is that the orphan grammar lines are no longer in the code (they are unreachable) and that you get the warning message.

Yes, you’re right. Thanks. I keep forgetting that PunyInform has separate definitions for ‘get’, ‘take’ and ‘pick’. I got stung by that a week ago when I extended ‘take’ so that the player could ‘take water with bucket’, but it didn’t work when I used ‘get water with bucket’.

Maybe I’m out of my depth now, but I think that the tokens first, last and replace don’t have any meaning when you are using extend only, they only are meaningful with extend.

Er, really? That contradicts the example I gave earlier from the DM4:

Extend only 'murder' 'kill' replace
  * animate -> Murder;

I’ve been using this sort of thing for years without any problem. Perhaps something has changed.

1 Like

I think this is wrong.

Even when you use only, you may want to specify that the lines you add should come first, or that the existing lines should be scrapped for this verb.

1 Like

Nothing has changed, I’m wrong (hence “Maybe I’m out of my depth now”).

Trying to rephrase what I wrote higher up.

extend modifies the grammar lines for a verb and its synonyms “in place”.

extend only makes a copy of the grammar lines for a verb and connects them to a subset of that verbs synonyms.

If you use extend only for all verbs and synonyms for a definition the original grammar lines remains without any verb no longer connected to them and you get the warning. If you want to redefine all synonyms for a verb, one should be done with extend so that verb modifies on the orginal set of grammar lines.

Humour me for a moment. I have a theory. It looks like replace has a higher priority than a simple Extend. It looks like all the replacements are done first. If there is only one verb left after the replacements and you extend it using only, then it spits the dummy, as if to say “Why are you using only, you bozo? There’s only one left.”

Basically so… Maybe it could ignore the only on the last dictword and modify it in place instead, but the compiler isn’t that intelligent, yet.

Pasting the following code into minimal.inf:

Extend only 'answer' replace
  * noun -> Take;

Extend only 'say' first
  * topic -> Say;

Extend only 'speak' replace
  * -> Talk
  * creature -> Talk
  * noun -> Talk
  * 'to'/'with' creature -> Talk
  * 'to'/'with' noun -> Talk
  * 'to'/'with' creature 'about' topic -> Ask
  * 'to'/'with' noun 'about' topic -> Ask;

[SaySub ; "Nobody is interested in your rambling."; ];
[TalkSub ; "You speak for deaf ears."; ];

compiling with 6.41 and looking at the dissassembly (using UnZ):

Verb 255 no-verb
00A21 01 [ 00 02 01 00 09 42 14 57 01
           00 06 0F                   ] * topic 'to' creature -> 0x020E0 [Action #2]
.
.
.
Verb 197 'answer'
00E6C 01 [ 00 13 01 00 00 0F          ] * noun -> 0x0267C [Action #19]

Verb 196 'say'
00E73 02 [ 00 40 01 00 09 0F          ] * topic -> 0x05310 [Action #64]
         [ 00 02 01 00 09 42 14 57 01
           00 06 0F                   ] * topic 'to' creature -> 0x020E0 [Action #2]

Verb 195 'speak'
00E86 07 [ 00 41 0F                   ] * -> 0x05318 [Action #65]
         [ 00 41 01 00 06 0F          ] * creature -> 0x05318 [Action #65]
         [ 00 41 01 00 00 0F          ] * noun -> 0x05318 [Action #65]
         [ 00 41 62 14 57 52 14 EF 01
           00 06 0F                   ] * 'to'/'with' creature -> 0x05318 [Action #65]
         [ 00 41 62 14 57 52 14 EF 01
           00 00 0F                   ] * 'to'/'with' noun -> 0x05318 [Action #65]
         [ 00 03 62 14 57 52 14 EF 01
           00 06 42 0F 77 01 00 09 0F ] * 'to'/'with' creature 'about' topic -> 0x020F4 [Action #3]
         [ 00 03 62 14 57 52 14 EF 01
           00 00 42 0F 77 01 00 09 0F ] * 'to'/'with' noun 'about' topic -> 0x020F4 [Action #3]

6.42 will give you a warning and don’t compile grammar lines for verb 255, instead:

Verb 255 no-verb
00A21 00

If you change the definition of 'say' to:

Extend 'say' first
  * topic -> Say;

you get:

Verb 255 'say'
00A1F 02 [ 00 40 01 00 09 0F          ] * topic -> 0x05304 [Action #64]
         [ 00 02 01 00 09 42 14 48 01
           00 06 0F                   ] * topic 'to' creature -> 0x020D4 [Action #2]
.
.
.
Verb 197 'answer'
00E70 01 [ 00 13 01 00 00 0F          ] * noun -> 0x02670 [Action #19]

Verb 196 'speak'
00E77 07 [ 00 41 0F                   ] * -> 0x0530C [Action #65]
         [ 00 41 01 00 06 0F          ] * creature -> 0x0530C [Action #65]
         [ 00 41 01 00 00 0F          ] * noun -> 0x0530C [Action #65]
         [ 00 41 62 14 48 52 14 E0 01
           00 06 0F                   ] * 'to'/'with' creature -> 0x0530C [Action #65]
         [ 00 41 62 14 48 52 14 E0 01
           00 00 0F                   ] * 'to'/'with' noun -> 0x0530C [Action #65]
         [ 00 03 62 14 48 52 14 E0 01
           00 06 42 0F 68 01 00 09 0F ] * 'to'/'with' creature 'about' topic -> 0x020E8 [Action #3]
         [ 00 03 62 14 48 52 14 E0 01
           00 00 42 0F 68 01 00 09 0F ] * 'to'/'with' noun 'about' topic -> 0x020E8 [Action #3]

EDIT: Removed 'ask', added 'answer'.
EDIT 2: Added how verb 255 looks compiled with 6.42.

The grammar for say, ask and speak end up the same for both, right?