Before I fling myself into the swirling madness of rewriting a bunch of basic grammar rules, is there a simple way to handle something like >PUT PEBBLE ON TABLE AND ROCK ON SHELF?
What I want is for this to be handled like >PUT PEBBLE ON TABLE and >PUT ROCK ON SHELF, but it’s treated like PUT PEBBLE ON TABLE ON SHELF and PUT ROCK ON SHELF. That is, the first noun phrase isn’t parsed as an object and direct object for the action (PEBBLE and TABLE), but instead as a single prepositional phrase describing one object (PEBBLE ON TABLE).
Rewriting the command as >PUT PEBBLE ON TABLE AND PUB ROCK ON SHELF has the desired effect, but I’d rather the parser be less picky; I’m creating situations in which the player might reasonably try this sort of thing and I think the default handling might lead to confusion.
I don’t know how you’d get all the squishy special cases without implementing this as a grammar rule.
Of course I’m not currently sure how you would implement it as a grammar rule either right now. The underlying problem is that you can implement a rule with no badness that will always win, regardless of whether the first noun phrase actually does make sense for the default parser behavior. Or you can make a rule with a badness, which will then never win, because the tricky bit is in noun resolution.
I don’t think there’s any way to implement a parallel rule either, because the rule that wins by default (with the stock parser) is commandPhrase(definiteConj), which is a wildcard rule.
My next thought was to tweak CommandProdWithDefiniteConj (the class used by the commandPhrase(definiteConj) grammar rule), but (afaik) there isn’t any straightforward way to short-circuit parsing in the rule’s resolveNouns(). Like you could always just throw a ReplacementCommandStringException with a slightly modified command string. But that would require, as far as I can tell, re-implementing all the command ranking logic inside resolveNouns() to figure out if the command would fail later.
I think you’d struggle to implement this in any existing IF system, and I also think not many people playing the game would expect such a grammatical construction to be accepted by the parser (for the same reason – we’ve gotten used to the limitations of current parsers).
I wouldn’t say this is exactly straightforward, but as it turns out I’ve previously done a bunch of work on modularizing the T3 parser and command execution cycle. So I can definitely catch the default failure and use that as a hook to try parsing using a different top-level grammar that behaves the way I want it to.
I was just hoping for something a little less…bespoke.