pacc logo

Supporting void types

It says here to “complete” (meaning finish) support for void, but that's a bit optimistic: at the moment, void is just a funny spelling for int. One item that I think falls under this heading, and I've been planning for quite a while, is to ensure that all paths through a rule include exactly one expr for non-void rules, and exactly none for void rules.

Here's a quote from the Journal file, that's over 2 years old.

What about this idea of analysing the tree to find out the maximum possible evlis for each rule? I had imagined walking the tree at the optimization stage, and couldn't see how to communicate the information to emit(). But actually we could do it in rule_pre() as we are about to emit each rule.

Insight! If we make this a little more abstract, so it can count the maximum of any type of node, then we can raise an error if pathmax(expr) > 1 (or rule type is void and pathmax(expr) > 0):

int pathmax(struct node *n, enum s_type t) {
    int r = 0;
    struct s_node *p;
    if (n->type == alt)
        for (p = n->first; p; p = p->next) {
            int m = pathmax(p, t);
            if (m > r) r = m;
    else if (s_has_children(n->type))
        for (p = n->first; p; p = p->next)
            r += pathmax(p, t);
    else if (n->type == t)
        r = 1;
    return r;

So, let's see if that code actually comes anywhere near working! Pretty much, with a couple of minor fixes. However, it doesn't go far enough: we also need a path_min(), so we can verify that for non-void rules, both path_min() and path_max() are 1.

That's all done. Very many of the test cases had taken advantage of the fact that pacc was previously slack about enforcing the void type on rules with no expressions. (With several dozen test cases to patch up, it did cross my mind briefly to wonder if it is necessary to be so rigid. But this is so obviously the Right Thing to do, and goes a long way towards compensating the dangers inherent in type defaulting.)

Also a few test cases still had int instead of void, even though I made the latter a synonym for the former a long time ago. That all took a little while to clear up, but everything's much neater now.

Best of all, though, this enhancement fixes one of the (previously two) expected failures. The test case was this:

P ← a:A { 5 }
A ← "5"

which in very early development actually failed to terminate, hence the test case. Due to this change, it now fails because the rule A contains no expressions, yet has int type. If we change it to A :: void, then the current version of pacc attempts to declare void a, which is of course invalid C. Fixing this will be the last (I hope) piece of the puzzle in “complete support for void types”.

Last updated: 2015-05-24 19:45:26 UTC


Porting and packaging

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...

Release relief

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...

See more news articles