經過許久的折騰,hello world是出來了。
目前語言自身的類庫還未準備好,所以直接調用了.net庫來實現基本控制臺輸出功能。
很多人問我這個語言有什么優勢,我想了下,優勢就是它是自己的語言,可以DIY。
語言只是個工具,我不指望有多少人可以用它。但我的目標是
做一個既能像C#一樣方便、又能像C++一樣跨平臺、不可反編譯的語言。
編譯原理是開發語言首先會想到的知識,而事實上,編譯原理只是語言開發的一個很小的階段。
很多人說自己懂編譯原理,其實也就是了解了LR之類的高科技詞語。這些人整天就知道做個解析器
解析一些代碼,事實上他們的工作只限于解析,解析只是為了炫耀他們會編譯原理。
真正開發一門語言,技術上需要至少需要包含這些東西:
1. 編譯器(或解釋器)
2.運行庫
一個腳本語言解釋器由這些部分組成:
詞法解析器 -> 語法解析器 ->解釋執行器
為了提高執行效率,解釋器改進為以下部分組成:
詞法解析器 -> 語法解析器 ->即時編譯器(JIT)-> 代碼優化器 -> 解釋執行器
一個編程語言編譯器由這些部分組成:
詞法解析器 -> 語法解析器 ->語義分析器 -> 代碼優化器 ->代碼生成器
運行庫是語言能執行的必要條件。比如js來說,內置對象就是運行庫。對于C++來說 <stdlib.h>就是運行庫。
如果需要開發一個包含 100種語法的且真實能用的編程語言,那么需要的時間是:
詞法解析器 1 + 語法解析器 10 + 語義分析器 100 + 代碼優化器 + 30 + 代碼生成器 100 + 運行庫 1000 。
如果有人突然有興趣想做個語言玩玩,然后花了11天時間終于折騰個語法解析器出來,對不起,你還需要 1230天來完成整個語言。
所以,開發語言不僅是技術難題,更是時間難題。
我已經開發完語言的大部分內容,總結下幾個難題,以及解決思路。當然,對于腳本語言,碰到的問題會少很多。
但是,我覺得像javaScript, Python都做的非常好了,真的我們也不需要新的腳本語言。
1.語言如何調用操作系統的 API實現文件讀寫操作?
2.如何檢測代碼內部的死循環?用過 C#的人都知道,下面的代碼會得到一個警告:
void Main(){ while(true) { } return; // 警告: 檢測到無法訪問的代碼}
3.如何支持泛型,支持GC,支持閉包,支持很多很多的流行特性?
也許這些問題你可以不解決,但試問,這些功能都沒有的語言還值的用么。
我想更多的人應該期望給自己做個腳本語言玩玩,或者可以給工作提高很多效率。
這些腳本語言可以不需要自己的運行庫,它可以轉為現成的語言執行。
這樣的語言開發起來其實不難,現在演示如何開發一個可以翻譯為Javascript 的語言。
一、做語法解析器
自己寫解析器其實很累,所以找一個現成語法生成器,用法可以看它的文檔。語法解析器的目標是將語言代碼字符串轉換為語法樹。
因為有太多教程介紹語法解析器做法,這里不再重點說明。
二、做代碼轉換器
語法樹是代碼解析后的一個數據結構,通過遞歸遍歷語法樹,可以知道代碼中有什么,然后進行相應的轉換操作。
var input = [ { type: 'if', condition: { type: 'int', value: '1' }, then: [ { type: 'funcCall', value: 'alert' } ] } ];var output = [];function visitNode(node) { if(node.type == 'if') { return visitIf(node); } if(node.type == 'funcCall') { return visitFuncNode(node); } if(node.type == 'int') { return visitInt(node); }}function visitIf(node) { visitNode(node.condition); visitNode(node.then); visitNode(node.elseNode);}function visitFuncCall(node) { output.push(node.value); output.push('('); visitFuncArguments(node.arguments); output.push(')');}function visitInt(node) { output.push(node.value);}
新聞熱點
疑難解答