2009-11-11 62 views
1

在學校裏,我們被分配去設計一門語言,然後實施它(我有很多樂趣實現它=))。我的老師告訴我們使用YACC /法,但我決定去與Java +正則表達式API,這裏是語言我如何設計外觀:語法分析問題

Program "my program" 
var yourName = read() 
if { equals("guy1" to yourName) } 
    print("hello my friend") 
else 
print("hello extranger") 
end 
Program End 

好吧,你可以看到,它的一個非常基本的語言=)。

我以爲我能實現它在一個非常OOP的時尚,就像讓一個抽象類Sentence,然後讓子類像VariableAssignmentIfSentence等,並有一個類Program這僅僅是一串句子正確的?然後調用一個抽象方法eval所有Sentence S,所以我最初的做法complie語言僅包括兩個階段:

  1. 確定SEACH行的語法
  2. 每行
創建correspondig類

當然,如果在任何階段出現問題,Ii都可能引發錯誤。

我的問題是,我做錯了嗎?我是否應該像理論說的那樣遍歷所有階段(詞彙,語法,語義)?我應該繼續使用我的天真的兩階段編譯器嗎?

+7

大錯誤。你應該學習解析,而不是用正則表達式來解決問題。您應該切換到使用Java解析系統(如Jack),或者更好的方法是使用BYACC/J http://byaccj.sourceforge.net/,以便您更好地與類同步。 – 2009-11-11 15:56:38

回答

5

我不會問一個顯而易見的問題,你爲什麼不遵循教師的建議和使用yacc/lex,因爲我知道答案。你想離開,做一些你認爲很酷的事情,並會幫助你學習。不幸的是,這種方法是由你的教授推薦的,因爲正如另一篇文章所述,很多非常聰明的人在探索多種方法之前花費大量時間試圖找到一個好的解決方案。

您可以使兩階段編譯器工作,但您需要接受它不會像完整過程那樣好,因爲它很難檢測到錯誤。其實很難。在某些情況下,您甚至不能在出現錯誤之前就知道有錯誤。即:已編譯並嘗試運行。

如果您想了解更多關於它的信息,請使用兩階段方法,您會碰到與之前遇到的人相同的問題。請務必明白,要達到最終解決方案需要更長的時間,您可能會將項目停靠點,並且可能無法正常工作。

也就是說,你會比班上其他人更多地瞭解它。如果你有時間空餘,我會按照你現在的樣子去做。知識可能會派上用場。我還會和你的教授談談,並告訴他你會以另一種方式違揹他的建議,因爲你希望有一個更透徹的理解。也許他不會因爲雄心勃勃而從你的項目中脫穎而出,即使結果不對。

畢竟,在大學裏做項目的重點是學習。

5

很多聰明的人都想到了這個問題,並且從我發表的文章中,他們得出了所有階段都需要的結論。

所以,如果你想要你的編譯器工作,按照理論的方式。

如果你想了解,爲什麼它決定階段,試試捷徑。它可能會花更長的時間。


免責聲明:我不知道編譯原理想法


另注:你有問題;你決定使用正則表達式來解決它;現在你有兩個問題

+0

@Jens Schauder,+1爲「現在你有兩個問題」引用。 – 2009-11-11 16:16:03

1

如果您使用正則表達式解析每行,您的語言將具有非常有限的語法。

如果語法變得更復雜,那麼您將無法僅使用正則表達式API解析每一行。如果您開始添加運算符,那麼即使if { equals("guy1" to yourName) }也無法用正則表達式解析,如果您在字符串文字中開始支持轉義字符如\n會發生什麼情況?

Java Regex API將能夠幫助您使用詞法分析器,但您必須從那裏編寫解析器。如果您使用的是Java

  • ,你可以看看Antlr(這否定了需要寫一個lexicall分析儀與Java的正則表達式庫),或
  • 你可以寫一個:你可以採取幾種方法之一手工遞歸下降解析器

(也,「聲明」是「句」這是比較常見的編譯器文本的同義詞)

0

如果你真的想骯髒你的手代碼一個遞歸下降解析器。如果您想了解編譯器理論,請使用antlr,並專注於爲解析器生成器留下實現的原則。順便說一句,爲什麼會用正則表達式使你的生活複雜化?!

1

如果您只想使用正則表達式來分析您的語言,那麼您的語言只能是常規語言。這是一個很大的限制,例如,任意深度的嵌套將是不可能的,因爲您將不得不分別教您的解析器每個嵌套組合。我不確定是否可以構建一個完整的圖靈語言。