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):
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
Post a Comment