* Trash Web
Changes Index Search

Webs Book Compare GPCE06 Gmt Gpce Gpce04 Gpce05 IFIPWG211 IPA06 Main Octave PEPM07 PEPM08 PHP Sandbox Sdf Stratego Sts TWiki Tiger Tools Transform Variability default porn free porn

Day 7

It is important that you run Eclipse 3.7 with an unstable built of Spoofax. All other combinations are likely not to work. Before you start this assignment, you need to update the following files in your project:

  • assignment1/MiniJava.tbl
  • lib/nbl-library.custom
  • trans/minijava.str

Name Binding

Spoofax' new Name Binding Language (NBL) is a declarative metalanguage for the specification of name bindings in terms of namespaces, definition sites, use sites, and scoping rules.


In NBL, a namespace is a collection of names and is not necessarily connected to a specific language concept. Different concepts can contribute names to a single namespace. For example, in MiniJava variables and parameters contribute to the same namespace. Namespaces are declared in a namespace section.

module names

namespaces Class

You can copy this content into a file trans/name.nd. Next, you should extend the namespace section with all namespaces of MiniJava.

Definition and Use Sites

Once you defined namespaces, you can define name bindings with rules of the form pattern : clause*, where pattern is a term pattern (like in rewrite rules) and clause* is a list of name binding declarations about the language construct that matches with pattern. For example, the following rule declares definition sites for class names:


Class(c, _, _, _): defines Class c

Use sites which refer to definition sites of names can be declared similarly. For example, the following rule declares use sites of class names:

Parent(c): refers to Class c

Identify definition and use sites of names in MiniJava and define the corresponding rules.

Editor Integration

When you save trans/names.nd, Spoofax generates automatically a file trans/names.str. This file contains Stratego code implementing name analysis based on the rules you provided. To use this implementation, you should import it into trans/minijava.str. When you open a MiniJava program and inspect its analysed abstract syntax, you will find definition and use sites of names annotated with URIs. For example, Class("c", ...) will become Class("c"{[Class(), c]}, ...). In trans/minijava.str you can also find boilerplate code for reference resolution (editor-resolve) and code completion (editor-complete). You can register these strategies in as reference resolver in editor/MiniJava-References.esv and completion proposer in editor/MiniJava-Completions.esv. After a build, you can try these editor services in a MiniJava editor.


In the current state, all names are globally visible in your project. Thus, you can refer to classes in other MiniJava programs, which reside in the same Eclipse project. Scopes restrict the visibility of definition sites. For example, a class scopes fields that are not visible from outside the class. This can be specified in NBL by extending the rule for classes with a scopes clause:

Class(c, _, _, _): 
  defines Class c
  scopes Field

Scopes can be nested and name resolution typically looks for definition sites from inner to outer scopes. As in the class example, scopes are often also definition sites. However, this is not a requirement. For example, a program has no name, but scopes its classes:

Program(_, _): 
  scopes Class

Extend your name binding rules with scopes clauses to scope all definition sites.

Name Checking

Similar to type checking, you can realise name checking in terms of constraints, which are implemented as rewrite rules.

The Index

Spoofax stores all definitions and references in an in-memory data structure called the index. By collecting all this summary information about files in a project together, it ensures fast access to global information. The index is updated automatically with changes to the file system (e.g., files being deleted or removed) and is persisted as Eclipse exits. All entries in the index have a URI. Index entries can be represented as terms and accessed by an API. For example, =Def([Class(),"c", Anon("12")]) is a definition entry for a class. Internally, index entries are stored in tables for efficient random access. They also contain meta-data such as the file name and line number of the definition. With this meta-data, Spoofax can provide editor services such as reference resolving.

Naming Constraints

You can use the index API to detect duplicate definitions, missing definitions, and unused definitions:

  Class(c, _, _, _) -> (c, $[Multiple declarations for class [c]])   
    where [_, _|_] := <index-lookup-all> c

  Parent(c) -> (c, $[Class [c] is not defined])
    where <index-is-unresolved> c

  Class(c, _, _, _) -> (c, $[Unused class [c]])   
    where <index-is-unused> c

Interaction with Type Analysis

Types of Definition Sites

Spoofax can also store type information about the definition sites of names in the index. For example, to determine the type of variable references, Spoofax needs to store the type of the corresponding declarations. Consider the following name binding rules which also involve type information:

Var(t, v): defines Variable v of type t

Spoofax uses this rule to determine the type of a variable declaration. This type is stored as an information about the variable name.

Types of Use Sites

Stored type information can then be used in the typing rules for variable references:

type-of: VarRef(x) -> <index-type-of> x

Types can also determine the context, in which a name should be resolved. For example, in a method call, the type of the first expression determines the callee. This can be expressed in NBL as follows:

Call(e, m, _):
  refers to Method m in Class c
  where e has type ClassType(c)

At this point, you can complete your type system and add missing type constraints.

%GS% Challenge: Try to type this. First, pretend that This() refers to a field This(). Second, define a typing rule which determines the type based on the annotated URI. You can retrieve the path of the URI with index-uri-path.


Inheritance defines a subtyping relation between super- and subclasses.

%GS% Challenge: Use the index to implement a subtyping relation. First, store inheritance relations as type information. Second, implement a strategy parent, which rewrites a class name to the name of its parent class. Next, implement a strategy ancestor, which rewrites a class name to a list of its ancestors' names. Make sure that this strategy does not cycle, even in the presence of cyclic inheritance. Finally, implement a strategy subtype, which succeeds on a pair of types, if the first type is a subtype of the second type.

Furthermore, it makes fields of the superclass available to the subclass. This can be expressed in NBL in terms of an import:

Class(c, Parent(p), _, ms):
  defines Class c
  scopes Field
  refers to Class p
  imports Field from Class p {transitive}

In the current version of NBL, it is important to specify the import on the class level. This might require an adaptation of your existing name binding rules for classes. You can now check inheritance-related constraints. Therefor, you should use import-related strategies from the index API. For example, you can check for overriding fields:

  Field(_, f) -> (f, $[Overriding field [f]])   
    where <index-lookup-imported> f

-- GuidoWachsmuth - 11 Oct 2012

Trash.Day7 moved from CC.Day7 on 13 Mar 2014 - 08:28 by GuidoWachsmuth - put it back