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

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

一個小目標

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

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

不一樣於大部分常見的其餘只支持四則運算的所謂」手工解釋器「教程,咱們但願在代碼結構儘可能清晰的600行代碼中,手工(不借助lex/yacc等工具)完成一個腳本語言「try」,實現如下功能:express

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

(若是看不懂下面這段也不要緊,能夠略過啦)數組

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

解釋器可運行的代碼示例

遞歸計算文波那契數列 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!";
  • 循環語句:ui

    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行的解釋器雖然不算什麼大工程,但相關的原理仍是稍微有些複雜的,可能須要多花一些時間理解程序的運行過程;
  • 代碼可能難以調試,尤爲在沒有生成中間代碼的狀況下;

參考資料

相關文章
相關標籤/搜索