解釋器

解釋器

解釋器是能夠執行用其他計算機語言編寫的程式的系統軟體,它是一種翻譯程式。它的執行方式是一邊翻譯一邊執行,因此其執行效率一般偏低,但是解釋器的實現較為簡單,而且編寫源程式的高級語言可以使用更加靈活和富於表現力的語法。

Python、TCL和各種Shell程式一般而言是使用解釋器執行的。微軟公司的Qbasic語言也是解釋方式,它不能生成可執行程式(但QuickBasic和VisualBasic可以);運用廣泛的網路程式語言java則同時有解釋和編譯方式。

基本信息

執行方式

解釋器解釋器
Python、TCL和各種Shell程式一般而言是使用解釋器執行的。微軟公司的Qbasic語言也是解釋方式,它不能生成可執行程式(但QuickBasic和VisualBasic可以);運用廣泛的網路程式語言java則同時有解釋和編譯方式。
在開始之前有必要再次強調:下面介紹的解釋器是一個原始碼解釋器。也就是說,解釋器在執行時,每次讀入一條語句,並且根據這條語句執行特定的操作;然後再讀入下一條語句,依次類推。這與偽代碼解釋器是有所區別的,例如早期的Java運行時系統。兩者的區別在於:原始碼解釋器直接對程式的原始碼解釋執行;而偽代碼解釋器先將程式的原始碼轉化為某種與機器無關的中間代碼,然後再執行中間代碼。相比之下,原始碼解釋器更易於創建,並且不需要一個獨立的編譯過程。

子系統

SmallBASIC解釋器包括兩個主要的子系統:一個是表達式解析器,負責處理數字表達式;另一個是解釋器,負責程式的實際執行。對於前者,可採用本書第二章所介紹的表達式解析器。但是在這裡做了某些改進,使得解析器能夠解析包含在程式語句中的數字表達式,而不是只能解析孤立的表達式。
解釋器子系統和解析器子系統包含在同一個解釋器類中,該類名為SBasic。儘管從理論上講可以使用兩個獨立的類:一個包含解釋器,另一個包含表達式解析器;但是將兩者用同一個類來實現的代效率會更高,因為表達式解析器和解釋器的代碼是密不可分的。例如,兩個子系統都操作保存著程式代碼的同一個字元數組。如果將它們分別安排在兩個類中,將會增加可觀的額外開銷,並導致性能上的損失和功能上的重複。此外,由於程式解釋的任務繁重,而解析表達式只是其中的一部分,因此將整個解釋機制包含在單個類中是很有意義的。
解釋器執行時,每次從程式的原始碼中讀入一個標識符。如果讀入的是關鍵字,解釋器就按照該關鍵字的要求執行規定的操作。舉例來說,當解釋器讀入一個PRINT後,它將列印PRINT之後的字元;當讀入一個GOSUB時,它就執行指定的子程式。在到達程式的結尾之前,這個過程將反覆進行。可以看到,解釋器只是簡單地執行程式指定的動作。

解釋編譯

解釋器運行程式的方法有:
1.直接運行高級程式語言(如Shell自帶的解釋器)
2.轉換高級程式語言碼到一些有效率的位元組碼(Bytecode),並運行這些位元組碼
3.以解釋器包含的編譯器對高級語言編譯,並指示處理器運行編譯後的程式(例如:JIT)
Perl,Python,MATLAB,與Ruby是屬於第二種方法,而UCSDPascal則是屬於第三種方式。在轉譯的過程中,這組高級語言所寫成的程式仍然維持在原始碼的格式(或某種中繼語言的格式),而程式本身所指涉的動作或行為則由解釋器來表現。
使用解釋器來運行程式會比直接運行編譯過的機器碼來得慢,但是相對的這個直譯的行為會比編譯再運行來得快。這在程式開發的雛型化階段和只是撰寫試驗性的代碼時尤其來得重要,因為這個“編輯-直譯-除錯”的循環通常比“編輯-編譯-運行-除錯”的循環來得省時許多。
在解釋器上運行程式比直接運行編譯過的代碼來得慢,是因為解釋器每次都必須去分析並轉譯它所運行到的程式行,而編譯過的程式就只是直接運行。這個在運行時的分析被稱為"直譯式的成本"。在解釋器中,變數的訪問也是比較慢的,因為每次要訪問變數的時候它都必須找出該變數實際存儲的位置,而不像編譯過的程式在編譯的時候就決定好了變數的位置了。
在使用解釋器來達到較快的開發速度和使用編譯器來達到較快的運行進度之間是有許多妥協的。有些系統(例如有一些LISP)允許直譯和編譯的代碼互相調用並共享變數。這意味著一旦一個子程式在解釋器中被測試並除錯過之後,它就可以被編譯以獲得較快的運行進度。許多解釋器並不像其名稱所說的那樣運行原始代碼,反而是把原始代碼轉換成更壓縮的內部格式。舉例來說,有些BASIC的解釋器會把keywords取代成可以用來在jumptable中找出相對應指令的單一byte符號。解釋器也可以使用如同編譯器一般的文字分析器(lexicalanalyzer)和語法分析器(parser)然後再轉譯產生出來的抽象語法樹(abstractsyntaxtree)。
可攜性佳,直譯式程式相較於編譯式程式有較佳的可攜性,可以容易的在不同軟硬體平台上運行。而編譯式程式經過編譯後的程式則只限定於運行在開發環境平台。

位元組解釋

考量程式運行之前所需要分析的時間,存在了一個介於直譯與編譯之間的可能性。例如,用EmacsLisp所撰寫的原始碼會被編譯成一種高度壓縮且最佳化的另一種Lisp原始碼格式,這就是一種位元組碼(bytecode),而它並不是機器碼(因此不會被綁死在特定的硬體上)。這個"編譯過的"碼之後會被位元組碼直譯器(使用C寫成的)轉譯。在這種情況下,這個"編譯過的"碼可以被說成是虛擬機(不是真的硬體,而是一種位元組碼解釋器)的機器碼。這個方式被用在OpenFirmware系統所使用的Forth代碼中:原始程式將會被編譯成"Fcode"(一種位元組碼),然後被一個特定平台的虛擬機直譯和運行。

相關詞條

相關搜尋

熱門詞條

聯絡我們