解釋器

解釋器

解釋器(英語:Interpreter),又譯為直譯器,是一種電腦程式,能夠把高級程式語言一行一行直接轉譯運行。解釋器不會一次把整個程式轉譯出來,只像一位“中間人”,每次運行程式時都要先轉成另一種語言再作運行,因此解釋器的程式運行速度比較緩慢。它每轉譯一行程式敘述就立刻運行,然後再轉譯下一行,再運行,如此不停地進行下去。

基本介紹

  • 中文名:解釋器
  • 外文名:Interpreter
  • 分類:電腦程式
執行方式,子系統,解釋編譯,位元組解釋,

執行方式

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

子系統

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

解釋編譯

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

位元組解釋

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

相關詞條

熱門詞條

聯絡我們