2014-02-06 39 views
0

我仍然試圖使用ANTLR解析簡單的Javadoc樣式格式。基本格式如下:返回默認模式使用Island語法而不使用令牌

/** 
* Description 
* 
* @name someId 
*/ 

我的解析器語法是在這裏:

query_doc  : BEGIN_QDOC description name NOMANSLAND* END_QDOC; 

description  : (DESCRIPTION_TEXT | NOMANSLAND)*; 

name   : OPEN_NAME INNER_WS NAMEID INNER_WS* CLOSE_NAME; 

我的詞法語法是在這裏:

BEGIN_QDOC   : '/**'; 


END_QDOC   : ('*/'); 


NOMANSLAND   : '\r'? '\n' (' ' | '\t')* '*' (' ' | '\t')*; 


DESCRIPTION_TEXT : ~('\n'); 


OPEN_NAME     : '@name' -> mode(NAME); 

mode NAME; 


INNER_WS     : (' ' | '\t')+; 


NAMEID      : ('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_' | '?')+; 

CLOSE_NAME     : (('\r'? '\n') | '*/') -> mode(DEFAULT_MODE); 

這似乎在大多數情況下是否工作正常除了在以下情況下關閉@name定義:

/** 
* @name someId*/ 

以上應該完全有效。在用'* /'結束註釋之前,我們不需要換行。我遇到的問題是,「* /」成功終止名字的定義,但它消耗的令牌,只有這樣我需要返回到默認模式:

​​

如果我真的希望它結束​​了評論。我希望它返回到默認模式,然後意識到這個令牌應該結束註釋(即它應該匹配END_QDOC)。我如何在ANTLR中完成這項工作?我試圖修復它,以便CLOSE_NAME是ID的倒數:

CLOSE_NAME : ~('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_' | '?'); 

但ANTLR仍然消耗*留下了無法識別的標記錯誤就剩下「/」。我真正想要做的是讓ANTLR退出該模式而不消耗令牌,以便當我們返回到DEFAULT_MODE時'* /'是下一個標記。有什麼想法嗎?

回答

0

首先,您可能希望使用-> pushMode(NAME)-> popMode回到默認模式,而不是使用mode命令。

爲了您CLOSE_NAME規則,你可以使用,而不是字面用於處理註釋的結尾匹配謂詞:

CLOSE_NAME 
    : ('\r'? '\n' 
    | {_input.LA(1) == '*' && _input.LA(2) == '/'}? 
    ) 
    -> popMode 
    ; 

這可能會產生一個零長度的令牌,並不得在ANTLR 4.0 ,但是在ANTLR 4.1中刪除了限制(更改爲警告),因爲我們意識到可以使用零長度標記來觸發模式更改,從而避免無限循環。

+0

我必須錯過一些東西,因爲這沒有用。現在令牌消失。它不會顯示爲CLOSE_NAME的一部分,但我仍然收到輸入不匹配''期待CLOSE_NAME – jcfolsom

+0

SO是否IntStream.LA實際上消耗了字符?這從文檔中不清楚。如果洛杉磯代表展望未來,那就是我想要的,但它似乎沒有正常工作。 – jcfolsom

相關問題