2016-04-14 54 views
0

我想能夠使用「NULL」既是參數(價值),並在我的語法一個函數名。看到這個減少的例子:ANTLR:解析NULL作爲函數的名稱和參數

grammar test; 

expr 
    : value # valueExpr 
    | FUNCTION_NAME '(' (expr (',' expr)*)* ')' # functionExpr 
    ; 


value 
    : INT 
    | 'NULL' 
    ; 

FUNCTION_NAME 
    : [a-zA-Z] [a-zA-Z0-9]* 
    ; 


INT: [0-9]+; 

現在,試圖解析:解析樹失敗

NULL(1) 

的結果,因爲它解析爲NULL值,而不是一個函數名。

理想情況下,我甚至應該能夠解析NULL(NULL) ..

你能告訴我,如果這是可能的,如果是,如何做到這一點?

回答

0

'NULL'串在你的語法定義了一個隱含的標記類型,它是相當於沿着這增加一些:

NULL: 'NULL'; 

在的詞法規則的開始。當令牌與多個詞法分析器規則匹配時,會使用第一個,因此在您的語法中,隱式規則會優先,並且您會得到類型爲'NULL'的令牌。

簡單的解決辦法是引入了函數名解析器規則,這樣的事情:

function_name: FUNCTION_NAME | 'NULL'; 

,然後用它在你的expr規則。但是這看起來很脆弱,如果NULL不是您的語法中的關鍵字。還有其他的解決方案,但我不確定該怎麼建議,因爲我不知道你希望你的語法如何擴展。

但另一種解決辦法是重新命名FUNCTION_NAMENAME,擺脫'NAME'令牌類型,並重寫expr這樣的:

expr 
    : value # valueExpr 
    | NAME '(' (expr (',' expr)*)* ')' # functionExpr 
    | {_input.LT(1).getText().equals("NULL")}? NAME # nullExpr 
    ; 

語義斷言這裏照顧名稱比較。