http://blog.csdn.net/gengzhikui1992/article/details/50762309
為了完整地定義編程語言,我們需要:
語法,描述程序看起來是什么樣的;
語義,描述程序的含義。
語法
語法的定義
每一種編程語言都有一系列規則,描述在那種語言中什么樣的字符串被認為是有效程序。這些規則定義了這種語言的語法。通過語言的語法規則,我們能把像 y = x + 1 這樣可能有效的程序與像 >/;x:1@4 這樣毫無意義的字符串區分開。
抽象語法樹
當然,計算機程序的預期用途是被計算機讀取,而要讀程序就需要語法解析器:這個分析器程序能夠讀取代表程序的字符串,根據語法規則檢查它是否有效,然后把它轉換成一個適合被進一步處理的結構化表示。
有各種各樣的工具能把一種語言的語法規則自動轉換成一個語法解析器。
總體來講一個語法解析器應該讀入像 y = x + 1 這樣的字符串,然后把它轉換成抽象語法樹( AST)。抽象語法樹是源代碼的一種表示,去掉了空格之類的無關細節,而只關注程序的分層結構。
語法總結
語法關心的只是程序的表面是什么樣的,而不是它的含義。程序有可能語法正確但沒有任何實際意義。例如,程序 y = x + 1 本身可能沒有任何意義,因為並沒有事先說明 x 是什么,而程序 z = true + 1 可能會在運行時候報錯,因為它試圖在一個布爾型值上加數字。
操作語義
操作語義定義
考慮程序含義的最實際方法是思考它做了些什么:在運行程序的時候,我們期望發生什么呢?在運行時編程語言中不同的結構都是如何表現的?把它們放到一起組成更大的程序時會是什么效果?
這是操作語義學( operational semantic)的基礎,這種方法為程序在某種機器上的執行定義一些規則,以此來捕捉編程語言的含義。這個機器常常是一種抽象的機器:
小步規約
那么,我們如何設計一台抽象機器,並使用它定義一種編程語言的操作語義呢?一種方法就是假想一台機器,用這台機器直接按照這種語言的語法進行操作一小步一小步地對其進行反復規約,從而對一個程序求值。不管最后得到的結果含義是什么,我們每一步都能讓程序更接近最終結果。
這種小步規約類似於對代數式求值的方式。例如, 為了對 (1×2) + (3×4) 求值,我們知道應該:
- 執行左側的乘法( 1×2 變成了 2),這樣表達式就規約成了 2 + (3×4);
- 執行右側的乘法( 3×4 變成了 12),這樣表達式規約成了 2 + 12
- 執行加法( 2 + 12 變成了 14),最終得到 14。
我們可以認為 14 就是結果, 因為通過上面步驟已經不能再進一步規約了;我們認為 14 是一個特殊代數表達式,它是一個值,有自己的含義,不需要進一步的努力了。
小步規約的形式化規則
把如何進行每一小步的規約寫成形式化規則,這個非形式化的過程就可以轉換成一個操作語義。
這些規則本身需要用某種語言( 元語言)寫下來,而這種語言通常是數學符號。
參考:《計算的本質:深入剖析程序和計算機》