一起寫一個解釋器(2)---看,兔子!
有一天我走在街上,突然聽到有一個聲音對我說話。
----嘿,親愛的,跟我去我的洞里看看吧
我四處張望,發現說話的是一隻掛在燈上的小喇叭。
Unbelievable,我一邊揉眼睛一邊想,我竟然也會經歷愛麗絲夢遊仙境。
我半信半疑的問
----你是一隻喇叭嗎?
----不,我是一隻兔子,童叟無欺,如假包換
----我沒看到兔子啊
----我在你腳底下
我低頭,果然看到了一隻雪白的兔子在對我眨巴眼睛。
----這不可能
----怎麼不可能?
----因為兔子不能跟人交流
----怎麼不能了?你跟那些硬邦邦的鐵疙瘩都能交流,從生物學上講,我作為兔子,肯定比那些鐵疙瘩跟你更有相似性吧?
----硬邦邦的鐵疙瘩?
----哦,我說的是電腦和手機,你不是每天都跟它們交流嗎?
----這不能算是交流
----那你告訴我什麼是交流?
我愣了一下
看到我被噎住,兔子得意洋洋。
----哈,我覺得吧,我能聽懂你說話,你能聽懂我說話,這就算交流。
嗯,好像很有道理的樣子
----那你告訴我,你是怎麼聽懂我說話的?
兔子沉默了一下,似乎在組織語言。
----剛開始,我確實不會說話,但我很想和人類交流,所以我下定決心學會說人話
其實我以前並不是不會說話,只是不會說人話而已,我會說兔子話
我們兔子的思維方式比你們要簡單很多。
----哦,我知道了,所以重點是翻譯,把我們的語言翻譯成你的語言?
----嗯,是這個道理。
----那你是怎麼翻譯的呢?
----這個過程還是很顯然的嘛
首先,我有兩隻耳朵,讓我聽到你說的話。
我們兔子嘛,肯定沒有你們人類那麼聰明,但是好在我記憶力比較好,無論你說了多少,我都會先記住。
然後,我把我記住的話拆成句子,一句一句研究。
再然後,我把每一句話拆分成一個一個詞語。
然後給每個詞語分類。
就是你們語文課教過的那些類別,主謂賓定狀補。
然後我把每個單詞按照這些類別,替換成兔子語言的主謂賓定狀補。
然後我就明白你在說什麼了。
接著我再想一句我想說的話,把它按照同樣的原則翻譯成人話,然後找一個小喇叭播放出來,當然這中間還有複雜的信號轉換,不過這就是另一個問題了。
----哦,那我可以理解一點點了,但還有一個問題。
----什麼?
----你是怎麼學會說第一句話的呢?我的意思是,一開始你根本不知道任何一句人話,這個從完全聽不懂,到能聽懂一句的過程,你是怎麼實現的呢?
----啊,這就是天賦了,我從一出生,就自然的可以聽懂特定規則的話,就是我一開始,是可以聽懂人類的簡單句的。
----簡單句?
----嗯,就是主謂賓,比如「你打我」,「我喜歡你」,「我是兔子」這樣的句子,詞語還不能複雜。然後我就用這很簡單的語法,學會了更多複雜的其他句式,你知道的,其實所有的複雜句式都可以拆成簡單句。
----哦,好像有點明白了,真是個勵志的兔子
----別扯那沒用的,去我洞里玩玩吧。
----嗯吶!
兔子學說話的過程帶給了我很大的啟發,簡單來說,應該是如下步驟:
段落變句子——>句子變簡單句——>簡單句變詞——>詞語分類——>按類別翻譯成自己的語言 ——>bingo !
轉念一想,哇,這不就是個解釋器嗎?
假設兔子是一個電腦,那麼它自己的思維方式就是機器代碼,而我們人類的語言就是高級語言。
解釋器,英文名Interpreter,一個用A語言寫的,把B語言翻譯成C語言的東西
路人:B語言和C語言我知道,A語言是什麼?Ada嗎?
更正一下,上句話中A,B,C是變數,可以是任何語言。
在寫解釋器之前,首先要搞清楚什麼是解釋器。
你寫的東西,和電腦之間有生殖隔離,就跟我和小白兔一樣,我們互相是不認識的。
這個時候就需要把你寫的高級語言的東西,翻譯成機器代碼。
我有一個翻譯系的朋友,她告訴我翻譯有兩種,一種叫筆譯,一種叫同傳。
筆譯就是把一大段外語翻譯成漢語,翻譯一整本書。
同傳就是那邊一邊說著,這邊就翻譯好了,各種高逼格的新聞翻譯會裡有。
跟這個很像,代碼之間的翻譯也有兩種方式。
1.把高級語言直接變成機器代碼,然後翻譯官走人,讓機器代碼在機器里自生自滅。類似筆譯
2.翻譯官拿著高級語言,看一句,翻譯一句,然後機器運行一句,中間有什麼翻譯的不清楚的,比如對內存分配有爭議,或者對垃圾回收進程管理有不一樣的理解,翻譯官立即處理。類似同傳
前者被稱為編譯器。
後者被稱為解釋器。
一般而言,
被編譯運行的代碼叫程序
被解釋運行的代碼叫腳本
這裡有一個大家常見的誤區,就是一個語言是編譯性語言,還是解釋性語言,其實並不是一定的,只是有習慣用法而已。比如C,大家都認為是編譯性語言,其實不一定,C也可以被解釋,但是因為C語言和彙編語言長得比較像,直接翻譯成機器代碼成本低,速度快,所以大家喜歡直接編譯。而python這種語言,語法用起來簡單,但是實際跑程序的時候還是會有各種問題,所以需要讓解釋器一直看著,但是其實如果你語法寫的很簡單,不用動態內存分配的各種東西,python也可以被編譯的,可以直接被編譯成C++,然後編譯運行,不過那樣python的特性也就沒了,所以沒人這麼做。
弄清楚了什麼是解釋器,接下來我們就可以開始寫這個解釋器了。
步驟跟上面的兔子做的事情一樣:
1.把段落變成簡單句,也就是把一大段代碼進行一下分割,變成一個一個簡單的表達式,干這個事情的東西被稱為語法分析器。
2.簡單句變成分了類的單詞,也就是把表達式的分割成符號,比如把「1+2」分成「1」,「+」,「2」,符號是最小的語義單位。干這個事情的東西被稱為詞法分析器。
3.搞清楚每部分是什麼,比如知道+是加法,1是加數,2是被加數。
4.知道這部分代碼在幹什麼之後,按照機器代碼需要的格式重寫,比如上面的「1+2」,在機器中可能是120,其中第一個1代表加數,第二個2代表被加數,0代表加法(這個規則是我瞎編的,具體怎麼樣,還是機器說了算),干這個事情的東西被稱為彙編器。
但是在機器的世界裡,是有一些不一樣的,比如說,在沒有C語言的時候,怎麼寫一個C語言的編譯器呢?就像那隻兔子怎麼學會說第一句話呢?
這個時候就要相信天賦了,跟兔子一樣,CPU一開始是認識一些東西的,當你把代碼按照特定的順序給它的時候,它就會執行一些操作,就像當你給一個加法器輸入數字的時候它會把東西加起來一樣,這是由各種與或非門構成的解碼器等東西實現的~
這個就不深究啦~如果想研究的話我們可以以後再搞....不然就要從硅的提純開始搞起了....
搞清楚寫解釋器的步驟之後,我們就可以開始擼代碼啦~
備註:
1.閱讀本系列教程需要有python基礎,需要至少會基本語法哦。
2.本系列教程的部分代碼會借鑒各種其他資料,如不小心造成侵權請告訴我,謝謝~
3.如果文章中有什麼錯誤,大家一定要毫不留情的在評論區罵我,不要縱容我誤人子弟。
4.後來我去了兔子洞里之後,兔子給我講述了關於紅藍藥丸,母體還有這個世界的真實性等一系列不可思議的故事,我開始懷疑自己生活在一個虛擬的世界裡,然後兔子趁機綁架了我,並告訴我除非有很多人給我點贊,否則不放我出去........emm......求大家救救我,謝謝~
推薦閱讀:
※用python實現一個簡易的lisp解釋器--解釋器基本結構的實現(5)
※一晚上糊出一個語言「後端」
※用python實現一個簡易的lisp解釋器--默認操作符的實現(6)