One thing that pacc has lacked all the way along is users. It turns out to be really hard to write decent code without those darned users probing the dark corners.
Now, of course, there's always been one primary user of pacc: and that's pacc! (There's a reason for the recursive acronym.) And of course, the fact that pacc can compile pacc.pacc is a good sign that a lot of it fundamentally works. But still, it's all a bit parochial.
I have tried to widen the net. On two occasions, I've started converting grammars written for other parser generators to pacc. The first was Bryan Ford's pappy parser for Java. Some of pacc's features were added specifically for this project, such as | as a separator for alternatives, and bound literals. And several bugs were uncovered.
I also began converting the yacc parser for rc, which is the Plan 9 shell designed by Tom Duff and reimplemented for Unix by Byron Rakitzis.
In both cases, I have (so far at least!) failed to complete the project. Obviously this is largely due to a lack of stamina and moral fibre. Another problem is that it's hard to work on the conversion in an incremental fashion, since a grammar is a tightly knitted whole. Especially when all the expressions are utterly wrong (because they are designed for a different language), and some of the details of the parser language itself are different, and the whole point of the exercise is that pacc itself may have bugs or infelicities lurking.
Anyway, enough excuses. I've just made two changes that could ameliorate the situation somewhat. The first is that I've finally got round to implementing value inheritance (which I've also called default expressions, but I really should pick one name and stick to it).
The idea is simple enough, and has been on the todo list for ages. Suppose you have an alternative in a rule (or even a whole rule) that simply calls another rule and returns its value:
S ← t:That → t / ...
You can now omit the excess verbiage, and write simply:
S ← That / ...
As well as the saving in keystrokes, in the latter case pacc ensures that S and That have the same type, which leads to much nicer error messages than letting the C compiler pick up on type errors. (In theory pacc could detect a type mismatch in the former case too, but I think that would involve a lot of code that doesn't exist yet.)
How does this help the conversion case? For one thing, pappy supports this abbreviation. For another, it makes it simpler to change the start rule to alias some low-level rule, so you can test the grammar from the bottom up. In java.pappy, the start rule is CompilationUnit. With value inheritance, you could say:
Start :: int ← HexNumeral
and test the tiny part of the grammar that deals with HexNumerals.
Except: that will give you a bunch of rule not reached errors. No, strike that, it will give you a single rule not reached error, since that is a fatal error. I think the only reason I made it a fatal error is that I had code to hand that would report an error and die, but nothing just to report an error. So the second change was to tidy that up a bit and make rule not reached a warning.
Last updated: 2015-07-15 22:05:44 UTC
One thing pacc needs is more users. And, perhaps, one way to get more users is to reduce the friction in getting started with pacc. An obvious lubricant is packaging. Read More...
Looking at _pacc_coords(), I noticed that it seemed to have the same realloc() bug that I'd just fixed in _pacc_result(). However, the "list of arrays" trick really wasn't going to work here. Read More...