顯示廣告
隱藏 ✕
※ 本文為 MindOcean 轉寄自 ptt.cc 更新時間: 2019-01-31 17:54:28
看板 Gossiping
作者 aeolus811tw (aekt)
標題 Re: [問卦] 寫編譯器的人是不是很屌?
時間 Thu Jan 31 06:46:02 2019


以下文章我盡力用中文說明部分

Debugger 只是一種輔助你除錯的工具而已, 他並不算語言編譯的一種
在程式語言編譯世界裡主要分為兩種
Compiler (編譯器) & Interpreter (翻譯器)
而各自還有更多的細分.

編譯器主要把程式碼變成機器碼讓人執行
翻譯器不變成程式碼的直接執行, 一般用在除錯/Script語言上

編譯器分為前後兩端, 而其流程為:

1. Lexical Analysis (字元分析)
將程式碼本身分割成為字塊(lexemes), 每個字塊都需要有相對的資料結構保留
譬如

if (1 == 1){}
會被分裂為
if, (, 1, ==, 1, ), {, }

如果你有寫過計算機的prefix / postfix notation就差不多能明白為何要這樣分割
當遇到無法理解的字元的時候(如if 打成 ef)就對丟錯

2. Syntax Analysis (結構分析)
將字元分析後取得的字塊組成一個AST (抽象語法樹), 這是為了保留資料的邏輯結構
譬如
樓上的案例會被做成
            if
          /    \
         =     nil
      1     1
如果有不對稱邏輯問題, 這步會丟出相關的錯誤 (如少打'}')

3. Semantic Analysis (語意分析)
利用第二步產生的AST來檢查是否有違反語言的規矩
這一步會檢查你是否有打錯計算符號, 檢查你的物件的類別是否正確, 以及推論出物件的類別
譬如
javascript / swift     / python
你可以用
let x = 1 /  var x = 1 / x = 1

在非C / Java 那種強烈識別(Strong typed)的語言裡, 語意分析就需要把這些變數的類別型態推論出來

這步如果遇到型態不符的問題會丟錯
完畢後會產生aAST (已標示抽象語法樹) 和 Symbol Table (符號表)
符號表內部會記錄目前遇到的任何函式字符&變數名字

4. Intermediate Code Gen (中間語法產生)
利用第三步產生的aAST來產生無硬體依賴性的低階語法
最常見為3AC (Three Address Code)
這種就很類似ASM 只不過還帶有你所知的計算符號等內容

譬如
第三步的if可能會變成
t1 = 1 eq 1
ifz t1 goto L1

以上為前端作業
完畢後就換後端作業

5. Optimization (最佳化)
這步會把第四步的產生結果進行刪減/重排列作業
譬如
要是你第四步產生了
t1 = x - 2
t2 = x * t1
t3 = t2 / 6
o1 = t3

可能會被最佳化為

t1 = x - 2
t2 = x * t1
o1 = t2 / 6

6. Code Generation (機器碼產生)
這一步會把第五步的吐出物轉成相關硬體規範的機器碼
譬如
t1 = x - 2
t2 = x * t1
o1 = t2 / 6

可能會變成
lea eax, x
sub eax, 2
mul eax, n
div eax, 6
ret eax

以上為很基礎的編譯器運作方式. VM Bytecode 之類的會加雜其他步驟, 不過大致上雷同
而翻譯器的話跟一開始所說的一樣跟編譯器很相似
差異在於翻譯器是單行翻譯完就直接跑, 直接跳過最佳化步驟
他會一直跑下去直到遇到錯誤

除錯的話一般就跟著最後產生的機器碼來執行
而除錯能一步一步走主要是利用跟翻譯器互動所達成的
BP 就是設定翻譯器要偵測的錯誤或硬體自己截斷的錯誤
讓翻譯器一直跑, 直到條件達成就丟錯的斷點錯誤


很多防盜版 / 防駭程式都會特別去偵測斷點錯誤來故意跑不同路線或直接讓系統死當
如hackshield & nProtect (玩過網路遊戲的應該都知道這兩款)
他曾經用過計時計算時間的手法來確保程式不會因為被斷點而暫停來讓反制反編譯

要說差很多? 未必
因為大致上有一定程度的關聯性.
當然你要說它們用處有差別就另當別論了.

要避免最佳化的除錯是因為要確認錯誤並非由編譯器所生, 如heisenbug.
而一步步的除錯也是IDE普遍化後才大眾化的功能, 在那之前的語言幾乎都沒提供完善版的功能
在石器時代能有IDE就該謝天謝地 (用emac, vi/vim, notepad 寫過程式的人應該都懂這個痛苦)

可是你最後丟出的東西都是最佳化過的, 因此你終究還是得從最佳化機器碼下手來除錯.



※ 引述《KILLE (啃)》之銘言:
: ※ 引述《paupauGO (ouo)》之銘言:
: : 就是阿
: : 寫程式的時候都需要編譯器
: : 可以code出各種東西
: : 但本魯很好奇的是
: : 編譯器到底是怎麼寫出來der
: : 內建各種方法,可以除錯跟設中斷點
: : 這麼屌的東西要開發應該hen辛苦ㄅ
: : 能寫出這麼厲害的工具的人是不是很猛?
: : -----
: : Sent from JPTT on my Asus ASUS_Z017DA.

--
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 17.115.109.225
※ 文章代碼(AID): #1SKYaiWp (Gossiping)
※ 文章網址: https://www.ptt.cc/bbs/Gossiping/M.1548888364.A.833.html
moonshade: 終於出現一篇正確的,推認真1F 01/31 06:50
backzerg: 這種時間出現這種專業文 不會是工作到天亮吧2F 01/31 06:51
moonshade: 但現在最佳化有一大半是code gen在做3F 01/31 06:51
moonshade: 其實cmd line用習慣是覺得IDE沒必要,IDE的好處是
moonshade: 找code,但是tag/cscope都做得到,所以emacs/gvim並
moonshade: 不會很痛苦(除了碰到多重繼承的C++以外...)
birdman0131: 這時間這種文是怎麼回事XD7F 01/31 06:55
uglybaby: 看不懂8F 01/31 06:56
ernova831: 認真推推9F 01/31 06:58
neo5277: 在八卦這麼認真做什麼…10F 01/31 07:09
GGing: 推!但嚴格來說 compiler 不一定是把 source code 直接變11F 01/31 07:09
GGing: 成 machine code。像 Javac 就是變成 byte code,然後 JVM
GGing:  才把 byte code 變成 machine code。
mate520te: 推一個14F 01/31 07:13
oilcaptain: 認真推15F 01/31 07:18
rex44391: 推 認真文16F 01/31 07:28
tinderbox: 推!17F 01/31 07:32
kipi91718: 推認真文18F 01/31 07:32
sweeteason: 認真推19F 01/31 07:36
tonylovesm: 跟我想的一樣20F 01/31 07:38
exceedMyself: 推21F 01/31 07:39
youchen68: 推,我以為要寫成001100之類的…(遮臉)XDDD22F 01/31 07:39
iamp42002: 幹……看不懂23F 01/31 07:43
khalid: 名人耶 應該是教主死對頭24F 01/31 07:45
zxc1028: 快推 不然別人以為我不懂25F 01/31 07:49
OGC218: 文組· · 路過26F 01/31 07:50
twPenn: 編譯器4ni?27F 01/31 07:54
silentence: 已經很淺白了 再深入一點就是天書領域了28F 01/31 07:56
amethystboy: 推認真29F 01/31 07:57
chunglee: 推,雖然看不懂30F 01/31 07:57
mhliu8: .NET 也是,C# Code# CompilerLNET Runtime31F 01/31 08:00
mhliu8: IT CompilerachinecodeExecution
mhliu8: C# Code# Compiler誄誃ET Runtime訿T Co
mhliu8: mpiler趏chinecode Execution
jass87987: 可以不要這麼專業嗎35F 01/31 08:04
mhliu8: 忘了濾掉特殊符號XD, 應該是 C sharp Code 轉 C sharp Com36F 01/31 08:04
mhliu8: piler 轉 IL 轉 .NET Runtime 轉 JIT Compiler 轉 machine
mhliu8:  code 轉 Execution
tsts286822: m起來39F 01/31 08:06
s0805744: 推40F 01/31 08:13
chrisgod: 專業推41F 01/31 08:13
mmc109815038: 哈哈哈  看不懂 XDDDDD42F 01/31 08:13
tmwolf: 認真推43F 01/31 08:14
moebear: 推 剛修完編譯器44F 01/31 08:17
berice152233: 嗯嗯,跟我想的一樣,晚餐我想吃燒鴨45F 01/31 08:19
pan568655: 推46F 01/31 08:21
Wand 
Wand: 這種文都是凌晨發,肝表示:47F 01/31 08:25
iyoweiya543: 推48F 01/31 08:28
LostInTime: 加班辛苦了,推推49F 01/31 08:32
whywhywhy: 我也是這樣想的50F 01/31 08:33
foxher: 熬夜寫程式,我懂51F 01/31 08:35
ym951305: 看不懂  推52F 01/31 08:36
Marty: 半夜寫程式 就像開了加速器 Coding的日常~53F 01/31 08:37
smallcar801: 半夜才是碼農的子彈時間54F 01/31 08:42
jeormy: 推55F 01/31 08:43
amows: 強者推56F 01/31 08:44
jungkailin: 推!57F 01/31 08:45
perytech: 好文推!58F 01/31 08:46
CRong: 看不懂的推59F 01/31 08:48
SaChiA55688: 強者推推60F 01/31 08:53
OldYellowDog: 推61F 01/31 08:59
Arctica: 推 長知識62F 01/31 08:59
Jruffian: 推,優質好文63F 01/31 09:01
kisweet999: 最佳化除了精簡指令外, 就是避免掉資料危障吧64F 01/31 09:01
goldflower: 像Jeff Dean直接寫機器碼就沒這麼多問題惹(?)65F 01/31 09:05
saturn22k: 這學期剛修完,頭好痛66F 01/31 09:06
KBTIT: 我也是這麼覺得67F 01/31 09:06
youjan: 快推68F 01/31 09:06
Luluemiko: 推推69F 01/31 09:12
LucasChen: push70F 01/31 09:14
s860134: 一學期的課71F 01/31 09:25
jerry0715no1: 專業 推72F 01/31 09:32
wahaha99: 專業推73F 01/31 09:36
cool9203: 推,編譯器前端,但我也沒學過,好想學ㄚ74F 01/31 09:38
shiyo729: 幫加班到凌晨QQ75F 01/31 09:38
choe9129: 太厲害了76F 01/31 09:40
mimiasd0722: 推77F 01/31 09:40
dreamnook: 認真推78F 01/31 09:53
pjason: 推,有機會會來深入研習一下79F 01/31 09:56
hw1: 推  我大學修的砍拍了全都還給學校了 XD80F 01/31 09:56
XperiaZ6C: 你一定是剛下班回文81F 01/31 09:58
keyman2: 嗯????82F 01/31 09:59
shaner: 好專業83F 01/31 10:02
yukinoba: 要對機器碼debug記得optimization level不能太高...84F 01/31 10:04
hikku: 完全看不懂 能讀懂這種東西的人到底是怎麼辦到的啦85F 01/31 10:12
selfhu: 推86F 01/31 10:16
harrishu: 文組看不懂 幹87F 01/31 10:16
joick50506: 推88F 01/31 10:27
octangus07: 專業推89F 01/31 10:38
MoseHas: 好像重回了大三在修compiler的感覺QQ90F 01/31 10:42
CityRanger: 看懂了 推推91F 01/31 10:51
bbo6uis122: 推92F 01/31 10:54
a5245242003: 推93F 01/31 11:00
penta: 有修過相關科目蠻好懂的XD94F 01/31 11:20
david220: 嗯嗯,跟我想得差不多95F 01/31 11:25
dfast: 只懂得 if else96F 01/31 11:29
sonicyang: vim才不痛苦 IDE才痛苦吧97F 01/31 11:39
oxlittle: 寫的真好98F 01/31 11:42
vul3kuo: CS本科就有教 只是一堆半路出家來寫程式的才覺得很神99F 01/31 11:57
YaLingYin: 看不懂QQ100F 01/31 12:01
abb123456: 看不懂101F 01/31 12:11
atony8155: 謝謝102F 01/31 12:11
liflguy: 大一就介紹過了吧103F 01/31 12:20
Everyeeeee: 趕快推104F 01/31 13:14
e369585: 推優質文章105F 01/31 13:14
Kemuel:106F 01/31 13:26
lucas323: 推107F 01/31 14:15
MidoBanA: 推108F 01/31 14:19
Corydoras: 文組看不懂啦109F 01/31 14:32
Luba: 跪求履歷啊110F 01/31 16:20
GentelMark: 優文111F 01/31 16:35
ph49: 你在八卦板這麼認真幹嘛…112F 01/31 16:54
shiwa: 推推113F 01/31 17:18
xianyuyu:114F 01/31 17:33

--
※ 看板: Gossiping 文章推薦值: 1 目前人氣: 0 累積人氣: 1478 
※ 本文也出現在看板: K_hot whatla 以及 1 個隱藏看板
分享網址: 複製 已複製
1樓 時間: 2019-01-31 14:51:16 (台灣)
  01-31 14:51 TW
時光彷彿回到過去......
r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇