2014-04-27 26 views
1

我正在與ANTLR4解析一個簡單的腳本語言。如何制定一個包含多個相同標記的規則?

這種語言使用以下語法FOR循環:

FOR [I] = 1 to [N] 
    instructions 
NEXT [I] 

爲了是正確的,一個FOR循環必須有完全FOR關鍵字之後和NEXT關鍵字後,同樣的道理。

例如,這是正確的:

FOR I = 1 TO 10 
NEXT I 

雖然這是不正確的:

FOR I = 1 TO 10 
NEXT J 

到目前爲止,我有一個規則是這樣的:

forloop 
    : FOR VARNAME EQUAL INT TO INT instructions NEXT VARNAME 
    ; 

隨着遵循相關詞法分析規則(我刪除了常量關鍵字,例如FOR : 'FOR';):

fragment ALPHA : [a-zA-Z_]; 
fragment ALPHANUM : [a-zA-Z_0-9]; 
fragment DIGIT : [0-9]; 
VARNAME : ALPHA ALPHANUM*; 
INT : DIGIT+; 

但是,該規則將解釋爲正確的第二個示例實際上是不正確的。

如何告訴ANTLR4第二個VARNAME必須與規則中的第一個相同?

回答

5

可以forloop規則的強制執行這兩個VARNAME s爲相等的末尾加上一個謂詞:

forloop 
    : FOR a=VARNAME EQUAL INT TO INT instructions NEXT b=VARNAME 
     {$a.getText().equals($b.getText())}? 
    ; 

但(IMO)更好的辦法是讓解析器只接受不等於VARNAME s,並在解析完成後(在某種驗證偵聽器中遍歷解析樹)檢查它們。

+0

謝謝!仔細想想,我認爲你是對的,但是最好知道如何添加這樣的謂詞:) – Benlitz

+0

實際上,我使用C#,所以我將謂詞轉換爲C#代碼:'{$ a.Text == $ b 。文本}?'。可悲的是我有以下錯誤:錯誤AC0066:屬性'文本'不是'$ a.Text'中的有效屬性。但是,如果我與調試器斷開(使用編譯的簡單謂詞),Text屬性似乎可訪問和正確定義(來自「IToken」接口)。任何人遇到過C#這樣的問題? – Benlitz

+0

@Benlitz,是不是有一個'$ a.GetText()'方法呢? –

相關問題