2014-05-22 66 views
2

我需要獲取每個規則的開始和結束索引。即,起始索引是屬於該規則的第一個標記的第一個字符的字符位置,結束標記是屬於該規則的最後一個標記的最後一個字符位置。有了這些數字,我可以精確地裁剪出輸入文件中的規則結果。

這樣做的直接方式應該是使用$start$stop標記,即$start.getStartIndex()$stop.getStopIndex()。但是,我遇到了$stop令牌通常是null,即使在@after操作中使用時也是如此。

根據明確Antlr4引用$stop令牌被定義爲:「最後非隱藏信道的令牌由所述規則匹配 當提及當前規則, 此屬性可僅對後和 最後行動「。這聽起來好像這樣的標記應該存在(至少對於與至少一個標記匹配的任何規則)。因此,這是很奇怪爲什麼這個令牌null在很多情況下(甚至有一個簡單的標記規則 - 而不是一個子規則 - ?作爲他們的最後一個記號停止令牌怎麼能在這種情況下null

眼下,我使用的一種變通方法僅通過詢問其當前令牌輸入,移動一個令牌回來,並使用此令牌作爲stop令牌然而,這似乎哈克:

@after { 
int start = $start.getStartIndex(); 
int stop = _input.get(_input.index()-1).getStopIndex(); 
// do something with start and stop 
} 

的清潔劑溶液(如果stop是不爲空)應該看起來像這樣:

@after { 
int start = $start.getStartIndex(); 
int stop = $stop.getStopIndex(); 
} 

回答

2

執行任何用戶定義的@finally{}操作後,在生成的代碼的finally塊中設置停止令牌。代碼在try區塊中執行,該區域也是在設置了停止標記之前發生的。

stop屬性僅適用於合格參考。例如,你可以做到以下幾點:

foo : bar {assert $bar.stop != null}; 

另外,請注意ANTLR 4的目的是鼓勵的動作代碼嵌入行動搬遷到偵聽器解析是後的解析樹操作和/或訪問者接口完成。當以這種方式使用時,將爲樹中的所有上下文設置停止令牌。在幾乎所有情況下,使用@after@finally塊都是ANTLR 4中的代碼異味,應該避免。

+2

但是,然後,明確的引用是錯誤的,因爲它表示在'$ after'和'$ finally'操作中'$ stop' token *是可用的。但謝謝你清理這個! – gexicide

相關問題