自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

當你在糾結(jié)學Python還是Java時,大二學生已經(jīng)開始造編程語言了!

開發(fā) 開發(fā)工具
我在之前的文章中說過多次,大學生在校期間應該去搞定那些基礎知識,因為大學生沒有工作的壓力,有大塊的時間,基礎知識相對枯燥,要想有成就感,可以做一些簡單的系統(tǒng),例如一個簡單的編程語言,一個有基本功能的OS......

 導讀

我在之前的文章中說過多次,大學生在校期間應該去搞定那些基礎知識,因為大學生沒有工作的壓力,有大塊的時間,基礎知識相對枯燥,要想有成就感,可以做一些簡單的系統(tǒng),例如一個簡單的編程語言,一個有基本功能的OS......

楊韜是我的知識星球“碼農(nóng)翻身”的一個大學生,他在星球提到做了一個簡單的編程語言解釋器,我建議他把過程給寫出來, 就是這篇文章了。

[[257924]]

下文的“我”就是楊韜。

為什么要自己寫一個解釋器?

從大學開始學習編程, 現(xiàn)在已經(jīng)快兩年了, 接觸了不少的編程語言。最開始入門學了C語言; 后來想寫安卓軟件, 學了Java; 接著接觸后臺開發(fā),學了Python; 后面又陸續(xù)地接觸Go, Dart, C++。 仔細算算, 已經(jīng)接觸過6門語言了!

但是仔細想想我似乎又什么也沒有學到,過年回家的時候, 遇到一個對計算機很感興趣的四年級的小朋友(ps: 小朋友會寫一點點python, html, 現(xiàn)在的小孩也太強了), 問了我諸如計算機上面的程序是怎么跑起來的, 代碼是怎么運行這種看似很基礎的問題, 可悲的是我居然對這些問題似懂非懂, 不能給小朋友很清楚地解釋出來。

我都不好意思說自己是學計算機的了, 居然連這些基礎的問題都沒有搞清楚。 這是促使我去深入學習編譯原理, 計算機組成原理和操作系統(tǒng)這些基礎知識的重要原因。

學習編譯原理最簡單的方法(對我來說)大概是自己實現(xiàn)一門編程語言, 雖然費時費力, 不過能對整個過程有個清晰的了解。

另外一個重要原因是有一種想要自己寫一門語言的沖動。 尤其是在學了這么多門語言之后就會萌生出這樣的念頭。不同的語言有不同的讓我喜歡的特性: Python有漂亮簡潔的語法, 靜態(tài)語言Go實現(xiàn)了像動態(tài)語言一樣的鴨子類型的接口, Dart有很多語法糖和方便的異步… (當然這些特性是仁者見仁, 智者見智的)。

但是又不能找到一門語言,具備所有自己喜歡的特性, 那就自己寫一個好了,可以把自己喜歡的特性都加上。

學習的過程

學校的編譯原理的課程安排在了大三, 我還沒有學過, 所以一切都是從0開始。 我先看了前橋和彌寫的《自制編程語言》一書, 這本書的實戰(zhàn)性很強, 沒有介紹太多的理論知識, 而是直接教你怎么寫編程語言。

我從這本書中了解了寫一門編程語言的大致過程和大致的思路。 不過書中的很多解釋不夠充分, 對于完全沒有接觸過編譯技術的人來說還是有點費解(也可能是我自己理解能力不夠好)。

我也是在自己了解了大致思路后就開始自己嘗試寫, 然后再回過頭來看書, 看作者提供的源代碼, 才能比較好地了解作者是在干嘛。

還有一些書中內(nèi)容介紹的不夠充分, 比如yacc和lex的使用。 這種工具畢竟比較流行, 網(wǎng)上找找別人寫的博客多看看, 自己再多嘗試就能很好地掌握。

因為更喜歡在實戰(zhàn)中學習, 所以前期只是了解了大致思路沒有特別深入的學習理論知識, 就直接開始碼代碼了。 在具體實現(xiàn)的過程中遇到問題, 再去看書或是網(wǎng)上尋找答案。

設計和實現(xiàn)

我選擇寫一個動態(tài)語言的解釋器, 而不是靜態(tài)語言的編譯器。

之所以要寫解釋器, 不是因為我更偏好動態(tài)語言, 其實相比而言我更喜歡靜態(tài)語言。 真正的原因是, 我覺得這只是***次嘗試, 很多東西都不會, 肯定會寫得很爛的,不如先就寫動態(tài)語言, 等真正學得比較好了, 再回過頭來寫一門自己喜歡的語言。

正式開始寫代碼前, 我還要給這門語言取個名字,雖然只是個練手的項目, 不過還是得有個名字吧。 取名字還正不是一件容易得事, 就像給函數(shù)或者類取一個恰如其分的名字一樣。

聽說恰當?shù)暮瘮?shù)名或類名還能反應整個項目的設計是否合理, 邏輯清晰, 語言的名字似乎并沒有這樣的意義。

我腦袋里閃過的***個名字是Cactus(仙人球, 仙人掌)。 我覺得很喜歡這個名字, 就把Cactus暫時留個我要寫的靜態(tài)語言了(希望我真的會寫, 沒有白留)。 仙人球是植物(正好是靜態(tài)的), 同樣帶刺的動物是刺猬(Hedgehog)。 動物是動態(tài)的, 正好符合我要寫的動態(tài)語言, 于是就叫Hedgehog了。

前面提到了lex和yacc, 我在自己寫的編程語言里面也使用了這兩個工具做詞法分析和語法分析。 既然是自己要寫一門語言為什么還要用別的工具呢? 當然不能以”不重復造輪子”作為借口, 我就是為了造輪子才想要自己寫編程語言的, 真正的目的是為了簡單。

前面提到我把這當作一個練手的項目, 為了熟悉整個過程, 我把簡單作為了整個過程的一個原則,很多地方我可以想到更優(yōu)但更加復雜的實現(xiàn)方式, 但是大多數(shù)仍然采用了最簡單最能保持整個項目邏輯清晰的實現(xiàn)方式。 我更多的目的是為了了解整體過程, 整體結(jié)構(gòu), 所以局部就盡量保持簡單了吧(當然比較懶也是重要原因)。

當然后續(xù)詞法分析和語法分析肯定會自己實現(xiàn)一下, 畢竟這算是編譯器或者解釋器的前端, 也很重要的。

解釋器是用C語言寫的。 之前從來沒有用C語言寫過這么大的項目(雖然到目前一共也就2千多行的代碼), 這次也讓我學會了很多C語言的高級用法。 比如 :

  1. void (*func)(void) 

是一個返回值為空, 參數(shù)為空的函數(shù)指針;

  1. void (*signal(int signo,void(*func)(int)))(int); 

是一個返回值為函數(shù)指針, 參數(shù)為(int signo,void(*func)(int)), (一個int, 一個函數(shù)指針)的函數(shù), 其中函數(shù)名為signal。

之所以用函數(shù)指針, 是為了用C語言寫面向?qū)ο螅?最開始我完全是使用面向過程, 只是簡單的通過不同文件實現(xiàn)簡單的封裝。

后來越寫越大, 就出現(xiàn)各種問題, 比如頭文件交叉引用引起編譯器報錯。 還有很多地方用面向?qū)ο罂梢愿玫貙崿F(xiàn), 比如要處理表達式的創(chuàng)建和求值, 如果能有一個表達式的接口, 就能利用多態(tài)的好處, 不需要再寫一個巨大的switch, case語句, 使用枚舉來判斷不同的表達式, 調(diào)用不同的函數(shù)。

我聽說限制程序員的不是編程語言而是編程思維, C語言當然也可以寫面向?qū)ο螅?數(shù)據(jù)可以封裝在結(jié)構(gòu)體中, 再給結(jié)構(gòu)體加上函數(shù)指針就實現(xiàn)了類的方法。

多態(tài)也可以通過自己實現(xiàn)虛函數(shù)表, 在對象初始化時把函數(shù)指針指向不同的函數(shù)就實現(xiàn)了。 大多數(shù)的面向?qū)ο蟮奶匦远加邢鄳姆椒▽崿F(xiàn), 只不過是語法上不如原生支持面向?qū)ο蟮恼Z言簡單罷了。

還有一些問題是關于這門語言本身的設計問題:

(1) for, if這類的語句中變量的作用域問題

一開始我設計的是Java, C++一樣的, for, if的代碼塊中聲明的變量, 它作用域只存在于整個代碼塊中。 后來想到了這是一門弱類型的動態(tài)語言, 獨立的運行環(huán)境也沒什么特別的用處, 于是就改成了和Python一樣: 這種代碼塊都沒有獨立的運行環(huán)境。

(2) 把函數(shù)看成什么的問題。

比如Java這種純粹面向?qū)ο蟮恼Z言, 函數(shù)只能是對象的方法。 我這里是把函數(shù)作為一種基礎數(shù)據(jù)類型, 像字符串一樣, 可以直接用于傳參, 賦值。

畢竟這是自己的編程語言,可以把它設計成自己喜歡的樣子, 所以大多數(shù)的設計都是根據(jù)自己的想法, 自己覺得怎么合理就怎么來(當然不是天馬行空地胡亂設計, 而是根據(jù)自己地實際經(jīng)驗選擇合理的設計吧)。

當然最開始寫一門編程語言的時候,有很多地方不知道怎么設計才合理, 這個時候我就參考自己學過的編程語言, 想想它為什么要采用這種設計, 出于怎樣的考慮。

這樣的思考, 讓我對之前學過的編程語言有有了更加深刻的認識, 可以說是受益匪淺吧。 我漸漸地也認識到編程語言的設計很多時候都是設計者編程思維的體現(xiàn)。

簡單地介紹一下Hedgehog

說了這么多, 是時候簡單地介紹一下我寫的這門編程語言了。目前還很簡陋, 后面再慢慢地完善它吧。

hedgehog 的多數(shù)設計和 python 比較相似, 無需聲明變量類型, if,for等語句沒有塊級作用域。

語法上又有點像 go 語言: if, for后面不需要(), 但是后面的代碼塊都必須加{};

沒有while, 不過有for condition {}來替代。 不過行尾必須加;這點和 go 不同。

大多數(shù)設計都是為了簡化實現(xiàn)方式, 比如必須加{}, ;是為了簡化語法的解析。

數(shù)據(jù)類型

  1. a = 10;  //int 
  2. b = 3.14;//float 
  3. c = true;//boolean 
  4. d = null;//null 
  5. s = "Hello, World!";//string 

控制語句

  1. a = 10; 
  2. if a > 10 { // `()` is not necessary. 
  3.     b = a+20; 
  4. } elsif a==10 { 
  5.     b = a+10; 
  6. else { 
  7.     b = a-10; 
  8. print(b); 

循環(huán)

  1. for i=0; i<10; i=i+1 { 
  2.     print(i); 
  3.     if i>=4 {break;} 
  4. i = 0; 
  5. for i<10 { 
  6.     if i<5 {continue;} 
  7.     print(i); 

函數(shù)

function也被看作一種值(基本數(shù)據(jù)類型), 不過目前還沒有對它實現(xiàn)垃圾回收, 所以直接以函數(shù)賦值或者其他操作會出現(xiàn)內(nèi)存錯誤。

  1. // 模仿python首頁的函數(shù) 
  2. func fbi(n) { 
  3.     a, b = 0, 1; 
  4.     for a<n { 
  5.         print(a); 
  6.         a, b = b, a+b;//支持這種賦值方式 
  7.     } 
  8. fbi(100); 
  1. func factorial(n) { 
  2.     if n==0 {return 1;} 
  3.     return n*factorial(n-1); 
  4. print(factorial(5)); 

目前只實現(xiàn)了一個原生函數(shù)print。 print接收一個基本數(shù)據(jù)類型作為參數(shù), 輸出并換行, 或者無參數(shù), 直接換行。

運算符

大多數(shù)與c保持一致, 除了&, |。 因為沒有提供位運算的功能, 所以直接用這兩個符號表示邏輯與和邏輯或。

  1. b = 2; 
  2. a = 10; 
  3. if a>20 & b<10 { 
  4.     print("`b` is less than 10 and `a` is greater than 20"); 
  5. if a>20 | b<10 { 
  6.     print("`b` is less than 10 or `a` is greater than 20"); 

“What I cannot create, I do not understand。” 我喜歡這種從自己制作過程中學習的方式。 這種方式給了我一種踏實感, 讓我覺得自己是真地明白了整個過程,而不是僅僅記住了什么公式, 學會了調(diào)用新的API。

【本文為51CTO專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請通過作者微信公眾號coderising獲取授權(quán)】

 

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2015-03-13 10:40:37

2020-08-07 07:39:19

編程語言JavaPython

2020-06-01 08:46:35

機器學習數(shù)學Python

2018-07-20 10:32:13

編程語言JavaPython

2017-09-04 17:35:27

麻省理工學院細菌乳膠

2017-02-24 14:05:14

AndroidMVCMVP

2019-04-22 09:58:25

C語言Web操作系統(tǒng)

2019-07-01 08:00:00

編程語言Java技術

2010-03-11 15:39:01

Python編程語言

2022-07-20 13:55:28

算法AI人工智能

2021-04-06 15:20:05

編程語言JavaIT

2021-01-13 14:55:54

JavaPython開發(fā)

2022-09-16 07:32:15

編程計算機命令

2020-06-05 08:31:29

編程語言RPython

2019-08-05 14:34:41

編程語言技術Java

2020-12-09 13:54:20

編程語言C語言Python

2017-02-07 09:37:46

2021-09-18 14:59:58

語言PythonC語言

2020-09-16 13:08:17

微信兒童版天眼查騰訊

2012-06-28 13:37:14

點贊
收藏

51CTO技術棧公眾號