I have the following code written in ANTLRWorks 1.4
grammar hmm;
s : (put_a_in_b)|(put_out_a)|(drop_kick)|(drop_a)|(put_on_a);
put_a_in_b : (PUT_SYN)(ID)(IN_SYN)(ID);
put_out_a : (PUT2_SYN)(OUT_SYN)(ID) | (E1)(ID);
drop_kick : ('drop')('kick')(ID);
drop_a : (DROP_SYN)(ID);
put_on_a : (E2)(ID);
PUT_SYN : 'put' | 'place' | 'drop';
PUT2_SYN : 'put' | 'douse';
IN_SYN : 'in' | 'into' | 'inside' | 'within';
OUT_SYN : 'out';
E1 : 'extinguish'|'douse';
DROP_SYN : 'drop' | 'throw' | 'relinquish';
WS : ( ' ' | '\t' | '\r' | '\n' ) {$channel=HIDDEN;};
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
E2 : 'put on'|'don'|'wear';
COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
| '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
;
When I run it with the input:
drop object
I get a MismatchedTokenException(5 != 15).
And with the input :
put o1 in o2
I get a NoViableAltException.
Though it runs fine with
place o2 in o2
I'm new to this, but it seems like there's ambiguities? Or maybe my usage of ANTLR is incorrect?
You've put
'drop'
and'put'
in two different lexer-rules:When
put
is encountered by the lexer,PUT_SYN
will always be the rule that matches it, so'put'
could (or should) be removed from thePUT2_SYN
rule.So, your problem with parsing the string
drop object
: the parser will try to matchdrop_a : (DROP_SYN)(ID);
but the"drop"
will be matched in the lexer rulePUT_SYN
.EDIT
Those synonym-lists can be better made into parser rules (instead of lexer-rules). Here's a small demo:
When interpreting the following source:
you'll see ANTLRWorks generate the following parse-tree: