編譯原理 TINY編譯器學習(一)

2021-06-22 14:00:12 字數 2132 閱讀 3872

《編譯原理及實踐》中附帶的tiny編譯器,**僅有幾千行,

這點**就實現了乙個完整的編譯器,及對應的目標**執行程式,接下來會用一段時間研究下這個**。

1. 源****

2. 原始碼結構

globals.h    main.c

util.h          util.c

scan.h        scan.c

parse.h      parse.c

symtab.h    symtab.c

analyze.h   analyze.c

code.h        code.c

cgen.h        cgen.c

其中scan、parse、analyze和cgen檔案分別對應於**掃瞄程式、分析程式、語義分析程式和**生成器各階段。

3. 關鍵函式

syntaxtree = parse( );

對應於詞法分析及語法樹生成。

buildsymtab(syntaxtree);

建立符號表

typecheck(syntaxtree);

型別檢測

codegen(syntaxtree, codefile);

目標**生成

同時工程採用了三個編譯巨集,可以分階段進行控制編譯器輸出

noparse      建立只掃瞄的編譯器

noanalyze  建立只分析和掃瞄的編譯器

nocode       建立執行語義分析但不生成**的編譯器

4. 使用方法

編譯此工程生成tiny.exe程式,可以通過 tiny.ext sample.tny可以對源**sample.tny進行編譯,生成sample.tm可執行檔案。

tm檔案只有在特定的虛擬機器上才能執行,對應的虛擬機器是tm.exe。

編譯tm.c可以生成tm.exe程式,執行tm.exe sample.tm就可以執行最終的程式。

5. 目標**直觀印象

5.1 待翻譯的源**:

a[index] = 6

5.2 普通的彙編**:

mov r0, index ;; value of index -> r0

mul r0, 2       ;; double value in r0,乘以2是因為陣列型別佔兩個位元組

mov r1, &a    ;; address of a -> r1

add r1, r0     ;; add r0 to r1

mov *r1, 6    ;; constant 6 -> address in r1

5.3 tiny目標**:

ldc 1, 0 ( 0 )  ;; load 0 into reg 1

ld 0, 68 ( 1 )  ;; load val at (68+r1) into r0; 假設index 在儲存器位址68中,注意這裡load的是位址裡的值,不是位址,注意和lda的區別。

ldc 1, 2 ( 0 )  ;; load 2 into reg 1

mul 0, 1, 0     ;; put r1 * r0 into r0

ldc 1, 0 ( 0 )  ;; load 0 into reg 1

lda 1, 20 ( 1 ) ;; load 20 + r1 into r0; 假設a在儲存器位址20,注意這裡load的是位址,不是位址裡存的值,注意和ld的區別。

add 0, 1, 0     ;; put r1 + r0 into r0

ldc 1, 6 ( 0 )  ;; load 6 into reg 1

st 1, 0 ( 0 )    ;; 將r1中存的6放到最終陣列的位址中。

6. sample.tny

read x;

if 0 < x then

fact := 1;

repeat

fact := fact * x;

x := x - 1

until x = 0;

write fact  

end這段程式使用tiny語言實現了乙個階乘計算程式,其中{}用於注釋,repeat-until類似於pascal語言。

7. 關於tm程式

大致瀏覽了下tm.c的源**,其實現就是將tiny目標語言翻譯成對應的c語言實現,相當於使用c語言實現了tm虛擬機器。

編譯原理 編譯器結構

編譯器是具有高度模組化的一種結構,說白了就是編譯的任務被劃分為乙個個小的子任務,交付給不同的小模組來執行。這些小模組的序列 順序 執行,對應的就是小任務的序列實現,最終就實現了編譯這個總任務。所以說編譯器也可以看成由多個階段構成的流水線結構 如圖所示,一種簡單的 流水線 式的編譯器結構 這個是具有優...

編譯原理 編譯器的編譯基本過程

原文出處 崤嶙的部落格 編譯器最基本的功能就是把高階語言 例如c fortran 編寫的 轉化為機器指令 就是01串 從這個角度來說它本質上是個轉換過程。經典的編譯過程主要包括 1 詞法分析 lexical analysis 2 語法分析 語法分析的輸入是一連串的token 詞法分析的輸出 根據語言...

tiny 的編譯原理實踐

首先將tm.c的執行得到tiny虛擬機器 globals.h main.c util.h util.c scan.h scan.c parse.h parse.c symtab.h symtab.c analyze.h analyze.c code.h code.c cgen.h cgen.c 拷貝...