antlr - What is wrong with this grammar? (ANTLRWorks 1.4) -


i have 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 run input:

drop object 

i mismatchedtokenexception(5 != 15).

and input :

put o1 in o2 

i noviablealtexception.

though runs fine with

place o2 in o2 

i'm new this, seems there's ambiguities? or maybe usage of antlr incorrect?

you've put 'drop' , 'put' in 2 different lexer-rules:

put_syn  : 'put' | 'place' | 'drop';          // drop & put put2_syn : 'put' | 'douse';                   //        put ... drop_syn : 'drop' | 'throw' | 'relinquish';   // drop 

when put encountered lexer, put_syn rule matches it, 'put' (or should) removed put2_syn rule.

so, problem parsing string drop object: parser try match drop_a : (drop_syn)(id); "drop" matched in lexer rule put_syn.

edit

those synonym-lists can better made parser rules (instead of lexer-rules). here's small demo:

grammar textadventure;  parse   :  command (endcommand command)* eof   ;  command   :  put_syn_1 otherword in_syn otherword   |  put_syn_2 out_syn_1 otherword   |  out_syn_2 otherword   |  drop kick otherword   |  drop_syn otherword   ;  drop_syn   :  drop   |  throw    |  relinquish   ;  in_syn   :  in   |    |  inside   |  within   ;   put_syn_1   :  put   |  place   |  drop   ;  put_syn_2   :  put   |  douse   ;  out_syn_1   :  out   ;  out_syn_2   :  extinguish   |  douse   ;  space      : (' ' | '\t' | '\r' | '\n'){$channel=hidden;}; endcommand : ';'; put        : 'put'; place      : 'place'; drop       : 'drop'; douse      : 'douse'; in         : 'in';       : 'into'; inside     : 'inside'; within     : 'within';     out        : 'out'; extinguish : 'extinguish'; throw      : 'throw'; relinquish : 'relinquish'; kick       : 'kick'; otherword  : ('a'..'z' | 'a'..'z')+; 

when interpreting following source:

drop object ; put in myshoes ; place in avase 

you'll see antlrworks generate following parse-tree:

alt text


Comments

Popular posts from this blog

unicode - Are email addresses allowed to contain non-alphanumeric characters? -

C#: Application without a window or taskbar item (background app) that can still use Console.WriteLine() -

c++ - Convert big endian to little endian when reading from a binary file -