2010-10-28 74 views
1

我有以下的檸檬語法(從實際語法簡化):如何從檸檬語法中刪除函數調用歧義?

%right ASSIGN . 
%nonassoc FN_CALL . 

program ::= expression . 
expression ::= expression ASSIGN expression . 
expression ::= function_call . [FN_CALL] 
expression ::= IDENTIFIER . 


function_call ::= expression LPAREN RPAREN . [FN_CALL] 

我不能夠解決在下面的狀態轉變,減少衝突:

State 3: 
     expression ::= expression * ASSIGN expression 
    (1) expression ::= expression ASSIGN expression * 
     function_call ::= expression * LPAREN RPAREN 
        ASSIGN shift 1 
        LPAREN shift 4 
        LPAREN reduce 1 ** Parsing conflict ** 
       {default} reduce 1 

我的想法是問題是a =(b(c))和(a = b)(c)之間的不確定性,但是我認爲賦予函數調用比賦值更高的優先級會解決它。任何想法可能是這種情況?

回答

0

第一個也是最大的一點:減少衝突是很少一個真正的問題。因此,這可能是你不需要(或者甚至是關心)修復的東西。

第二點:不幸的是,在我看來,你可能已經過度簡化了你的語法。舉個例子,語法(如你所發佈的)看起來像a=(b(c))(a=b)(c)應該直接被拒絕(唯一指定LPAREN的地方,它必須被RPAREN立即跟在之後)。你發佈的內容並不足以讓我們猜測真正的語法可能出現什麼問題。

+0

我只用括號來表示含糊不清;我試圖展示的兩個可能的解析樹是頂級表達式是其表達式爲「a = b」的函數調用,以及頂級表達式是其第一個表達式是標識符並且其第二個表達式是第二個表達式是一個函數調用。 即使在這個小小的語法中,問題也顯現出來;如果按原樣編譯,則會出現衝突。 – Topoli 2010-10-28 01:02:33

0

這是做你想做的嗎?

program ::= assignment . 

assignment ::= expression ASSIGN assignment . 
assignment ::= expression . 

expression ::= expression LPAREN RPAREN . 
expression ::= IDENTIFIER . 

它可以讓你分配函數調用(這是不尋常的),但你的原始語法也是如此。我意識到這只是一個更大的語法的一部分。

+0

雖然這樣做,但是事實是,我不得不重寫整個語法來編碼優先規則,這讓我有點擔心。 – Topoli 2010-10-28 01:17:36

+0

您不必重寫全部內容。您可以很容易地將它分離爲二進制,前綴和後綴操作,並在二進制部分中使用右%左聲明。 – xscott 2010-10-28 01:33:31