Groovy for Domain-specific Languages - Second Edition

(nextflipdebug2) #1
Chapter 8

[ 201 ]

A state machine AST transformation


Unlike the previous examples, we won't need an annotation class for a global AST
transformation. AST transformation would get quite unwieldy if we tried to build
all the logic into the AST transformation class, so we separate out the responsibilities
into four classes:



  • StateMachineASTTransformation: This is the GroovyASTTransfromation
    class similar to the ones we already encountered in our annotation-based
    examples.

  • StateMachineParser: This class implements the GroovyClassVisitor
    interface. This class uses a visitor pattern to allow us to work on any part
    of the tree of AST nodes in our compiled source. The main responsibility of
    this class is to produce a simple data model to store the key elements of the
    state machine.

  • StateMachineModel: This class stores the data model of the parsed state
    machine. It describes the possible states, the initial state, the available events,
    and the allowed transitions for each event.

  • StateMachineBuilder: This class builds the new AST nodes we need to
    implement the state machine pattern.


@GroovyASTTransformation (phase = CompilePhase.SEMANTIC_ANALYSIS)
class StateMachineASTTransformation implements ASTTransformation {
def parser
def builder

void visit(ASTNode[] nodes, SourceUnit source) {
if (!nodes) return
if (!(nodes[0] instanceof ModuleNode)) return
if (!source?.name?.endsWith('State.groovy')) {
return
}
def model = new StateMachineModel()

parser = new StatePatternParser(model)
builder = new StatePatternBuilder(nodes, model)

for (ClassNode classNode : nodes[0].classes) {
classNode.visitContents(parser)
}

builder.buildStatePattern()

}
}
Free download pdf