2013-12-09 27 views
2

不確定是什麼導致了這一點。當我嘗試編譯文件,我得到一個錯誤說「左遞歸檢測的表達... - >片段...... - >表達在.jj文件中檢測到左遞歸

的代碼,有這是本節

void statement() : {} 

{ 
    identifier() <ASSIGN> expression() 
    | identifier() <ASSIGN> <STRING> 
    | <EMARK> expression() 
    | <QMARK> identifier() 
    | identifier(arg_list()) 
    | <BEGIN>(statement() <SEMIC>)+ <END> 
    | <IF> condition() <THEN> statement() 
    | <IF> condition() <THEN> statement() <ELSE> statement() 
    | <WHILE> (condition()) <DO> statement() 
    | {} 
} 

void expression() : {} 
{ 
    fragment()((<PLUS_SIGN> | <MINUS_SIGN> | <MULT_SIGN> | <DIV_SIGN>) fragment())* 
} 

void fragment() : {} 
{ 
    identifier() | <NUM> | (<PLUS_SIGN> | <MINUS_SIGN>)fragment() | expression() 
} 
面積

我真的不知道如何去解決這個問題,並希望得到任何幫助吧! 謝謝!

+1

供參考:+++++ ---- +++ 6將是一個有效的片段 – Paperwaste

+0

這個任務已經在幾個最近的堆棧溢出問題中討論過。檢查出問題http://stackoverflow.com/questions/20287086/left-factoring-removing-left-recursion-javacc和http://stackoverflow.com/questions/20364288/left-recursion-elimination-in-an-ll1 -語法 。 –

回答

2
void fragment() #void : {} 
|<LBR> expression() <RBR> 

更改片段生成規則,其中它的表達式包括括號在任何一方。這應該解決您的遞歸問題。

+0

一個男孩爲一個男孩 – AndyOHart

1

我覺得你的抽象是一點點了。

(<PLUS_SIGN> | <MINUS_SIGN>)fragment() 

更可以否定一個片段的表達的

我會考慮

void expression() : {} 
{ 
    fragment()((<PLUS_SIGN> | <MINUS_SIGN> | <MULT_SIGN> | <DIV_SIGN>) fragment())* 
    | <MINUS_SIGN> fragment() 
    | <PLUS_SIGN> fragment() 
} 

我也相信的那個片段並不需要成爲一個expression()要麼遞歸已經被((<PLUS_SIGN> | <MINUS_SIGN> | <MULT_SIGN> | <DIV_SIGN>) fragment())*封裝能夠重複

+0

感謝您的回覆。 我嘗試了你所說的並且錯誤消失了,但是現在我得到4個警告,如下所示: 警告:選擇衝突涉及兩個擴展,分別爲 243行,11列和244行,第11列。 一個常見的前綴是: 考慮在先前的擴展中使用前瞻2。 他們都與此類似,另一個提到了一個共同的前綴,如果不是。任何想法這是告訴我什麼? – AndyOHart

+1

沒有抱歉不能幫助你在那裏我不熟悉.jj我只能幫助你的遞歸問題,因爲我對haskell有一點經驗。 Goodluck – Paperwaste

+0

沒問題欣賞幫助男人:) – AndyOHart