2015-04-01 82 views
0

OK,在這裏張貼一個簡單的例子後: Ambiguous ANTLR parser rule曖昧ANTLR解析器規則 - 第2部分

我認爲,過度simplyfing的例子並沒有爲我工作。 因此,我現在添加一個真實的例子。

這裏要分析的文本:

#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_'前綴,導致以下樹(我添加了一個事件樹,所有事件看起來都一樣): enter image description here

像往常一樣,任何幫助表示讚賞。

謝謝, 布絲

回答

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); 

請注意,您的單行註釋規則也是錯誤的,因爲它不符合.字符。我會把那個留給你,應該有很多例子。

+0

嗨阿德里安,感謝您的答覆。我理解你的邏輯,但恐怕這是行不通的。 – baruchl 2015-04-05 08:05:39

+0

@baruchi把你試過的東西放在你的問題中。 – 2015-04-05 10:38:54

+0

'eventNameRule:EVT_ID; EVT_ID:EVT_HEADER ID; EVT_HEADER:'EVT _';' 仍然得到了和以前一樣的確切結果。 (對不起,格式不正確,評論編輯器有些困難......) – baruchl 2015-04-06 05:48:49