好的,在这里发布一个简单的例子后: Ambiguous ANTLR parser rule
我认为过度简化这个例子并不适合我。 所以,我现在正在添加真实的例子。
以下是要解析的文字:
#ifndef _EVENTS_H
#define _EVENTS_H
#define EVENTS_LOGGER_VER 3.0f
/******************************************************************************************************
<Start of event definitions section - Do not edit this 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 is 0x%x.
#define EVT_I2C_SECTION_START 0x20
#define EVT_I2C_DRIVER_ERROR 0x26 // I2C driver returns with 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, us : %d
#define EVT_DFU_AFTER_UPDATE_STATE_REG 0x2D // Going to 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
这是语法:
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);
现在,问题是,正如前一篇文章中所解释的那样,eventNameRule可能是不明确的,它捕获'EVT_'前缀,导致后面的树(我添加了一个事件树,所有事件都看起来像相同):
像往常一样,任何帮助都表示赞赏。
谢谢, 布丝
答案 0 :(得分:0)
词法分析器独立于解析器运行。词法分析器将匹配与大多数字符匹配的规则。对于EVT_FLOW_HW_ASSERTION_BASE
,这是ID
。
您可以为事件名称定义单独的词法分析器规则:
EVT_ID : 'EVT_' ID;
将它放在ID
之前,以便匹配,因为在这种情况下,如果多个规则匹配相同的长度(EVT_ID和ID),词法分析器将选择第一个规则。
编辑:您需要相应更改event
规则:
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);
请注意,您的单行注释规则也是错误的,因为它与.
个字符不匹配。我会把那个留给你,应该有很多例子。