Reputation: 7750
Code first:
// I need, but not allowed
o = (<I_EXIT> | <I_RET> | <I_NOP>)
// Work around, the generated code will do double switch
(o = <I_EXIT> | o = <I_RET> | o = <I_NOP>)
// Work around, introduce new token, will warning
// Warning: Line 59, Column 11: Regular Expression choice : XXX can never be matched as : XXX
// Consider this is a bad practice.
TOKEN:{
<I_NO_OP: <I_EXIT> | <I_RET> | <I_NOP>>
}
o = <I_NO_OP>
// Work around, introduce new grammar, generate double switch with one more function call, looks awful.
Token oneOp():{
Token t = null;
}{
(t = <I_CALL> |t = <I_PUSH> |t = <I_POP> |t = <I_JPC>){return t;}
}
...
o = oneOp() a = operand()
I picked
(o = <I_EXIT> | o = <I_RET> | o = <I_NOP>)
It's looks better. Is there any other way to do this ? I'm not sure is this the right way to do this..
The whole jjt is here
Upvotes: 1
Views: 651
Reputation: 16231
(o = <I_EXIT> | o = <I_RET> | o = <I_NOP>)
is a reasonable solution.
Since your three tokens are completely interchangeable from a syntactic point of view, you could also define one token kind like this.
TOKEN:{
<I_NO_OP: "EXIT" | "RET" | "NOP">
}
In this case, you would not define I_EXIT
, I_RET
, and I_NOP
.
Upvotes: 3