AspectG

(Internal classification: major example)

Reference paper: “Domain-Specific Aspect Languages for Modularizing Crosscutting Concerns in Grammars” Damijan Rebernak, Marjan Mernik, Hui Wu, Jeff Gray, In IET Software, To Appear

The reference discusses both AspectG and AspectLISA

Domain of the language

The definition of programming languages (grammars) and compiler construction. An important problem in this area is the modularity, reusability and extensibility of a language specification. AOSD is used here to modularize semantic concerns that crosscut many language components described in the grammar.

From the reference paper: “Within a language specification, modularization is typically based on language syntax constructs (e.g., declarations, expressions and commands). Adding new functionality to an existing language sometimes can be done in a modular way by providing separate grammar productions associated with the extension. For example, additions made to specific types of expressions within a language can be made by changing only those syntax and semantic productions associated with expressions. […] there are certain types of language extensions (e.g., type checking, environmnent propagation, code generation) that may require changes in many (if not in all) of the language productions represented in the grammar. […] the various concerns associated with each language tool are often scattered throughout the core language specification. Such language extensions to support tool generation emerge as aspects that crosscut language components”

AspectG is a DSAL for ANTLR grammars. (ANTLR stands for ANother Tool for Language Recognition) ANTLR is a parser generator that facilitates the building of language tools, it uses EBNF notation for grammar specification. Tokens are defined using regular expressions and semantic actions are written in a General Purpose Language (GPL).

Intent of the language

AspectG allows for the creation of different tools on top of an existing language specification, by adding additional semantic actions (written in Java) inside the grammar productions. It is not unusual for such tools to add the similar semantic actions across (parts of) the grammar, hence the cross-cutting nature.

Note that the authors claim that AspectG could be language-independent, as it does not matter which language is the generated target, neither which GPL is used to specify the semantic actions.

Comparing AspectLISA and AspectG in one line: AspectLISA allows for extension of the base language, AspectG allows for the definition of new tools on an existing grammar.

Join Point Model and Advice Model

  • JPM: Domain-Specific : Matches are on both the syntax of the grammar and the semantic actions.
  • AM: General-Purpose : Semantic actions are written in Java (could be any GPL)

Anatomy of the language

The structure of AspectG pointcuts is similar to AspectJ pointcuts, except that they use either the within predicate to filter on grammar productions, the match predicate to filter on semantic rules, or a boolean operation of these.

  • within pointcuts can use the * wildcard to match on zero or more terminal or non-terminal symbols.
  • match pointcuts test whether their argument is a substring of the semantic actions.

“The advice are semantic rules written as native Java statements that can be applied at join points specified by pointcuts” (Rebernak et. al.). As the order of execution of these statements is relevant (in contrast to AspectLISA), advice execution specifies before or after. As a result, advice code is virtually identical to AspectJ advice code.

Typical Example

As the base language: ANTLR is a DSL, we first include an example of code in ANTLR. This is an excerpt of the same robot example as in AspectLISA.

root :(
  BEGIN
    {fileio.print("int x =0; int y = 0; int time = 0;"); }
    commands
    END EOF!);
commands:( command commands | );
command :(
  LEFT    {fileio.print("x=x-1;"); fileio.print("time=time+1;");}
  |RIGHT  {fileio.print("x=x+1;"); fileio.print("time=time+1;");}
  |UP    {fileio.print("y=y-1;"); fileio.print("time=time+1;");}
  |DOWN  {fileio.print("y=y+1;"); fileio.print("time=time+1;");});

The first pointcut below matches all command productions within the above example, the second is an illustration of a boolean expression of predicates, matching all command productions that increase the time counter (which again matches all productions).

pointcut productions(): within(command.*);
pointcut count_gpllinenumber():
  within(command.*) && match(fileio.print("time=time+1;"));

The following advice is used as part of a debugging tool for the robot language

before(): productions() {dsllinenumber++; }
after():  count_gpllinenumber() {
  gplendline=fileio.getLinenumber();
  filemap.print("mapping.add(newMap("
    + dsllinenumber + ",Robot.java,"
    + gplbeginline + "," + gplendline + "));"); }

Enforced Restrictions

AspectG can only add extra semantic actions to rules in the underlying grammar. The code for these rules, in a GPL, is however simply merged into the grammar (the weaver is a preprocessor). There is no verification of these actions whatsoever, which is why the authors claim AspectG could be language-independent.

Implementation description

Aspects are woven into the ANTLR grammar itself, in a preprocessor approach. The preprocessor uses an ANTLR-built ANTLR parser together with low-level matching and transformation operations on the AST of the ANTLR source. Aspects are treated as a set of rewrite rules, the weaver applies these rules until no more matching rules can be found.