代码优先:
// 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()
我picked
(o = <I_EXIT> | o = <I_RET> | o = <I_NOP>)
看起来好多了。还有其他方法吗?我不确定这是否是正确的方法。
整个jjt为here
最佳答案
(o = <I_EXIT> | o = <I_RET> | o = <I_NOP>)
是一个合理的解决方案。
由于从语法的角度来看,您的三个标记完全可以互换,因此您还可以定义一种标记类型。
TOKEN:{
<I_NO_OP: "EXIT" | "RET" | "NOP">
}
在这种情况下,您将不会定义
I_EXIT
,I_RET
和I_NOP
。