Template construction
ANTLR v3 has built-in support for constructing StringTemplate templates. there are two forms: Special symbols in actions and rewrite rules similar to AST construction. I am including a number of rules from the mantra example.
Sometimes you just need a string to become a template:
'void' -> {%{"void"}}
The following tree grammar rule illustrates some of the basic rewrite rules:
primary
: ID -> {%{$ID.text}} // create template from token text
// create template using rule results as template attributes
| ^('new' typename args=expressionList)
-> new(type={$typename.st},args={$args.st})
| listliteral -> {$listliteral.st} // reuse template built for listliteral
// create template using token text as template attribute
| NUM_INT -> int_literal(v={$NUM_INT.text})
;
And here are some more complicated examples:
assignment
: // special case "a[i] = expr;"
^('=' ^(EXPR ^(INDEX a=expression i=expression)) rhs=completeExpression)
-> indexed_assignment(list={$a.st}, index={$i.st}, rhs={$rhs.st})
| ^('=' lvalue completeExpression)
-> assignment(
lhs={$lvalue.st},
rhs={$completeExpression.st})
| ^(assign_op lvalue completeExpression)
-> assignment_with_op(
type={$assign_op.start.type.name},
op={$assign_op.text},
lhs={$lvalue.st},
rhs={$completeExpression.st})
;
When you need to append multiple strings or templates into a another template use the += operator for a rule's return value (former use of toTemplates no longer required). For example adding variable declarations inside a struct template :
structDeclaration
: name=Ident (decls+=typeDecls)+ -> structDecl(name={$name.text},declList={$decls});
;
and the templates for a struct declaration may be something like this :
structDecl(name,declList) ::= <<
struct <name> {
<declList; separator="\n">
}
More on string templates can be found here: String Template