Old NTA containg new NTA + circular attribute => loop

Issue #6 duplicate
Jesper Öqvist created an issue

Click here to view original trac ticket.

This is the original issue description from the Trac server:

The attached files results in a program that is stuck in an endless loop when running it. The bug was observed in connection with the development of the Oberon-0 compiler.

The attached JastAdd specification contains an NTA (using the old syntax) that has a child, which is also an NTA (but using the new syntax). The child NTA contains a node that has a circular attribute. The idea is that the top-level NTA is used for predefining standard types. The user can then define new types using the already defined types, such as the standard types. The circular attribute is then used to identify circular dependencies between type definitions. See the attached files for more details. It works fine if: The top-level NTA is defined as lazy, or: The top-level NTA is defined using the new syntax instead of the old one

These are the attached files:


Start ::= TypeDef /PreTypes/; 

TypeDef ::= <Name> Type;

abstract Type;
Bool : Type;
Use : Type ::= <Name>;


aspect PredefinedTypes {
  syn PreTypes Start.getPreTypes() = new PreTypes();
  syn nta TypeDef PreTypes.getTypeDef() = new TypeDef("BOOLEAN", new Bool());

aspect NameAnalysis {
  syn TypeDef Use.decl() = lookup(getName());
  inh TypeDef Use.lookup(String name);
  eq Start.getTypeDef().lookup(String name) {
    if (getPreTypes().getTypeDef().getName().equals(name)) {
      return getPreTypes().getTypeDef();
    return null;

aspect TypeAnalysis {
  syn boolean Type.isCircular() circular [true] = false;
  eq Use.isCircular() { 
    if (decl() == null) {
      return false;
    return decl().getType().isCircular();


public class Test {
  public static void main(String args[]) {
    Use u = new Use("BOOLEAN");
    TypeDef t = new TypeDef("t", u);
    Start start = new Start(t);

    //System.out.println("decl(): " + u.decl());
    System.out.println("isCircular: " + u.isCircular());

The bug is caused by the NTA Start.getPreTypes() not being declared lazy while also being declared using the AST NTA syntax (Start ::= /PreTypes/). See issue #72 and issue #228.

Comments (3)

  1. Jesper Öqvist reporter

    I marked this issue as a duplicate of #72 because that one is more focused on the core problem: that an NTA in some cases can be non cached. The circular attribute is hindered from completing because new NTA nodes are created over and over again with fresh caches.

  2. Log in to comment