2010-01-16 60 views
4

我有一個簡單的LALR(1)語法,但遇到了問題。LALR(1)空函數參數列表

start ::= spec. 
spec ::= MOD STRING top_stmt. 
spec ::= top_stmt. 
top_stmt ::= stmt. 
top_stmt ::= conditional. 
stmt ::= expr. 
stmt ::= assignment. 
conditional ::= IF stmt_list. 
expr ::= retval. 
expr ::= NOT retval. 
retval ::= access. 
retval ::= invoke. 
access ::= ns_identifier OBJECT_OPERATOR property_chain. 
access ::= ns_identifier. 
ns_identifier ::= identifier. 
ns_identifier ::= ns_identifier NS_SEPARATOR identifier. 
ns_identifier ::=. 
property_chain ::= property_chain OBJECT_OPERATOR identifier. 
property_chain ::= identifier. 
identifier ::= VARIABLE. 
identifier ::= STRING. 
assignment ::= access ASSIGN expr. [ASSIGN] 
stmt_list ::= stmt. 
stmt_list ::= stmt_list COMMA stmt. [COMMA] 
invoke ::= access LPAREN empty_stmt_list RPAREN. 
empty_stmt_list ::=. 
empty_stmt_list ::= stmt. 
empty_stmt_list ::= empty_stmt_list COMMA stmt. [COMMA] 

圓點標誌着統治的結束,括號中的終端都分配有關聯:分配是右結合,逗號左副教授。

但是lemon表示它不能減少規則「empty_stmt_list :: =」。因爲它沒有連接到開始符號。我敢打賭它是:-)

還有一個「調用」的解析衝突,當empty_stmt_list確實是empy語句列表時,它無法在RPAREN和COMMA之間做出決定。

我想要實現的是能夠解析沒有(void)參數的函數調用。

其他一切按預期工作。

感謝

編輯:我已經編輯我原來的職位,並張貼整個剝離下來的語法。

+0

您的符號是不是完全傳統的 - 它是ANTLR啓發的嗎?什麼是括號'(A)'和'(B)'的東西?在記譜法中單獨的'。'的意義是什麼?它似乎是一個元字符,規則和後面的行動 – 2010-01-16 17:23:41

回答

4

你的第一個問題是,我不認爲這一點做了你希望它是什麼:

invoke ::= access LPAREN empty_stmt_list RPAREN. 
empty_stmt_list ::=. 
empty_stmt_list ::= stmt. 
empty_stmt_list ::= empty_stmt_list COMMA stmt. [COMMA] 

invoke生產將匹配access LPAREN COMMA stmt RPAREN,我認爲是不可取的(並且是在LPAREN/COMMA衝突來自)。

您可以修復,通過做它喜歡這樣,這使得利用現有stmt_list規則:

invoke ::= access LPAREN maybe_empty_stmt_list RPAREN. 
maybe_empty_stmt_list ::= . 
maybe_empty_stmt_list ::= stmt_list. 

這仍然報告發生衝突(但只有1現在),並且仍然抱怨maybe_empty_stmt_list ::=.不能減少。所以,看在XXX.out文件,看看它是什麼:

State 2: 
... 
    (16) ns_identifier ::= * 
... 
    (25) maybe_empty_stmt_list ::= * 
... 
         RPAREN reduce 25 ** Parsing conflict ** 
.... 
        {default} reduce 16 

...它看來,問題出在ns_identifier ::=.規則。通過有關生產工作回來,這是不是太不難看出,空ns_identifier可以降低到stmt_list(通過ns_identifier - >access - >retval - >expr - >stmt - >stmt_list)。

這解釋了衝突;並且事實上ns_identifier ::=.規則在這種情況下更受歡迎,因爲它出現在語法的較早部分(請參閱解決documentation中的reduce-reduce衝突的規則,這解釋了爲什麼它會抱怨maybe_empty_stmt_list ::=.規則永遠無法減少。

+0

謝謝了,我完全解決它,包括刪除空的ns_identfier規則,這實際上是一個神器,以解決另一個老問題。自我評述:設計語言解析器需要關心和「做正確」的心態。接受的答案。 – Flavius 2010-01-17 21:33:10

0

您可以嘗試爲LPAREN/COMMA添加優先規則,並檢查它是否會影響其他地方的語義。