grappa icon indicating copy to clipboard operation
grappa copied to clipboard

Recursive rules passing different Var instances should be possible

Open akirschbaum opened this issue 10 years ago • 1 comments

When using rules that have parameters, @Cached can be used to allow recursive calls. The generated caching code then checks all parameters for equality when reusing rules.

This mechanism works fine for rules like

@Cached
public Rule rule(boolean flag) {
    return flag ? rule(false) : sequence("a", "b");
}

(Please ignore that this rule does not make much sense; I just needed a simple example for a rule definition with a structure that depends on the method's parameter.)

Quite often I need code like

@Cached
public Rule rule(Var<Integer> count) {
    Var<Integer> tmp = new Var<>();
    return firstOf(
        sequence("c", count.set(0)), 
        sequence("b", rule(tmp), count.set(tmp.getNonnull()+1), "b")
    );
}

That is: a recursion where the rule definition structure does NOT depend on the method's parameter but in which a different parameter is passed in each recursion level.

Such rules are currently not possible because the generated caching code never finds a match and therefore causes an infinite recursion during parser generation.

akirschbaum avatar Apr 28 '15 20:04 akirschbaum

Such rules are currently not possible because the generated caching code never finds a match and therefore causes an infinite recursion during parser generation.

Yes, that's what happens.

Unfortunately this is not curable with the current system; the day when indy is used I can probably fix this... But I'm far from being done with indy at all!

fge avatar May 09 '15 08:05 fge