對(duì)于程序員來(lái)說(shuō)編譯器是非常熟悉的,每天都在用,但是當(dāng)你在點(diǎn)擊“Run”這個(gè)按鈕或者執(zhí)行編譯命令時(shí)你知道編譯器是怎樣工作的嗎?
這篇文章就為你解答這個(gè)問(wèn)題。
編譯器就是一個(gè)普通程序,沒(méi)什么大不了的
什么是編譯器?
編譯器是一個(gè)將高級(jí)語(yǔ)言翻譯為低級(jí)語(yǔ)言的程序。
首先我們一定要意識(shí)到編譯器就是一個(gè)普通程序,沒(méi)什么大不了的。
在沒(méi)有弄明白編譯器如何工作之前你可以簡(jiǎn)單的把編譯器當(dāng)做一個(gè)黑盒子,其作用就是輸入一個(gè)文本文件輸出一個(gè)二進(jìn)制文件。
基本上編譯器經(jīng)過(guò)了以下幾個(gè)階段,等等,這句話教科書(shū)上也有,但是我相信很多同學(xué)其實(shí)并沒(méi)有真正理解這幾個(gè)步驟到底在說(shuō)些什么,為了讓你徹底理解這幾個(gè)步驟,我們用一個(gè)簡(jiǎn)單的例子來(lái)講解。
假定我們有一段程序:
while (y < z) { int x = a + b; y += x;}
那么編譯器是怎樣把這一段程序人類認(rèn)識(shí)的程序轉(zhuǎn)換為CPU認(rèn)識(shí)的二進(jìn)制機(jī)器指令呢?
提取出每一個(gè)單詞:詞法分析
首先編譯器要把源代碼中的每個(gè)“單詞”提取出來(lái),在編譯技術(shù)中“單詞”被稱為token。其實(shí)不只是每個(gè)單詞被稱為一個(gè)token,除去單詞之外的比如左括號(hào)、右括號(hào)、賦值操作符等都被稱為token。
從源代碼中提取出token的過(guò)程就被稱為詞法分析,Lexical Analysis。
經(jīng)過(guò)一遍詞法分析,編譯器得到了以下token:
T_While whileT_LeftParen (T_Identifier yT_Less
就這樣一個(gè)磁盤(pán)中保存的字符串源代碼文件就轉(zhuǎn)換為了一個(gè)個(gè)的token。
這些token想表達(dá)什么意思:語(yǔ)法分析
有了這些token之后編譯器就可以根據(jù)語(yǔ)言定義的語(yǔ)法恢復(fù)其原本的結(jié)構(gòu),怎么恢復(fù)呢?
原來(lái),編譯器在掃描出各個(gè)token后根據(jù)規(guī)則將其用樹(shù)的形式表示出來(lái),這顆樹(shù)就被稱為語(yǔ)法樹(shù)。
語(yǔ)法樹(shù)是不是合理的:語(yǔ)義分析
有了語(yǔ)法樹(shù)后我們還要檢查這棵樹(shù)是不是合法的,比如我們不能把一個(gè)整數(shù)和一個(gè)字符串相加、比較符左右兩邊的數(shù)據(jù)類型要相同,等等。
這一步通過(guò)后就證明了程序合法,不會(huì)有編譯錯(cuò)誤。
根據(jù)語(yǔ)法樹(shù)生成中間代碼:代碼生成
語(yǔ)義分析之后接下來(lái)編譯器遍歷語(yǔ)法樹(shù)并用另一種形式來(lái)表示,用什么來(lái)表示呢?那就是中間代碼,intermediate representation code,簡(jiǎn)稱IR code。
上述語(yǔ)法樹(shù)可能就會(huì)表示為這樣的中間代碼:
Loop: x = a + b y = x + y _t1 = y < z if _t1 goto Loop
怎么樣,這實(shí)際上已經(jīng)比較接近最后的機(jī)器指令了。
只不過(guò)這還不是最終形態(tài)。
中間代碼優(yōu)化
在生成中間代碼后要對(duì)其進(jìn)行優(yōu)化,我們可以看到,實(shí)際上可以把x = a + b這行代碼放到循環(huán)外,因?yàn)槊看窝h(huán)都不會(huì)改變x的值,因此優(yōu)化后就是這樣了:
x = a + bLoop: y = x + y _t1 = y < z if _t1 goto Loop
中間代碼優(yōu)化后就可以生成機(jī)器指令了。
代碼生成
將上述優(yōu)化后的中間代碼轉(zhuǎn)換為機(jī)器指令:
add $1, $2, $3Loop: add $4, $1, $4 slt $6, $1, $5 beq $6, loop
最終,編譯器將程序員認(rèn)識(shí)的代碼轉(zhuǎn)換為了CPU認(rèn)識(shí)的機(jī)器指令。
總結(jié)
注意這篇簡(jiǎn)短的講解不希望給大家留下這樣的印象,那就是編譯器是很簡(jiǎn)單的,恰恰相反,現(xiàn)代編譯器是非常智能并且極其復(fù)雜的,絕不是短短一篇文章就能講清楚的,能實(shí)現(xiàn)一個(gè)編譯器是困難的,實(shí)現(xiàn)一個(gè)好的編譯器更是難上加難。
本文的目的旨在以極簡(jiǎn)的方式描述編譯器的工作原理,這樣你就不用把編譯器當(dāng)做一個(gè)黑盒了,希望這篇文章能對(duì)你有所幫助。
編輯:lyn
-
編譯器
+關(guān)注
關(guān)注
1文章
1642瀏覽量
49286
原文標(biāo)題:編譯器是如何工作的
文章出處:【微信號(hào):mcu168,微信公眾號(hào):硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論