2017-08-03 131 views
0

我正在與Antlr4一起解析布爾類DSL。Antlr4語法 - 識別語法錯誤

這是我的語法:

grammar filter; 

filter: overall EOF; 

overall 
    : LPAREN overall RPAREN 
    | category 
    ; 

category 
    : expression # InferenceCategory 
    | category AND category # CategoryAndBlock 
    | label COLON expression # CategoryBlock 
    | LPAREN category RPAREN # NestedCategory 
    ; 

expression 
    : NOT expression   # NotExpr 
    | expression AND expression # AndExpr 
    | expression OR expression # OrExpr 
    | atom      # AtomExpr 
    | LPAREN expression RPAREN # NestedExpression 
    ; 

label 
    : ALPHANUM 
    ; 

atom 
    : ALPHANUM 
    ; 

下面是一個例子輸入字符串解析:

(CAT1:(1或2)和CAT2 :(4))

這個語法對這個輸入正常工作;它產生完全符合我的需要以下的解析樹:

enter image description here

然而,有DSL,在沒有指定其他類別時是「CAT1」的標籤是隱性的怪異情況。這就是InferenceCategory標記捕獲的內容,其中此表達式將在稍後的代碼中作爲類別處理。

例如,

((1或2)和CAT2 :(4))

我得到(如預期):

enter image description here

然而,在以下情況下:

CAT2 :(4)和(1或2)

我得到:

enter image description here

注意,第二塊沒有被確定爲一個InferenceCategory和,而是作爲一個正常表達,在第一類。這是因爲語法在cat2之後解析(4):作爲一個正常表達式,並且過去的所有東西都被解析爲正常表達式。

有什麼辦法解決這個問題嗎?我已經試過:

label COLON expression (AND category)* # CategoryBlock (不工作)

category AND category AND category (其中「作品」,但非常哈克,只有在我有完全的特定情況下工作三個類別,再一次,它再次打破)

回答

1

NOT expression # NotExpr這樣的「替代標籤」在你的分析樹中沒有什麼不同。它們只是語義。他們將導致代碼生成過程創建特定的簽名,您可以在訪客或偵聽器中重寫。

例如,其背後的基本原理是,不要只爲expression獲得一個訪客覆蓋,您將爲每個替代標籤獲得幾個,一個。這樣,您不必檢查expression並確定它在執行操作之前的類型。相反,例如,您將獲得覆蓋# OrExpr的覆蓋,並且只要您處於該覆蓋代碼中,就知道您正在處理OR,並在OR令牌的每一側使用表達式。

解析樹很有用,但大部分語義只有在您編碼Listener或Visitor時纔會變得明顯。

+0

嗨,我知道替代標籤是語義,直到我與聽衆/訪問者工作。在這種情況下,我不確定如何在解析器級別唯一標識這些隱式類別,因爲它們在功能上是相同的。我目前的執行過程中,我只是忽略了這個問題,直到其中一個隱含類別出現在我的「標籤:表達式」右側的情況下,在這種情況下,它被解釋爲表達式而不是類別,並且成爲另一個類別的子樹而不是兄弟姐妹(這是主要問題)。 – thevises

相關問題