I have some non-reserved keywords I'm matching with rules like:
kFOO = {self.input.LT(1).text.lower() == 'foo'}? ID;
Where the ID
token is a standard alpha-numeric string. These kinds of rules work great, except when I try to do something like this:
some_rule
@after { do_something_with($t.text) }
: t=kWORD1
| t=kWORD2
| t=kWORD3
;
In the generated pars开发者_运维百科er, the kWORD1
and kWORD2
rule functions don't return anything, but the kWORD3
function does. As well, in the some_rule
function, only the block trying to match kWORD3
assign the return value to t
. The other two invocations don't reference t
in any way.
(Also, I expected the following to work, but it did not, I suspect for the same underlying reason.
some_rule
@after { do_something_with($t.text) }
: t=( kWORD1
| kWORD2
| kWORD3)
;
Nothing gets assigned to t
under any conditions.)
However, the following DOES work as expected:
some_rule
@after { do_something_with($t1.text or $t2.text or $t3.text) }
: t1=kWORD1
| t2=kWORD2
| t3=kWORD3
;
Each of the matching functions is generated to return a value, and each of the blocks matching the keyword rules in some_rule
assigns the return value to their label. The problem with this solution is it gets a little excessive when there are several more alternatives.
Half of me cries "BUG!" but this is the first antlr project I've done, so more likely there's something I don't understand.
What's the best way to do what it is I'm trying to do here?
Besides the fact that .toLower()
never matches FOO
,
I believe this is due to the fact that kWORD1 is another type of kWORD2 etc. but something that might work is this:
kWORD [String pre]
: {self.input.LT(1).text.lower() == $pre}? ID;
some_rule
@after { do_something_with($t.text) }
: t=kWORD['word1']
| t=kWORD['word2']
| t=kWORD['word3']
;
untested though.
精彩评论