Old NTA syntax requires lazy

Issue #72 resolved
Jesper Öqvist
created an issue

When declaring an NTA attribute using the old style (in the abstract grammar), the attribute definition needs to be defined as lazy. Otherwise, the attribute will be computed every time the attribute is used. Example:

A ::= /B/;
B;

syn B A.getB() = new B();

Test program:

import AST.*;
public class Test {
    public static void main(String args[]) {
        A a = new A();
        System.out.println(a.getB());
        System.out.println(a.getB());
    }
}

And when running:

$ java -jar jastadd2.jar --rewrite --package=AST lang.ast aspect.jrag 
$ javac AST/*.java Test.java 
$ java Test
AST.B@33f42b49
AST.B@86c347

Note that two objects of type B are created! The --rewrite flag is also required, because without it JastAdd2 creates Java code that contains compile errors.

Quick fix, make the attribute lazy:

syn lazy B A.getB() = new B();
Version: JastAdd2 R20120427

Note that the syn NTA syntax does not require the attribute to be defined lazy.

syn nta B A.getB() = new B();

Here, the NTA is implicitly lazy.

Comments (3)

  1. Jesper Öqvist reporter

    Always cache abstract grammar declared NTAs

    • Renamed the AttrDecl.isLazy() attribute to AttrDecl.isMemoized().
    • AttrDecl.hasCache() was removed since it was equivalent to AttrDecl.isMemoized().
    • Inlined AttrDecl.shouldCache(CacheMode) into AttrDecl.isMemoized().
    • Simplified boolean conditionals (isMemoized() || isCircular()) using the fact that isCircular() is implied by isMemoized().

    fixes #72 (bitbucket)

    → <<cset 01fa9ca200ef>>

  2. Log in to comment