2014-12-22 73 views
2

我需要認識到在Fortran中的I4格式整數數組整數鏈(代表的寬度4的整數),如以下示例: enter image description here語義謂詞ANTLR不承認的寬度4

使用純上下文無關文法:

WS : ' '  ;  

MINUS : '-' ; 


DIGIT : '0'..'9'  ; 

int4: 
       WS WS (WS| MINUS) DIGIT 
      | WS (WS| MINUS) DIGIT DIGIT 
      | (WS| MINUS | DIGIT ) DIGIT DIGIT DIGIT  
    ; 

numbers 
    : int4*; 

上面的例子是正確匹配:

enter image description here 然而如果使用語義謂詞來編碼的r語義約束ULE INT4:

int4 
scope { int n; } 
@init { $int4::n = 0; } 
: ({$int4::n < 3}?=> WS {$int4::n++;})* 
    (MINUS {$int4::n++;})? 
    ({$int4::n < 4}?=> DIGIT{$int4::n++;})+ 
    {$int4::n == 4}? 
    ; 

它的工作原理爲INT4規則,但它不是數字的規則是相同的,因爲它不承認第一個例子中的整數數組:

enter image description here

在這種情況下可能會更好的純粹的上下文無關語法,但在格式I30(代表寬度爲30的整數)的情況下?

主要問題是:在語法中是否可以使用語義謂詞?

+0

@BartKiers爲了更好地理解問題,我在幾分鐘前編輯了它 – Cyberguille

+0

@BartKiers是的,但是當我在int4規則中添加了語義謂詞時,分析樹似乎以數字結束,因爲你請參閱解析樹的最後一張圖片 – Cyberguille

回答

1

您的分析樹似乎以數字規則結束,因爲您的數字規則會引發異常(但它不會顯示在圖表中......)。你可以看到它,如果你運行生成的代碼,如果你走在異常仔細一看,上面寫着(行信息可能會有所不同你):

Exception in thread "main" java.util.EmptyStackException 
    at java.util.Stack.peek(Stack.java:102) 
    at FortranParser.numbers(FortranParser.java:305) 
    at Main.main(Main.java:9) 

和代碼拋出異常是:

public final void numbers() throws RecognitionException { 
       .... 
       else if ((LA5_0==DIGIT) && ((int4_stack.peek().n < 4))) { 
         alt5=1; 
       } 

所以你的問題是,語義謂詞被傳播到數字規則,並在該水平範圍堆棧是空的,因此int4_stack.peek()拋出一個異常

一個小竅門,以避免它就是你在全球範圍內使用的變量,例如:

@members { 
    int level=0; 
} 

和修改語義斷言謂詞前檢查水平,就像:

int4 
scope { int n; } 
@init { $int4::n = 0; level++; } 
@after { level--; } 
: ({level==0 || $int4::n < 3}?=> WS {$int4::n++;})* 
    (MINUS {$int4::n++;})? 
    ({level==0 || $int4::n < 4}?=> DIGIT{$int4::n++;})+ 
    {$int4::n == 4}? 
    ; 

這是隻是一種解決方法,以避免你得到的錯誤,也許(知道錯誤)有一個更好的解決方案,你不需要搞亂你的語義謂詞。

但是,我認爲,答案是肯定的,有可能在語法中使用語義謂詞。

+0

謝謝!你的回答非常有幫助,它的工作原理!我認爲這是一個很好的解決方案,在這種情況下拋出的異常應該由ANTLR的開發者解決。因爲我使用的是ANTLRWorks 1.4.2,所以在上一個版本中可能已經修復了這個問題。 – Cyberguille