JastAdd
This is our old website.
Broken links can occur.
A new website is under construction.

Abstract syntax

Abstract grammars are specified in .ast files and correspond to a Java class hierarchy.

Predefined Java classes in the hierarchy:

Predefined AST class

Description

Java API for untyped traversal

ASTNode

The topmost node in the hierarchy.
The API supports "untyped" traversal of the AST.
The traversal is untyped in that you will only get nodes
typed by ASTNode, not the more specialized types
from the .ast file.

class ASTNode extends Object {
   int getNumChild();
   ASTNode getChild(int); //Numbered from 0 to getNumChild()-1
   ASTNode getParent();
}
List

Used to implement lists

class List extends ASTNode { }
Opt

Used to implement optionals

class Opt extends ASTNode { }

Abstract syntax constructs in the .ast file



Java API for typed traversal

Basic constructs



abstract A;

A is an abstract class.
A corresponds to a nonterminal

abstract class A extends ASTNode { }
B: A ::= ...;

B is a concrete subclass of A
B corresponds to a production of A

class B extends A { }
C: A ::= A B C;

C has three children of types A, B, and C.
The API supports typed traversal of the children.

class C extends A {
   A getA();
   B getB();
   C getC();
D: A;

D has no children.
D corresponds to an empty production of A

class D extends A { }
E: A ::= A [B] C* <D>;

E has a child of type A, an optional child of type B,
a list of zero or more C children, and a token of type D.

class E extends A {
   A getA();
   boolean hasB();
   B getB();
   int getNumC();
   C getC(int);
   String getD();
   setD(String);
}

Naming children



F: A ::= Foo:A Bar:B;

It is possible to name children.

class F extends A {
   A getFoo();
   B getBar();
}
G: A ::= A First:B C Second:B D;

Note! If there is more than one child of the same type, they must
be named. Here there are two children of type B. They are
distinguished with the names "First" and "Second".

class G extends A {
   A getA();
   B getFirst();
   C getC();
   B getSecond();
   D getD();
}

Typed tokens

Tokens are implictly typed by String. But you can also give a token
an explicit type.


A ::= <T>

Here, T is a token of the Java type String.
(The set method is intended to be used only by the parser, to set the
token value. This is useful when you are using JavaCC with JJTree for
parsing, since JJTree can construct the AST nodes for you, but you
will need to set the token values explicitly using the set method.)

class A extends ASTNode {
   String getT();
   setT(String);
}
A ::= <T:String>

This is equivalent to the example above.


A ::= <T:int>

Here, T is a token of the Java primitive type int.

class A extends ASTNode {
   int getT();
   setT(int);
}

Class hierarchy

The class hierarchy can contain any number of levels.


For example:

abstract A;
abstract B: A;
C: B;
D: C;
abstract class A extends ASTNode { }
abstract class B extends A { }
class C extends B { }
class D extends C { }

Inheriting children



abstract A ::= B C;
D: A;
E: A;

Children are inherited by subclasses

abstract class A extends ASTNode {
   B getB();
   C getC();
}
class D extends A { }
class E extends A { }
abstract A ::= B C;
D: A ::= F;

Subclasses can add children to those specified by the superclass.

abstract class A extends ASTNode {
   B getB();
   C getC();
}
class D extends A {
   F getF();
}

... example to be added ...

Subclasses can repeat/override children ... (to be explained)


Nonterminal attributes (NTAs)



A ::= B C /D/

A has three children: a B child, a C child, and a D child. The D child
is an NTA (nonterminal attribute): It is not created by the parser,
but must be defined by an equation. See specifying NTAs.

abstract class A {
   B getB();
   C getC();
   D getD();
}

About the implementation of Optionals and Lists

The AST representation has additional Opt and List nodes in order to implement children that are optionals or lists. The normal typed traversal API bypasses these implementation nodes, so you will not see them. But you can access the Opt and List nodes by additional implementation level traversal methods like getBOpt() and getDList() below. Note also that if you use the untyped traversal methods (getChild(), etc.), you will stop also on the Opt and List nodes. Examples:

.ast construct

Implementation structure

Java API for implementation level traversal

A ::= [B]
class A extends ASTNode {
   private Opt theBOpt; // Never null
}
class Opt extends ASTNode {
   private ASTNode theNode; // Null if child is not present
}
class A extends ASTNode {
   ...
   Opt getBOpt();
}
C ::= D*
class C extends ASTNode {
   private List theDList; // Never null
}
class List extends ASTNode {
   private ...; // Representation of the list;
}
class C extends ASTNode {
   ...
   List getDList();
}

Creating AST nodes

Use the following constructor API to create the AST. Typically you create the AST in the action routines of your parser. But you can of course also create an AST by coding it explicitly, e.g., in a test case. If you use JavaCC+JJTree, see below.

AST class

Java API for creating AST nodes

A ::= B C [D] E* <G>
class A extends ASTNode {
   A(B, C, Opt, List, String); //Arguments must not be null
}
ASTList
class ASTList extends ASTNode {
   ASTList()
   ASTList.add(ASTNode); // Returns the same ASTList object
}
ASTOpt
class ASTOpt extends ASTNode {
   ASTOpt()
   ASTOpt(ASTNode); // The argument may be null
}

Building ASTs using JJTree

If you use JJTree, the creational code is generated. You use the "#X" notation in the JJTree specification to guide the node creation.

JJTree maintains a stack of created nodes. The "#X" notation means:

  • create a new object of type X
  • pop the nodes that were created during this parse method and insert them as children to the new X node
  • then push the new X node

You need to explicitly create List and Opt nodes. When the parsing structure does not fit the abstract tree, e.g. when parsing expressions, you need to use some additional tricks. You also need to set token values explicitly. An example is available in lab 3-4 in the Lund University compiler course. Look at the CalcTree example and the file calc.jjt.