如何創(chuàng)造一門編程語言

編程語言,作為人與計(jì)算機(jī)溝通的橋梁,有著重要和深遠(yuǎn)的意義。有過計(jì)算機(jī)編程經(jīng)驗(yàn)的人,多少學(xué)習(xí)或掌握過一到多種編程語言。計(jì)算機(jī)專業(yè)領(lǐng)域的編程語言成百上千種,主流的編程語言也有數(shù)十種之多。每種編程語言面向的領(lǐng)域和特性都不盡相同,不過歸根結(jié)底是為了解決人與計(jì)算機(jī)之間溝通的效率問題,提高計(jì)算機(jī)的生產(chǎn)力。想必有不少人對(duì)那些主流編程語言的創(chuàng)造者十分傾佩,也相信有不少人會(huì)好奇一門編程語言是如何誕生的。那么如何創(chuàng)造一門編程語言呢?

總的來看,創(chuàng)造一門編程語言需要有以下幾個(gè)過程:

(1)設(shè)計(jì)語言的特性。

(2)定義語言的單詞、語法和語義。

(3)實(shí)現(xiàn)編譯器或者解釋器將程序翻譯為計(jì)算機(jī)底層表示。

(4)生成計(jì)算機(jī)程序的二進(jìn)制存儲(chǔ)格式。

(5)完善語言的運(yùn)行時(shí)環(huán)境和標(biāo)準(zhǔn)庫。

一、語言特性設(shè)計(jì)

所謂語言特性,就是編程語言為開發(fā)者提供了什么樣的原子性功能特征。比如是否支持?jǐn)?shù)學(xué)表達(dá)式計(jì)算、字符串處理,是否支持變量、函數(shù)和遞歸,是否支持分支、循環(huán)復(fù)合語句等。語言的變量類型是強(qiáng)類型、弱類型,還是動(dòng)態(tài)類型,程序是過程式、函數(shù)式,還是面向?qū)ο蟮?。是否支持模板、泛型和反射機(jī)制,是否支持多線程和并發(fā)特性,是否支持錯(cuò)誤和異常處理機(jī)制等等。

語言特性設(shè)計(jì)是一門編程語言最關(guān)鍵的環(huán)節(jié),直接決定了語言的基本特征和雛形。當(dāng)然,這也是最難的一個(gè)環(huán)節(jié),因?yàn)檎Z言設(shè)計(jì)是面向具體問題領(lǐng)域的,是語言設(shè)計(jì)者從大量的編程實(shí)踐中的獲得的總結(jié)和升華。比如C語言設(shè)計(jì)者希望面向計(jì)算機(jī)底層,擁有對(duì)操作系統(tǒng)和硬件的直接操縱能力。而Python的設(shè)計(jì)者則希望盡可能地減少操作計(jì)算機(jī)資源的繁瑣過程,以獲得語言的簡潔性、高度的靈活性和擴(kuò)展性。SQL的設(shè)計(jì)者面向具體的數(shù)據(jù)查詢和分析領(lǐng)域,希望幫助開發(fā)者獲得快速檢索和操縱數(shù)據(jù)的能力。而Go語言的設(shè)計(jì)者則希望在保留C語言優(yōu)秀功能的基礎(chǔ)上,擴(kuò)展編程語言對(duì)高并發(fā)環(huán)境的支持,并擁有垃圾回收和快速編譯的能力。

凡此種種,編程語言特性的設(shè)計(jì)都是面向具體的問題領(lǐng)域的,是語言設(shè)計(jì)者構(gòu)建于開發(fā)者和計(jì)算機(jī)之間的中間層,是對(duì)開發(fā)過程中重復(fù)功能邏輯的原子性“封裝”,最終的目的是為了提升具體問題領(lǐng)域內(nèi)的軟件開發(fā)效率。

二、單詞、語法和語義

和人類使用的自然語言類似,編程語言也有自身的單詞、語法和語義,專業(yè)上稱為詞法記號(hào)、語言文法和語義。

常見的詞法記號(hào)可以分為數(shù)字、字符、字符串、標(biāo)識(shí)符、關(guān)鍵字,以及用于連接表達(dá)式的運(yùn)算符、分割語句或者程序段落的界符等符號(hào)。這些是編程語言程序的基本單位,通過它們的有序組合,構(gòu)建出了一門編程語言形形色色的代碼片段。

編程語言的文法是用來描述語言的語法規(guī)則的,具體來說是規(guī)定詞法記號(hào)之間的排列組合的順序與規(guī)則。它描述了編程語言程序的基本模式,不符合該模式的詞法記號(hào)的排列被擋在了合法語言程序的大門之外。同時(shí),它也是各種編程語言對(duì)于開發(fā)者最明顯的差異化特征。一個(gè)有經(jīng)驗(yàn)的開發(fā)者可以很容易地通過掃視一段代碼,就能分辨出這是哪種編程語言編寫的計(jì)算機(jī)程序。

編程語言的語義描述了一段符合語言語法的程序,對(duì)于計(jì)算機(jī)而言的真正含義,是開發(fā)者最終要傳達(dá)給計(jì)算機(jī)的意愿和指令。語言的語義必須是準(zhǔn)確的、無二義性的,編譯器也正是通過語義的指導(dǎo),將計(jì)算機(jī)程序翻譯為計(jì)算機(jī)可識(shí)別的表達(dá)形式。

三、程序的翻譯

計(jì)算機(jī)程序是用來供人閱讀和修改的,計(jì)算機(jī)硬件并不能理解程序內(nèi)的思想和含義。因此,必須有一個(gè)翻譯轉(zhuǎn)換的過程,將人所表達(dá)的意愿準(zhǔn)確無誤地傳遞給計(jì)算機(jī),讓計(jì)算機(jī)明確并執(zhí)行人下發(fā)的指令。實(shí)現(xiàn)這種翻譯工作的工具就是編譯器或解釋器。

對(duì)于編譯器來說,它的輸入是人類書寫的計(jì)算機(jī)語言程序,輸出則是計(jì)算機(jī)可識(shí)別的底層表示。首先,它需要識(shí)別出程序中的單詞,即詞法分析。然后,根據(jù)單詞的組合模式識(shí)別出程序的語法結(jié)構(gòu),即語法分析。最后,根據(jù)不同的語法結(jié)構(gòu)對(duì)應(yīng)的語義,將程序按照每個(gè)語法模塊的形式轉(zhuǎn)換為計(jì)算機(jī)可識(shí)別的指令序列,即語義分析和目標(biāo)代碼生成。

眾所周知編譯器的實(shí)現(xiàn)具有一定的復(fù)雜度,其根本原因來自于語言語法的結(jié)構(gòu)靈活性和計(jì)算機(jī)底層表達(dá)形式的多樣性,這也是創(chuàng)造一門編程語言最核心的環(huán)節(jié)。

四、二進(jìn)制存儲(chǔ)

編譯器將語言程序翻譯轉(zhuǎn)換后,需要將轉(zhuǎn)換后的結(jié)果存儲(chǔ)起來,以便計(jì)算機(jī)在需要的時(shí)候?qū)⑵浼虞d、執(zhí)行。這里不可避免的涉及到兩個(gè)問題:

(1)轉(zhuǎn)換后的結(jié)果是什么樣的形式?

(2)轉(zhuǎn)換后的結(jié)果保存在哪里?

第一個(gè)問題描述的是計(jì)算機(jī)程序被轉(zhuǎn)換為怎樣的形式,才是計(jì)算機(jī)可以識(shí)別的。由于計(jì)算機(jī)中實(shí)際運(yùn)行程序的硬件模塊是CPU,因此計(jì)算機(jī)程序只有被轉(zhuǎn)換為CPU的二進(jìn)制指令格式才能被正確識(shí)別、執(zhí)行。比如常見的Intel體系的CISC指令格式、ARM體系的RISC執(zhí)行格式等。

第二個(gè)問題描述的是計(jì)算機(jī)程序轉(zhuǎn)化為二進(jìn)制指令格式后,以什么樣的方式保存在計(jì)算機(jī)的磁盤上。由于絕大多數(shù)的計(jì)算機(jī)程序是需要通過運(yùn)行在計(jì)算機(jī)硬件之上的操作系統(tǒng)加載運(yùn)行的,因此計(jì)算機(jī)程序的二進(jìn)制表達(dá)形式必須以對(duì)應(yīng)操作系統(tǒng)可識(shí)別的文件格式存儲(chǔ)。比如常見的Windows操作系統(tǒng)的PE文件格式、Linux操作系統(tǒng)的ELF文件格式等。

五、運(yùn)行時(shí)環(huán)境和標(biāo)準(zhǔn)庫

理論上講,一門編程語言如果能提供出完備的操縱操作系統(tǒng)和硬件的原子性功能就已經(jīng)成功了。但是不提供強(qiáng)大的運(yùn)行時(shí)環(huán)境支持和標(biāo)準(zhǔn)庫,是很難讓一門編程語言真正的好用和流行的。沒有人希望簡單地打印一行字符串,還需要使用編程語言提供的基本特性實(shí)現(xiàn)調(diào)用操作系統(tǒng)提供的打印接口的邏輯。Java語言之所以久興不衰,正是因?yàn)樗粌H提供了完善的運(yùn)行時(shí)環(huán)境和開發(fā)庫支持,甚至提供了更強(qiáng)大的開發(fā)框架和工具支持。

因此可見,除了完備的語言特性,為開發(fā)者提供更方便好用的庫和框架支持,消除軟件構(gòu)建過程中復(fù)雜和重復(fù)的邏輯,才是一門優(yōu)秀編程語言的長盛之道。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容