You can't inject just any production or terminal into your AST which are not matched in the parser rule you're creating the AST for. In your case, you can insert plus
or minus
since they are matched by the parser rule, but you can't insert plus_special
or minus_special
since these are not matched by the parser rule num_addition
.
You can inject imaginary tokens though.
Try something like this:
grammar T;
tokens {
// Some imaginary tokens:
PLUS_SPECIAL;
MINUS_SPECIAL;
}
// ...
num_addition
: (a=num_multi -> $a) ( PLUS b=num_multi -> ^(PLUS_SPECIAL $num_addition $b)
| MINUS b=num_multi -> ^(MINUS_SPECIAL $num_addition $b)
)*
;
// ...
PLUS : '+';
MINUS : '-';