2017-02-23 68 views
0

我目前正在編寫一個類似Visual Basic的LALR(1)語法,並面對這個特殊的轉換/減少衝突,我不知道如何正確解決它。由於括號衝突/減少LALR(1)衝突

語法的問題的部分是(請參見EDIT 1EDIT 2澄清):

Expression 
    : IndexExpression 
    | /* other expressions */ 

IndexExpression 
    : MemberExpression 
    | MemberExpression '(' ArgumentList ')' 

MemberExpression 
    : ParenthesizedExpression 
    | Identifier 

ParenthesizedExpression 
    : '(' Expression ')' 

ArgumentList 
    : Expression 
    | Expression ',' ArgumentList 
    | ',' ArgumentList 

和移位/減少衝突是這樣的:

State 109 
    237 ParenthesizedExpression: '(' Expression ')' . 
    $default reduce using rule 237 (ParenthesizedExpression) 

... 
State 295 

    231 IndexExpression: MemberExpression '(' . ArgumentList ')' 
    237 ParenthesizedExpression: '(' . Expression ')' 
    ... 
    Expression go to state 352 

... 
State 352 
    182 ArgumentList: Expression . 
    183    | Expression . ',' ArgumentList 
    237 ParenthesizedExpression: '(' Expression . ')' 
    ... 
    ')' shift, and go to state 109 

    ')' [reduce using rule 182 (ArgumentList)] 

換句話說,解析器在面對由圓括號包裝的表達式時不確定,無論是具有單個expre的ArgumentList ssion或括號表達式

有什麼辦法可以解決這個衝突,同時把語法保持爲LALR(1)?

謝謝。

編輯1:

/*其他表達式* /在表達其實不是一個空的表情,我只是寫它爲簡潔的方式。實際上它具有其它替代的表達式:

Expression 
    : IndexExpression 
    | Expression '+' Expression 
    | ... 

編輯2:

以下是其中@rici指出可能是有問題的語法(尤其聲明的第一右手規則的附加部分):

Statement 
    : MemberExpression ArgumentList 
    | MemberExpression '=' Expression 
    | MemberExpression '(' ArgumentList ')' '=' Expression 
    | ... 
+0

你需要展示更多的語法。或者,更好的是,創建一個具有相同問題但只有少數幾部作品的可重新編譯的語法。順便說一下,'argument_list'語法很奇怪。爲什麼你覺得用左遞歸編寫它是有用的,在LALR(1)解析器中通常應該避免使用左遞歸?多重缺失的觀點意味着什麼?如果所有其他參數都可以省略,爲什麼最後一個不能呢? – rici

+1

您是否允許在不帶圓括號的情況下調用帶有一個參數的函數的VB語法?如果是這樣,那很可能是你的問題。 – rici

+0

@rici **缺少參數**:在這個特定的VB語言中,它允許參數列表具有空參數,除了最後一個。由於我不想讓_Expression_變爲空,我最終將_ArgumentList_中的第三條規則放置了。 **括號括起來的一個參數**:是的!事實上,在昨天更深入地尋找根本原因之後,我得出結論認爲這可能是原因。你有關於如何包含這個語法的建議嗎? –

回答

2

的錯誤是因爲Expression允許爲空,因爲評論規則/* other expressions */,一nd被假定不是空的。

下面顯示了其中在兩個等效規則使用Expression結果:

ArgumentList 
    : Expression 
    | Expression ',' ArgumentList /* degenerates into "',' ArgumentList" */ 
    | ',' ArgumentList 
    ; 

移位的數目/減少衝突是用於次ArgumentList被引用的數目(一次在IndexExpression和兩次在ArgumentList本身)

要刪除衝突要麼修復ArgumentList一個空Expression的情況下:

ArgumentList 
    : Expression 
    | ArgumentList ',' Expression 
    ; 

或確保Expression永不爲空(刪除註釋的規則)。

+0

您好kdhp,請參閱我的編輯1進行澄清。對不起,我原來的帖子不明確。 –

+1

@SamTatasurya沒有看到表達式列表我只能猜測或者有另一個空值,一個運算符沒有被聲明爲'%left' /'%right',或者有另一個規則''('Expression' )''(也通過'IndexExpression-> MemeberExpression-> ParenthesizedExpression'出現) – kdhp