11
votes

I've been helping augment a twenty-some year old proprietary language within my company. It is a large, Turing-complete language. Translating it to another grammar regime (such as Antlr) is not an option (I don't get to decide this).

For the most part, extending the grammar has gone smoothly. But every once in awhile I'll get a reduce-reduce or shift-reduce that

  • is difficult to eliminate
  • sometimes just doesn't make sense (to my feeble brain)

After a lot of painful staring at y.output files and experimental grammar refactorings, I've usually gotten where I wanted to go. Sometimes I've had to make unsatisfactory compromises.

So, are there any tools out there which can suck in a yacc grammar, which enhance browsing, experimenting, and allow debugging of changes?

If I add a production, I'd like to see more than "atomic production that is used everywhere" (think identifier) "conflicts with rule foo" (yes, there is more info, s/r, r/r, than that, but I think you get my drift). It would be nice to have some hint of the interplay beyond putting on my thinking cap and trying to imagine a symbol stack and state machine.

Update: I guess I should clarify. We use Berkeley Yacc. I have been testing using a recent version of Bison. For output, I've compiled the grammar with --report=itemset.

My goal with this post is to seek out external tools which augment the grammar debugging facilities which ship with yacc. It's painful today with the default set. Help me find better interactive tools, such as those you can use with Antlr.

2

2 Answers

7
votes

You might get some help from yacc -d, which produces debugging output -- it basically gives a full listing of the symbol stack states and such. The output is dense and voluminous, so trying to read all of it directly rarely accomplishes much (never has for me anyway). However, when you make a change the gives (for example) an r/r conflict, you can run yacc -d on the old grammar and the new one, then run diff on the results, to get a much more detailed run-down on what change(s) caused the conflict.

It's probably worth noting, however, that s/r conflicts are often benign -- unless you're fairly sure it's a problem, trying to "fix" it often isn't worthwhile. The same is not true with r/r conflicts though. While these are sometimes benign, it's comparatively rare.

Edit: Oops -- sorry, that should be -v. You mention y.output, so you apparently already know how to do that part. The point is that you don't try to look at the y.output files directly, but do a diff between the one that came out cleanly and the one that didn't to get some detail about the actual conflict (without staring at 10 jillion lines of "stuff" that's just fine.