2009-10-04 79 views
14

我已經編程了多年(主要是Python),但我不明白當我編譯或執行我的代碼時幕後會發生什麼。學習編程語言的工作方式

在前面提到的關於操作系統的question中,我正在尋找對編程語言工程的簡單介紹。我希望能夠定義和理解諸如編譯器,解釋器,本地代碼,託管代碼,虛擬機等術語的基礎知識。什麼將是一個有趣和互動的方式來了解這個?

+2

有關SO的最終編譯器資源問題:http:// stackoverflow。COM /問題/ 1669 /學習到寫一個編譯器有一些建議的資源有哪些需要很隨和的辦法:如果你可以編程,你要準備學習編譯的方法。不要害怕。我喜歡Crenshaw教程。 – dmckee 2009-10-05 00:09:36

+0

^這是一個很好的資源列表。謝謝。 – 2009-10-09 00:00:10

回答

12

代碼以執行簡而言之

的程序(代碼)被饋入編譯器(或解釋器)。

字符用於形成令牌(+,標識符,數字),它們的值存儲在某個稱爲符號表的東西中。

這些標記放在一起形成語句:(int a = 6 + b * c;)。主要以語法樹的形式:

     = 
        /\ 
       / \ 
        a  + 
        /\ 
        / \ 
        6  * 
         /\ 
         b c 

在解釋器中樹直接執行。

使用編譯器,樹最終可以轉換爲中間代碼或彙編代碼。

您現在有一個或多個「目標文件」。這些包含沒有精確跳轉的彙編代碼(因爲如果目標位於其他對象文件中,這些值還不知道,尤其是這些值)。 目標文件通過填充跳轉(ans引用)空白的鏈接器鏈接在一起。鏈接器的輸出是一個庫(也可以鏈接)或可執行文件。

如果啓動可執行文件,程序數據將被複制到內存中,並且還有一些其他鏈接跳轉以將指針與正確的內存位置相匹配。然後控制第一條指令。

3

This site has a great series關於計算機程序結構和解釋講座,這正是你想學習的東西的類型。附帶的教科書也是有用的,我沒有親自閱讀整個事情。我認爲觀看講座非常好,約60%的路程。

2

哇找到很多講座。例如,這是噸的寫的書都是關於這一個巨大的問題。我真的懷疑你會在這方面得到一個體面的答案。你需要去當地的書店或者選擇一些comp sci課程。

爲了給你一個快速的介紹:

  • 編譯:,其將寫代碼到本機是由處理器所理解的指令的程序。
  • 譯員:一個程序,讀取書面代碼,並在飛行中,翻譯並提供相應的處理器本機指令。
  • 託管代碼:在虛擬機中運行的代碼,例如以提供跨平臺兼容性(Java)。
  • 虛擬機:一個程序,模擬全面的計算機環境的行爲,或更確切地說是API。除此之外,這提供了一些安全優勢和跨平臺兼容性。
2

​​3210將解釋很多這些概念,你應該給它一個閱讀,這是一個真正讓我大開眼界。

4

編譯器,解釋器和虛擬機僅僅是實現細節的例子。你可能要尋找的是編程語言理論,生成語法,語言翻譯,並且你需要一些計算機體系結構來將理論與實現聯繫起來。

我個人從Sebesta's book瞭解到。它對這個主題進行了非常廣泛的介紹,而沒有進入細節。它還具有編程語言歷史的良好篇章(〜20種語言〜每種語言3篇論文)。它總體上對語法和語言理論有很好的解釋。此外,它還介紹了Scheme,Prolog和編程範例(邏輯,功能,命令^,面向對象)。

^它比前兩個更集中在命令範例上。

1

當我瞭解編程時,在上個世紀下半葉的某個地方,我瞭解到一切都需要轉換爲機器碼。腳本語言會根據腳本代碼決定調用哪個代碼。編譯後的代碼將首先編譯爲p代碼,該代碼表示​​預編譯的代碼,需要將其鏈接到其他預編譯的代碼才能創建完整的應用程序。我當時很喜歡Turbo Pascal,只是因爲Turbo Pascal直接編譯成machione代碼,並沒有使用中間的p代碼。也就是說,直到Turbo Pascal 4.0,它創建了* .tpu編譯單元。大多數其他編譯器會將其編譯爲.obj格式。

Java創建時,相對較新的東西開始流行起來。基本上,Java編譯器只是將代碼編譯爲一些二進制腳本文件。這個腳本可以被解釋,儘管那個機制很快就改變了。

現在,口譯人員幾乎已經滅絕。大多數腳本語言將首先被編譯爲機器碼,然後機器碼被存儲在某個緩存中,因此可以快速執行,而系統不必重新解釋任何重複指令。這適用於文本和二進制腳本。 PHP將是一個基於文本腳本的例子。 Java和.NET是二進制腳本,因爲您通常會將代碼編譯爲這種二進制腳本格式。 (他們會說它不同,但我認爲二進制腳本聽起來更好。)

一般來說,訣竅是將代碼轉換爲機器代碼,使用任何可能的方式。已經有很多方法可以做到這一點,並且明確說明它有點複雜。

我還記得我能寫一個C語言應用程序的時候,SQL語句應該放在代碼本身的內部。這也很實用,但它需要一個預處理器,它將首先解析代碼中的SQL語句,將其轉換爲其他C++語句,並用更復雜的C++命令替換SQL語句。然後整個事情將被編譯爲p代碼。然後,您需要將它與其他SQL庫鏈接起來,最後得到一個可執行文件。

4

基本而言,你寫source files。這些是花哨的文本文件,輸入compiler輸出某種形式的可執行代碼(執行它取決於您正在談論的代碼類型)。編譯器有幾個部分:

  • 處理宏等文件上的某種形式的preprocessing(如來自C)。
  • A parser接收源文件,驗證它們是否符合您的語言的語法規則,並將文件轉換爲內存中的數據結構,該結構更容易被程序的其他部分操作。這被稱爲Abstract Syntax樹或AST。
  • 某些形式的AST分析,它驗證您編寫的實際代碼不違反語言的任何規則(例如,以不支持它的語言遞歸)以及其他許多事情。
  • Optimization諸如尾部調用優化,循環優化和許多其他種類的優化。
  • Code generation,這是最終的AST和任何其他生成的數據,並將其轉換爲某種可執行或解釋的二進制文件的實際過程。

Interpreter:

解釋器是一個程序,它在某種形式的二進制數據,其表示未編譯由目標機器代碼直接可執行程序,並且運行中的命令。例子是python,java和lua。

Native code:

這是一個已經被編譯成目標機器直接執行本地指令代碼。例如;如果您在x86架構上運行,那麼C++將編譯爲可由處理器理解的可執行文件。

Virtual Machine:

這通常是內置模擬處理器的結構和操作的程序。它可能與讀取bytecode的程序一樣簡單,並且根據字節碼錶示的命令運行本地語言操作(儘管調用此虛擬機可能是一段時間),或者它可能與完全模擬處理器和所有相關的外圍設備。

那些其他答案在他們中有好點,但這個信息和鏈接應該讓你開始。任何其他問題,只是問!

(本文的大部分與維基百科的幫助下寫成雖然有些是從內存中寫入)

1

series of lectures斯坦福涵蓋幾種編程語言下到位,螺栓,包括Python(雖然我只看了幾個C)。

2

如果你想知道從源代碼到實際運行在目標機器上的東西,你應該得到着名的Red Dragon Book的副本。我用它來構建解析器和詞法分析器。雖然可以追溯到1986年,但我相信在這個過渡期間已經取得了一些進展,據我所知,它並沒有作爲一個文本被超越。

看來Addison-Wesley已經完成了其前身Green Dragon Book的重印,並且將它作爲最近的東西傳遞給它,所以要小心獲得真正的文章。