...
Sometime I think I will spend a couple of weeks and try to build one myself ANTLR-style. The first thing I realize is that concrete syntax, while beautiful, is not always powerful enough to do what we want (I suppose it could be an option). For example, what if you want to match a series of identifiers and transform them to something else? You need some kind of repetition operator inside the strings of concrete syntax, but why invent new syntax. We have grammars to specify languages. Grammars both recognize and generate language as you see in ANTLR parser grammar to treat grammar fragment rewrite rules. So, I propose something more along the lines of grammar to grammar transformations. Elements on the left are available as streams of data to the template on the right-hand side:
No Format |
---|
exprvar: type ID (',' ID)* -> (type ID ';')+ |
...
You could also go to text instead of a token stream. In this case, the output grammar would actually be a StringTemplate (an "unparser"). For example, the following transformation would convert the token stream matched on the left hand push all of the elements into the attributes of the template on the right:
No Format |
---|
exprvar: type ID (',' ID)* -> "<type> <ID; separator=\", \">" |
...
A rewrite rule is applicable when the left-hand side matches the input in the context of the specified rule, such as expr above. The context means "what rule am I matching?" Context is important, because you might want to do something different depending upon context. For example, you might want to do do something different for variable declarations matched at the class level (fields) and for variables matched in methods (locals):
No Format |
---|
[classDef var]: // context is "field"
type ID -> blort
[... method var]: // context is "local"
type ID -> blech
|
The "..." means anything on the stack of rule vacations. The entire context for the local rebels then is a var rule match within a method rule.
One could also imagine wanting to combine contexts into a single translation if fields and locals are separated in the grammar:
No Format |
---|
[localVar | field]:
type ID -> blort
|
Arbitrary semantic content
No Format |
---|