2011-09-28 18 views
2

我想創建一個LALR語法來分析嵌套列表,但我總是遇到一個轉換/減少衝突。如何避免LALR語法中的轉換減少衝突來解析嵌套列表?

我有列表1這是TYPE1項目和List2列表:

<list1> ::= <type1> | <type1> <list1> ; 
<type1> ::= A | B | <list2> ; 

而且我有一個列表2這是2型項目的列表:

<list2> ::= <type2> | <type2> <list2> ; 
<type2> ::= X | Y ; 

該語法產生的轉變/減少錯誤。我怎樣才能避免它?

這是具體Bigloo來源:

(lalr-grammar 
    (comment 
    new-line 
    text-chunk 
    white-space) 
    (input 
    (()    '()) 
    ((node-list)  node-list)) 
    (node-list 
    ((node)   (cons node '())) 
    ((node node-list) (cons node node-list))) 
    (node 
    ((comment)   (cons 'comment comment)) 
    ((new-line)  (cons 'new-line new-line)) 
    ((text)   (cons 'text text)) 
    ((white-space)  (cons 'white-space white-space))) 
    (text 
    ((text-chunk)  (cons 'text text-chunk)) 
    ((text-chunk text) (cons 'text (string-append text-chunk text))))) 

終端爲:評論,新行,文本塊和空白。 非終端是:輸入,節點列表,節點和文本。

中的bigloo埋怨減少規則文本到文本的塊:

*** WARNING:bigloo:lalr-grammar 
** Shift/Reduce conflict: 
- shift to state 2 
- reduce rule (text --> text-chunk) 
on token `text-chunk' 

但我不認爲這是一個問題的bigloo。它看起來像一個語法問題。

回答

2

語法實際上是不明確的,因爲一個type2實例的序列可以在list2級別上累積,但它也可以看作是一個type1實例的序列。

例如該輸入

X X 

均可解析爲

list1(
    type1(
    list2(
     type2(
     X) 
     list2(
     type2(
      X))))) 

而且作爲

list1(
    type1(
    list2(
     type2(
     X))) 
    list1(
    type1(
     list2(
     type2(
      X))))) 

什麼關於list1水平引入分隔符?這將解決問題。

+0

謝謝!你是對的。我能夠通過兩種方式解決問題。首先,可以通過擴展語法來以正確的方式指導解析器。但第二種解決方案更加優雅。我可以在我的Bigloo語法中指定type2終端的優先級。通過該解析器不會將type2元素的列表視爲type1元素的列表。 – ceving