什麼是語義學,直譯器

2022-07-14 10:09:14 字數 1298 閱讀 8121

很多人問我如何在掌握基本的程式語言技能之後進入「語義學」的學習。現在我就簡單介紹一下什麼是「語義」,然後推薦一本入門的書。這裡我說的「語義」主要是針對程式語言,不過自然語言裡的語義,其實本質上也是一樣的。

乙個程式的「語義」通常是由另乙個程式決定的,這另乙個程式叫做「直譯器」(interpreter)。程式只是乙個資料結構,通常表示為語法樹(abstract syntax tree)或者指令序列。這個資料結構本身其實沒有意義,是直譯器讓它產生了意義。對同乙個程式可以有不同的解釋,就像上面這幅圖,對畫面元素的不同解釋,可以看到不同的內容(少女或者老婦)。

直譯器接受乙個「程式」(program),輸出乙個「值」(value)。用圖形的方法表示,直譯器看起來就像乙個箭頭:程式 ===> 值。這個所謂的「值」可以具有非常廣泛的含義。它可能是乙個整數,乙個字串,也有可能是更加奇妙的東西。

其實直譯器不止存在於計算機中,它是乙個很廣泛的概念。其中好些你可能還沒有意識到。寫 python 程式,需要 python 直譯器,它的輸入是 python **,輸出是乙個 python 裡面的資料,比如 42 或者「foo」。cpu 其實也是乙個直譯器,它的輸入是以二進位制表示的機器指令,輸出是一些電訊號。人腦也是乙個直譯器,它的輸入是影象或者聲音,輸出是神經元之間產生的「概念」。如果你了解型別推導系統 (type inference),就會發現型別推導的過程也是乙個直譯器,它的輸入是乙個程式,輸出是乙個「型別」。型別也是一種值,不過它是一種抽象的值。比如,42 對應的型別是 int,我們說 42 被抽象為 int。

所以「語義學」,基本上就是研究各種直譯器。直譯器的原理其實很簡單,但是結構非常精巧微妙,如果你從複雜的語言入手,恐怕永遠也學不會。最好的起步方式是寫乙個基本的 lambda calculus 的直譯器。lambda calculus 只有三種元素,卻可以表達所有程式語言的複雜結構。

專門講語義的書很少,現在推薦一本我覺得深入淺出的:programming languages and lambda calculi。只需要看完前半部分(part i 和 ii,100來頁)就可以了。這書好在什麼地方呢?它是從非常簡單的布林表示式(而不是 lambda calculus)開始講解什麼是遞迴定義,什麼是解釋,什麼是 church-rosser,什麼是上下文 (evaluation context)。在讓你理解了這種簡單語言的語義,有了足夠的信心之後,才告訴你更多的東西。比如 lambda calculus 和 cek,secd 等抽象機 (abstract machine)。理解了這些概念之後,你就會發現所有的程式語言都可以比較容易的理解了。

3 2 內聯語義學

文字塊中的小部分的語義。源文章 inline semantics 雖然段落和列表的目的是為了識別整段文字,但我們有時想為文字中的乙個詞 或幾個詞 提供意義。對於重要的詞,使用標籤。這 重要strong 但這並不重要。p 效果 這重要,但這並不重要。預設情況下,元素會以黑體顯示,但請記住,這只是瀏覽器...

建構函式語義學之程式轉化語義學 2

在 建構函式語義學之程式轉化語義學 1 中編譯器做了一些優化,有時他還會給你的程式更多的優化 1 在使用者層面做優化 如果程式設計師頂乙個計算用的 constructor x bar const t y,const t z x xx 以 y 和 z 來處理 xx return xx 有的編譯器開發人...

C 函式語義學

我們或許會認為呼叫類成員函式的開銷會大於呼叫普通函式,但是其實不是這樣的,呼叫普通成員函式和全域性函式開銷差不多,我們可以在vs中除錯,檢視反彙編 普通成員函式在呼叫的時候編譯器會在傳遞乙個物件的this指標 eg includeusing namespace std class a void te...