...
In this case, whatever was matched for the type
rule would be replicated for each identifier match on the input stream. Input tokens int i,j
would become output token stream int i; int j;
. This token stream could then be repeatedly processed by the rules until nothing had changed, signifying the end of translation. Naturally, one could design rewrite rules that flip back and forth between two patterns causing an infinite loop. This is a well-known problem and rewrite systems. I'm satisfied to send the call that a bug in your rewrite rules, though I'm sure I could come up with something nice to let you know precisely which rules were the problem.
Rewrite rule precedence
Rewrite rules specified first would be given precedence over those specified later. There is therefore no notion of an ambiguous rewrite rule to match. The first one that matches, wins. So, be careful that you get the order right. In the following case, a cast expression will never be matched because it is mentioned after the parenthesized expression.
No Format |
---|
expr:
'(' expr ')' -> whatever
'(' ID ')' expr -> somethingelse
|
Generating text rather than tokens
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 |
---|
expr: type ID (',' ID)* -> "<type> <ID; separator=\", \">" |
Grammatical context
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?"
Arbitrary semantic content
...