用c語言手搓一個600行的類c語言解釋器: 給編程初學者的解釋器教程(1)- 目標和前言

用c語言手搓一個600行的類c語言解釋器: 給編程初學者的解釋器教程(1)- 目標和前言

用c語言手搓一個600行的類c語言解釋器: 給編程初學者的解釋器教程(1)- 目標和前言
用c語言手搓一個600行的類c語言解釋器: 給編程初學者的解釋器教程(2)- 簡介和設計
用c語言手搓一個600行的類c語言解釋器: 給編程初學者的解釋器教程(3)- 詞法分析
用c語言手搓一個600行的類c語言解釋器: 給編程初學者的解釋器教程(4)- 語法分析1:EBNF和遞歸下降文法
用c語言手搓一個600行的類c語言解釋器: 給編程初學者的解釋器教程(5)- 語法分析2: tryC的語法分析實現

項目github地址及源碼:
https://github.com/yunwei37/tryC

一個小目標

這一系列教程希望面向初學者,使用c語言手工實現一個簡單的解釋器來玩,不需要您掌握除了c語言以外的其他前置知識,也不需要您學習過編譯原理的相關知識(當然如果能對簡單的數據結構有所瞭解的話會更好,比如樹、棧等)。

寫一個能執行代碼的解釋器不僅是一件很有(zhuang)趣(bi)的事情,大概也可以作爲剛學習完c語言的一個練手的小項目啦

不同於大部分常見的其他只支持四則運算的所謂”手工解釋器“教程,我們希望在代碼結構儘量清晰的600行代碼中,手工(不借助lex/yacc等工具)完成一個腳本語言“try”,實現以下功能:

  • 選擇和循環的流程控制語句
  • 支持的數據類型:雙精度浮點數、字符型、字符串、浮點數數組
  • 支持函數和變量的定義、函數的遞歸調用、嵌套作用域

(如果看不懂下面這段也沒關係,可以略過啦)

這個小玩意採用遞歸下降法進行語法分析,同時不顯式構建語法樹,不生成中間代碼或目標代碼,在語法分析的同時進行解釋執行;

解釋器可運行的代碼示例

遞歸計算文波那契數列 1 - 15,將結果存入數組中,並打印:

# Fibonacci sequence
func fun{ 
	if(x <= 2){  
		return(1);  
	}
	y = 0;
	x = x - 1;
	y = fun(x);
	x = x - 1;
	return(y + fun(x));
};

# save the Fibonacci sequence of 1 to 15 in an array 
array arr(15);	
x = 1;
while( x <= 15 ){
	arr[x - 1] = fun(x);
	x = x + 1;
}

puts("Fibonacci sequence:");
# print the Fibonacci sequence of 1 to 15
i = 0;
while(i < 15){			
	print(arr[i]);
	i=i+1;
}

(起名困難x)這個小玩意我們就隨便叫它tryC吧,當做是一個小的嘗試。

本人水平有限,如有疏漏之處,還請多多指教。

部分語言規則:

  • 註釋在一行內,以‘#’開頭;
  • 語句以‘;’結尾
  • 賦值語句類型:
    x = 123.4;
    x = 'c';
    x = "hello world!";
    
  • 循環語句:
    while( bool ){
        statements
    }
    
  • 選擇語句:
    if( bool ){
        statements
    }
    
    if( bool ){
        statements
    }else{
        statements
    }
    
  • 定義函數:函數參數在定義中不出現,在調用中獲取;返回值爲double
    func function_name{
        ...
        return(expression);
    }
    
    
  • 定義數組:
    array array_name(array_length);        
    
    
  • 輸入輸出:
    puts(string);
    print(num);
    read(num);
    

寫在前面

關於寫這玩意的緣由(寫的很亂可以不看系列)

之前大一學c語言的時候,老師要求實現一個四則運算的計算器,於是我想…要是能給計算器加上函數和變量的定義就好啦…那大概能算一個簡單的解釋器?我應該怎樣去實現它呢?就去查了不少資料七拼八湊加上自己腦補搓了一個出來…雖然能跑起來但是代碼混亂不堪一塌糊塗,不過也挺好玩的。

這裏的部分是過了一年之後大二學編譯原理的時候,把當時的代碼用相對比較規範完善的方式重寫了一遍,也因此希望把它整理成一個簡單的教程,讓c語言的初學者也可以愉快地搓一個解釋器玩;或者讓學過編譯原理的同學,能夠把理論和實踐聯繫起來,(不要像我一樣被一大堆的理論迷惑住或嚇跑),對於如何構造一個解釋器有個直觀感性的認識,並且發現它並不像想象的那麼困難。

需要了解的前置知識

  • c語言的指針、函數指針、結構體等
  • 遞歸的思想

心理準備

  • 寫一個600行的解釋器雖然不算什麼大工程,但相關的原理還是稍微有些複雜的,可能需要多花一些時間理解程序的運行過程;

  • 代碼可能難以調試,尤其在沒有生成中間代碼的情況下;

參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章