The "Rewrite The Parser in Inform 7" Project

Ron has already mentioned his reasons for doing this. I think it might be nice to have this I7 parser packaged as an extension, with copious headings as hooks for code replacement. As a basis for extensions that need to hack one part or another of the parser code, this would be much more convenient and readable than what’s currently required. I have a few extensions that hack sections of Parser.i6t: to make a simple, one-line change to the underlying parser code, you often need to include a large block of I6 code. It can be even more tiresome to make two extensions that hack the same block in different ways work together nicely. Ron’s division of the code into smaller routines and I7 constructs could make things significantly easier on both extension authors and users.

–Erik

Allow me to rephrase. I am out of the programming loop enough that however many times he’s explained it, it just went over my head, gleefully. And I never really bothered much about it, because I’m certainly not the intended audience.

And yet, I find this whole undertaking a courageous effort worthy of note.

Sorry, I think that your meaning in the original post was clear enough–I was just using your post as a springboard to say what I hope to get out of the project. To get somewhat programmy again: I haven’t had a chance to study the source in any detail, but it also sounds like there might be some useful ideas for manipulating I6 arrays from the I7 level in Ron’s code. (On the other hand, I think Ron mentioned that there will be I7 arrays in the upcoming release of Inform, which is also neat.)

–Erik

I’ve got a practical question. Going over my Speech Motivations extension (there’s got to be a better name for it…), I realized that this gives a misleading response to “’[person], [any known thing]”:

Check an actor answering something that (this is the block talking about topics rule): say "'[The topic understood]' was not recognized as something you can talk about."; stop the action.

The issue is the comma (again). The command “[person], [text]” is translated to answering it that before any I7 Understand lines can get to it… because Understand lines can’t include commas. But perhaps your I7 parser could be applied to this problem, or at least could give enough insight to include an I6 hack that could help. This is my current workaround:

Check an actor answering something that (this is the block misparsed orders rule): unless the player's command includes "tell/answer/say/shout/speak": [we assume there was a comma] say "'[The topic understood]' was not recognized as something you can ask someone to do."; stop the action;
Not ideal, but it works as long as authors don’t define any additional synonyms for ‘answer’. Unfortunately, my WIP does add some synonyms for ‘answer.’ I could just add them to the extension, but that seems like dodging the problem instead of solving it. Is there a way to say this instead?

if the player's command includes a comma

Edit: I came up with a better test: (though this still may give weird results for “tell [someone] that [any unknown thing]”)

if the topic understood matches "[any thing]"

Or better yet,

Understand "[something] [comma] [any known thing]" as informing it about.

?

Damn. Testing this turned up a bug in Scope Caching. It looks like a successfully parsed grammar line with an “any” token will cause out-of-play objects to become marked visible, which triggers Scope Caching’s modifications to Epistemology to mark them as known. Or something.

[spoiler][code]include Epistemology by Eric Eve.
Include Scope Caching by Mike Ciul.

Test is a room. Bob is a man in Test.

Check answering something that when the player’s command matches “[any thing]”:
say “[The topic understood] was not recognized as a command, but now every thing is in scope.”;

There is a rock.

After reading a command: showme the list of marked visible things.

test me with “rules/epistat rock/bob, rock/z/epistat rock”[/code][/spoiler]

(I believe the code at viewtopic.php?f=7&t=3264&start=0#p23302 fixes that issue.)

However, I am seriously considering spinning off that part of the parser to its own rulebook, as a way of shortening Parser__parse, if no other reason.

How funny, and embarrassing, that you anticipated and answered my question, and I forgot about it! I think I mainly skipped over it because it uses indexed text, but it looks like “the player’s command matches the text ‘,’” is useful in itself. I didn’ t know there was any way to detect a comma.

I’m all for spinning off parts of the parser, especially that one!

Functions that are too big to fit on one screen are a pet peeve of mine. :laughing:

Hey Ron, how is this project going? I keep coming back to it, reading a little more each time. I ran into some issues between my Lost Items and Scope Caching extensions that made me think I really need to understand the parser better. It’s quite an impressive undertaking you have here!

I was just examining the “Truth States as ‘We’ Commands” mini-extension. I’d like to see these mini-extensions available, maybe as a package if they’re too small to justify independent release. It looks very handy, and I’m impressed that it’s possible to overload phrases like “we shouldn’t” as both a “to decide if” and a “to” phrase.

I put it on pause for the Comp. Current state as of a couple weeks ago: all functions translated, but I want to test it out and maybe rename some stuff for clarity’s sake before next release. Parser__parse is very long so I’m looking into extracting certain subsections.

As for the things I call mini-extensions in there, I didn’t really feel any of them are substantial enough for independent release. I only gathered related phrases under headings like that so readers can distinguish support code from the parser itself.

I still have another round of Comp games to go through before I come back to this.

Lo and behold, version 7 and Release Candidate #1 of the Parser Rewrite project is complete. Finally, all functions within the enormous template file Parser.i6t have been translated to Inform 7, including Parser__parse(), which alone comprises 448 lines of Inform 7 code excluding interspersed comments and wrapped lines. While “parse”, as it’s now known, was split into a few functions, this was done primarily to remove GOTO statements. Many such statements still exist in parse, and many sections could be tucked away into standalone functions themselves without too much effort.

In any event, Inform 7 is a very readable language, and while rewriting and revising names of variables and phrases and the like could go on theoretically forever, my own time has become monopolized by life concerns. As the recent IF Comp wound down, so did my unemployment insurance, and so I arranged a move some 40 miles away to cheaper housing. As the fates would have it, the day after my move started I was offered a position minutes away from where I used to live. And so for the past month or so I’ve been working a new job, as a professional software developer once again, for about 11 to 12 hours a day, with an hour and a half commute each way on top of that.

So, not much time for fun stuff. Well, nothing that should be expected to be completed in any reasonable timeframe anyway.

But the sun is shining today, and my financial woes are gone, and if my biggest problem right now is a nasty commute, I consider myself lucky.

I intend to release the parser rewrite as an extension on the official Inform 7 site, but first I’d greatly appreciate some community members poke at it to see if it breaks. I can fix the odd bug here or there, and release it officially in two to four weeks, say?

Congratulations on the job, Ron!

Also on the Parser project. This is insanely exciting, though I can’t really understand it.

I had an odd thing happen when I dropped this code into the parser in place of “The lab is a room.” Typing “test me” gave me a bunch of “you can’t start with a comma” errors, even though typing the commands in the test script worked as it should.

In the thing as it is, “me, jump” causes the game to hang in the Mac IDE, though “jump” and other commands work fine.

Hope this helps!

I think I’d be willing to try it out with my WIP. I’ve been following the project with great interest, and lately I’ve been referring to your version to figure out: a) how the parser works, and b) some tips on expressing various I6 components in I7.

I even borrowed your phrase idea for expressing truth states as “we should/will/are/etc…”

Congratulations on your new job, and good luck with the new location!

Congratulations. I would not have laid money on this project being finishable. :slight_smile:

Great news (both the job and the extension)!

Curiouser and curiouser; I tried again by uncommenting the scenario (with Bob and the coins) and adding ‘Test me with “Bob, get the coin”’. It seems like I get the “You can’t begin with the comma” error when I start with “test me” and then get it again when I type “Bob, get the coin”; but if I type “Bob, get the coin” I don’t get it, and sometimes if I follow it with test me it works.

I wonder if it’s related to this bug:

inform7.com/mantis/view.php?id=860

?

I can imagine that additional parser voodoo is going on when running test commands, given their nature.

Congratulations, Ron!

This is very exciting. I hope that eventually this will become the standard parser. It will make a lot of things easier!

“me, jump” is definitely sending it into a loop – it gets to “Actor is: yourself” and then starts running NounDomain on “me” again. That’s as much as I can figure out. (And I seem to be kind of intermittent at reproducing it.)

Thank you all very much! I’m pretty happy, even if I do have to debug someone else’s javascript nowadays. (sigh)

Matt I’ll hunt that down. It didn’t occur to me to test the Test Me functionality much. I generally find bugs by turning on full trace output and running 2 Inform projects side by side, flicking back and forth as I page down the output to see where things go off the rails. Thanks for the bug hunting.

The last bug I fixed before release was rather embarassingly having an Otherwise block at the wrong level of indentation near the end of Parse. :blush: