parsing - Ambiguous ANTLR parser rule - part 2 -


ok, after posting simple example here: ambiguous antlr parser rule

i think over-simplyfing example didn't work me. so, i'm adding real example.

here text parsed:

#ifndef _events_h #define _events_h #define events_logger_ver 3.0f /****************************************************************************************************** <start of event definitions section - not edit comment. ******************************************************************************************************/ #define evt_flow_hw_assertion_base              0x0     // hw assertion base event #define evt_flow_hw_assertion_pmg               0x1    // hw assertion detected on pmg module. module = 0x%x. status 0x%x. #define evt_i2c_section_start                   0x20 #define evt_i2c_driver_error                    0x26    //  i2c driver returns error 0x%x on device 0x%x offset 0x%x #define evt_i2c_target_device_error             0x27    //  i2c interrupt on error: status=0x%x%x #define evt_time_measurements                   0x2a    // time measurement. line : %d; spare : %d; time, : %d #define evt_dfu_after_update_state_reg          0x2d    // going dfu  (reg_reset_status = %x) #define evt_mnot_safe_debug_info_ctl_ro_p1      0xc3    // ctl ro data 0x99-0xa0: 0x%x 0x%x 0x%x 

and here grammar:

grammar eventshfile;  /*  * parser rules  */  prog : ifndefevents defineevents defineversion event+ eof;  ifndefevents : ifndef '_events_h';  defineevents : define '_events_h';  defineversion: define 'events_logger_ver' version=versionrule 'f';  versionrule:   real   ;  event : define evt_header eventname=eventnamerule hex eventid=eventidrule (comment_header commentrule)?;  eventnamerule : id;  eventidrule : hex_value;  commentrule: (id | hexargumentrule | decimalargumentrule | numericargumentrule | hex | hex_value | commentchar)+;  numericargumentrule : '%x';  hexargumentrule : hex numericargumentrule+;  decimalargumentrule : '%d';  ifndef : '#ifndef'; define : '#define';  evt_header : 'evt_';  comment_header : '//';  fragment digit                   :           [0-9];  fragment letter                  :           [a-za-z];  fragment underscore              :           '_';  fragment hexadigit     :   [0-9a-fa-f]     ;  id : letter (letter|digit|underscore)* ;  real : digit+ '.' digit+;  hex : '0' [xx] ;  hex_value : hexadigit hexadigit* ;  commentchar : ('(' | ')' | '=' | '-' | ':');  blockcomment :   '/*' .*? '*/' -> channel(hidden); ws     :   (' ' | '\r' | '\n' | '\t') -> channel(hidden); 

now, problem is, explained in previous post, eventnamerule ambiguous, , catches 'evt_' prefix, resulting in following tree (i'm adding 1 event tree, events same): enter image description here

as usual, appreciated.

thanks, busi

the lexer operates independently of parser. lexer match rule matches characters. evt_flow_hw_assertion_base id.

you define seperate lexer rule event names:

evt_id : 'evt_' id; 

put before id matched, lexer choose first rule if multiple rules match same length (evt_id , id) in case.

edit: need change event rule accordingly:

grammar eventshfile;  /*  * parser rules  */  prog : ifndefevents defineevents defineversion event+ eof;  ifndefevents : ifndef '_events_h';  defineevents : define '_events_h';  defineversion: define 'events_logger_ver' version=versionrule 'f';  versionrule:   real   ;  event : define eventname=eventnamerule hex eventid=eventidrule (comment_header commentrule)?;  eventnamerule : evt_id;  eventidrule : hex_value;  commentrule: (id | hexargumentrule | decimalargumentrule | numericargumentrule | hex | hex_value | commentchar)+;  numericargumentrule : '%x';  hexargumentrule : hex numericargumentrule+;  decimalargumentrule : '%d';  ifndef : '#ifndef'; define : '#define';  evt_id : evt_header id; evt_header: 'evt_'; comment_header : '//';  fragment digit                   :           [0-9];  fragment letter                  :           [a-za-z];  fragment underscore              :           '_';  fragment hexadigit     :   [0-9a-fa-f]     ;  id : letter (letter|digit|underscore)* ;  real : digit+ '.' digit+;  hex : '0' [xx] ;  hex_value : hexadigit hexadigit* ;  commentchar : ('(' | ')' | '=' | '-' | ':');  blockcomment :   '/*' .*? '*/' -> channel(hidden); ws     :   (' ' | '\r' | '\n' | '\t') -> channel(hidden); 

note single line comment rule wrong, doesn't match . characters. i'll leave 1 you, there should plenty of examples.


Comments

Popular posts from this blog

javascript - AngularJS custom datepicker directive -

javascript - jQuery date picker - Disable dates after the selection from the first date picker -