代码优先:
// 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()
(o = <I_EXIT> | o = <I_RET> | o = <I_NOP>)
看起来更好。有没有其他方法可以做到这一点?我不确定这是正确的做法..
整个jjt是here
答案 0 :(得分:2)
(o = <I_EXIT> | o = <I_RET> | o = <I_NOP>)
是一个合理的解决方案。
由于您的三个标记从语法的角度来看是完全可互换的,您还可以定义一个这样的标记类型。
TOKEN:{
<I_NO_OP: "EXIT" | "RET" | "NOP">
}
在这种情况下,您不会定义I_EXIT
,I_RET
和I_NOP
。