2013-02-04 130 views
0

我devloping我自己的編譯器,我有錯誤恢復設計 在java語法的恐慌模式的問題。野牛C++多重錯誤恢復與丟失的分號

我想到了多種解決方案,但真正的問題:

我怎麼能做到這一點與野牛C++?

我這樣做:

包2

進口的java.lang。*;

誤差必須消耗到第一半結腸和這與規則運行正確

package_rule:包錯誤「;」

但如果我寫這個代碼:

封裝2

進口的java.lang *

等級Y {無效方法(){INT米}

}

我需要從解析器中像標準編譯器那樣報告錯誤:

標識符預計在包行。 失蹤';'在導入指令行報告一個包。 mssing';'在整數m行。

我的意思是我需要包後錯誤消耗令牌,直到第一個分號或停止時,在最後一行befere聲明他們找到類或接口聲明!並報告線後發現的任何其他錯誤:

int m //缺少';'

請幫助我,在我腦海中有多種解決方案,但是如何用bison C++爲java語法實現?

感謝名單了很多..

回答

0

你不會介意來解決這個問題在C++面向對象的方式,而不是在野牛的方式,你會嗎?

考慮您有這些類型的定義

struct BaseExpression { 
    virtual std::string toIdentifier() = 0; 
    // other member. remember to declare a virtual destructor 
}; 

struct IntLiteral : BaseExpression { 
    std::string toIdentifier() { 
     error::toAnIdentifier(); 
     return ""; 
    } 
}; 

struct Identifier: BaseExpression { 
    std::string ident; 

    explicit Identifier(std::string id) : ident(id) {} 

    std::string toIdentifer() { 
     return ident; 
    } 
}; 

AST節點的定義是這樣

%union { 
    BaseExpression* expr_type; 
} 

%type <expr_type> simple_expr 

package_expr: simple_expr 
{ 
    $1->toIdentifer(); // thus integers or float numbers would generate errors 
    // do sth with that identifer 
} 
; 

package_expr: package_rule '.' simple_expr 
{ 
    $3->toIdentifer(); // same trick 
    // do sth with that identifer 
} 
; 

的規則,其中simple_expr

simple_expr: int_literal { return new IntLiteral; } 
      | ... 
      | identifier { return new Identifier(yytext); } 
; 
1

好了,你的基本的問題是如何做您希望它嘗試從語法錯誤中恢復。當你有一個像

package x import 

輸入序列做你想讓它假定有應該是一個分號那裏,或者你希望它承擔別的東西卡住了分號之前,它應該扔東西距離,直到它得到分號?

後者是你有什麼 - 規則package: PACKAGE error ';'不正是 - 每當它看到關鍵字PACKAGE之後卻什麼來的package規則的其餘部分不匹配,應該扔掉輸入,直到它看到一個​​3210並嘗試從那裏繼續。

如果你想前,你可以使用一個類似的規則package: PACKAGE name error - 如果看到PACKAGE的東西,看起來像一個有效的軟件包名稱,但沒有分號,把它當作如果有一個分號那裏,並嘗試繼續。

使它能夠做到上述事情是非常困難的。最接近的將是具有語法看起來像:

package: PACKAGE name ';' /* normal package decl */ 
     | PACKAGE name  /* missing semicolon -- treat this as a semantic error */ 
     | PACKAGE error ';' /* no name -- skip up to the next semicolon to recover */ 

然而,這樣的事情可能給你語法是很難解決衝突。

+0

thanx爲你的答案,我解釋我的問題犯了一點錯誤。 pakcage 2 //這裏錯誤在id和缺少';' 什麼我需要設計專業編譯器的Java語言, 匹配標準的。 所以你的suggession克里斯多德是goOd,我寫了它,但這要麼 發現錯誤在ID或';'但不是他們兩個! 我需要的東西或者消耗錯誤到下一個';'在導入時使用規則PACKAGEG 錯誤';',或者如果在聲明類,接口或EOF之前沒有發現停在最後一行。 我需要真正的高級解決方案,在java標準中得到相同的結果,我在等待你的建議。 – lady

+0

那麼,你可以改爲使用規則'package:PACKAGE error',甚至'declaration:error',從語法錯誤恢復到最高級別,而不會丟棄任何令牌。它可能會給你一個錯誤級聯,但是(由於不完全恢復造成很多「錯誤」錯誤) –

+0

package:PACKAGE錯誤。在這種情況下,錯誤標記只包含PACKAGE標記後的第一個字,然後停止,這不是我的目標!我想要錯誤標記在類或接口之前消耗所有的標記,如果找到..然後發現類或接口內的錯誤,清除??在這個解決方案中,當寫入規則時:> package:PACKAGE error |時出現其他問題包錯誤';' |那麼第二條規則就不會被使用!真正的問題:( – lady