日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

柯里化的前生今世(四):编译器与解释器

發(fā)布時間:2025/3/15 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 柯里化的前生今世(四):编译器与解释器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

關(guān)于

在上一篇中,我們提到了形式語言與文法,S表達(dá)式與M表達(dá)式,同像性。

本文將開始寫一個簡單的解釋器,
通過具體實現(xiàn),我們來理解求值環(huán)境,動態(tài)作用域和靜態(tài)作用域,還有閉包等概念。
當(dāng)然,一篇文章來寫完這些肯定是不夠的,我們可以慢慢來,循序漸進(jìn)。
寫完了這個解釋器之后,我們會增加一些新的功能。

編譯器與解釋器

編譯器會將源代碼轉(zhuǎn)換成另一種語言的代碼,然后在支持后一種語言的機(jī)器上執(zhí)行。
而解釋器則不同,它會逐行分析源代碼,直接執(zhí)行分析結(jié)果。

值得一提的是,編譯和解釋是執(zhí)行代碼的兩種手段,
具體的語言實現(xiàn)很可能采用兩者的混合形式。
例如,一段Java程序,會首先經(jīng)過javac編譯為字節(jié)碼,
字節(jié)碼再交由Java虛擬機(jī)來解釋執(zhí)行。(JIT和RTSJ,略。。

編譯器包含以下三個部分,
編譯器前端:詞法分析,語法分析,最終生成抽象語法樹這種中間代碼。
編譯器優(yōu)化:中間代碼多次轉(zhuǎn)換,多種優(yōu)化,
編譯器后端:目標(biāo)代碼生成,優(yōu)化目標(biāo)代碼。

解釋器不包含目標(biāo)代碼生成階段,將優(yōu)化結(jié)果直接執(zhí)行。
前端和優(yōu)化,是編譯器和解釋器共有的。

抽象語法樹

編譯器前端會分析源代碼文本,生成一棵抽象語法樹。
假如,我們有如下源代碼,(1+2*3)*(4-5)。
使用ANTLR,我們得到了(具體)語法樹,

語法文件如下:

grammar Expr;expr: expr ('*'|'/') expr| expr ('+'|'-') expr| INT| '(' expr ')';INT: [0-9]+ ; WS: [ \t]+ -> skip ;

我們看到語法樹包含了產(chǎn)生式的名稱,這在后續(xù)處理過程中是不需要的,
因此,編譯器前端會將具體語法樹轉(zhuǎn)換成一種中間形式——抽象語法樹。

(* (+ 1 (* 2 3)) (- 4 5))

這不就是S表達(dá)式嗎?
對的,編譯器前端會將任何語言的源代碼轉(zhuǎn)換成與具體語法無關(guān)的抽象語法樹,
而S表達(dá)式正是這種抽象語法樹的線性編碼。
(因此,你寫任何語言,本質(zhì)上都是在寫Lisp。。

格林斯潘第十定律:
任何C或Fortran程序復(fù)雜到一定程度之后,都會包含一個臨時開發(fā)的、不合規(guī)范的、充滿程序錯誤的、運行速度很慢的、只有一半功能的Common Lisp實現(xiàn)。

簡化解釋器的實現(xiàn)

為了簡化解釋器的實現(xiàn),我們會直接分析S表達(dá)式(抽象語法樹),并且略過優(yōu)化環(huán)節(jié)。我們也不解釋四則運算表達(dá)式,因為這涉及到了操作符的定義問題。
我們將直接實現(xiàn)lambda表達(dá)式和函數(shù)的調(diào)用。

(define (eval-exp exp)(handle-decision-tree `((,is-symbol? ,eval-symbol)(,is-self-eval-exp? ,eval-self-eval-exp)(,is-list?((,is-lambda? ,eval-lambda)(,is-function-call-list? ,eval-function-call-list))))exp))

和其他解釋器的教材不同的是,我沒有寫那么多的if-else,
而是把決策模式提取出來了,這樣會更清晰一些。

eval-exp會根據(jù)exp的具體形式,尋找相應(yīng)的處理方式,
而各個處理方式中,還有可能再用到eval-exp來處理子表達(dá)式。
因此,這是一個遞歸執(zhí)行的過程。

下文,我們會剖析這個簡單的解釋器,
把每個處理分支都實現(xiàn)一下。

關(guān)于寫作意圖

本系列文章的寫作目的是想借著柯里化這個概念,
把函數(shù)式編程相關(guān)的知識點串聯(lián)起來。

為什么選擇柯里化呢,因為柯里化首先和高階函數(shù)相關(guān),
我可以借此來引入作用域的概念,
continuation本身就是一個單參函數(shù),順便就可以介紹了,
hygienic macro也涉及到了標(biāo)識符的查找,學(xué)了求值環(huán)境也容易理解了。

其次,帶參數(shù)的類型,可以類比函數(shù)的柯里化來理解,
要想理解帶參數(shù)的類型,我們就得學(xué)習(xí)類型,以及代數(shù)數(shù)據(jù)類型,
從而繼續(xù)深入下去,學(xué)習(xí)Functor,Applicative,Monad這些類型類。
這樣類型系統(tǒng)就揭開了神秘的面紗。

當(dāng)然,這些都是偏工業(yè)應(yīng)用的,并沒有涉及理論基礎(chǔ),
自動機(jī)理論,可計算性理論,形式語義,也不適合在本系列中提及,
寫完本系列后,我會嘗試寫其他系列,希望能覆蓋掉某些點,
以此來督促自己努力學(xué)習(xí),小心求證。

參考

程序設(shè)計語言:實踐之路
編程語言實現(xiàn)模式
The Definitive ANTLR 4 Reference
Lisp in Small Pieces
Java 是編譯型語言還是解釋型語言?
Abstract vs. Concrete Syntax Trees

總結(jié)

以上是生活随笔為你收集整理的柯里化的前生今世(四):编译器与解释器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。