前言
完善一些細節,爲最後一個function的功能添磚加瓦。實現了局部變量後,還有實現變量的local聲明、const聲明……
命名行運行suatin.exe
E:\ 的目錄
2020/03/04 23:14 <DIR> Can
2020/01/22 00:00 <DIR> File
2020/03/05 19:41 <DIR> JSP
2020/03/27 00:28 6 main.suatin
2020/03/24 17:54 <DIR> SQL
2020/03/27 00:30 1,038,336 suatin.exe
2020/03/10 11:49 48,935 test.jpg
2020/02/26 16:24 <DIR> VSCode Used
2019/11/30 04:36 <DIR> 視覺小說企劃
3 個文件 1,087,277 字節
6 個目錄 12,275,941,376 可用字節
E:\>suatin
E:\>E:\suatin.exe test.jpg
文件不是suatin類型文件
E:\>E:\suatin.exe main.jpg
文件不是suatin類型文件
E:\>E:\suatin.exe main.suatin
[0]普通語句>sum=0;
[0][result]0
suatin environment>
name isconst type funcPtr flag num str
NIL true nil 00000000 false 0
FALSE true bool 00000000 false 0
TRUE true bool 00000000 true 0
sum false number 00000000 true 0
program time consumed 73 ms
E:\>
//main.cpp
#include"Resolver.h"
int main(int argc, char *argv[]){
if (argc < 2) {//參數不夠
return 1;
}
std::string s = argv[1];
std::string suffixStr =s.substr(s.find_last_of('.') + 1);//獲取文件後綴
if (suffixStr != "suatin") {
std::cout << "文件不是suatin類型文件" << std::endl;
//system("pause");
return 1;
}
sua::g_file_dir = argv[1];//獲取文件路徑
time_t start = clock();
////初始化環境
//SHOWFUNCTIME("初始化語言環境", sua::InitEnv);
sua::InitEnv();
//sua::g_file_dir = "main.suatin";
//詞法分析
//SHOWFUNCTIME("詞法分析", sua::Lexer);
sua::Lexer();
//顯示全局中綴表達式
//SHOWFUNCTIME("全局中綴表達式", sua::ShowGlobalInfix);
////語法分析
sua::Resolver p;
//SHOWFUNCTIME("語法分析·創建語法樹", p.create);
p.create();
//SHOWFUNCTIME("語法分析·打印語法樹", p.print_ast);
//p.print_ast();
//p.print_st();
//SHOWFUNCTIME("語法分析·解釋語法樹", p.interpret);
p.interpret();
//顯示環境信息
//SHOWFUNCTIME("顯示環境信息",sua::PrintEnvInfo);
sua::PrintEnvInfo();
//釋放環境
//SHOWFUNCTIME("釋放環境", sua::FreeEnvSpace);
sua::FreeEnv();
std::cout << "program time consumed " << clock() - start <<" ms" <<std::endl;
//system("pause");
return 0;
}
精簡ID內存結構
看上一篇文章lang:自制編程語言15.5——C++如何在struct中使用union???
15.5這篇文章中,我將flag\num\str幾個的屬性結構體改成了共用體了!!!其中str的長度和其他幾個變量沒法比,單單是string這個類型都有28個字節,所以我把str屬性換成了str指針!!!
還剩下一個isconst屬性,這個屬性也可以去掉。
在語言環境(符號表)中設置一個常量區,只要檢查這個變量是否在常量區就行了,常量區不一定是全局的,每一個scope下都可以有一個常量區(也許這樣查找的時間複雜度就上來了2333)
CSDN
https://download.csdn.net/download/weixin_41374099/12278652
BDWP
鏈接:https://pan.baidu.com/s/1Rc1BntnKyh0d0aDwXZXqOw
提取碼:3pt0
設計變量棧
設計變量棧是爲了實現局部變量。爲此需要區分這樣四條語句。
- x; 表示定義全局變量或本地變量(當然,因爲是nil類型,解釋時肯定是出錯的)
- local x; 表示定義全局變量或本地變量,這個語句存在的位置不做要求
- const x; 表示定義常量,常量不區分是全局還是本地
- del x; 表示刪除某條語句,如果這條語句在本地的就刪除本地,如果在全局就刪除全局的。如果是常量,就刪除常量——如果不存在此變量,不報錯!
/*語言環境
由一個棧組成!
棧底scope=0是特殊變量區(關鍵字NIL、TRUE、FALSE就是特殊變量)
scope=1是常量區
scope=2是全局變量區
scope>2是局部變量區
*/
typedef std::map<std::string, SuatinID*> _SuatinVar_Scope_Unit;
typedef std::vector<_SuatinVar_Scope_Unit*> _SuatinVar_Stack;
extern _SuatinVar_Stack SuatinEnv;
項目演示
//test.suatin
sum = 0;
for(i=0;i<120;i=i+1)
if(i>=45)
sum = sum + i;
end
end
...
...
...
[2][result]true
[4][result]true
[5][result]6031
[3][result]119
[2][result]true
[4][result]true
[5][result]6150
[3][result]120
[2][result]false
suatin environment>
------------------------------------------------------------------------------
name type value
scope=0_[special variable zone]>
NIL nil false
FALSE bool false
TRUE bool true
scope=1_[const variable zone]>
scope=2_[global variable zone]>
i number 120
sum number 6150
------------------------------------------------------------------------------
program time consumed 2674 ms
請按任意鍵繼續. . .
這次畫的時間頗多了。。。。沒學知識只能靠奇技淫巧,這就是看不懂編譯原理的代價。。。。快點做完function就去學編譯原理啦!
CSDN
https://download.csdn.net/download/weixin_41374099/12304911
BDWP
鏈接:https://pan.baidu.com/s/1K23mufEgCimVty2XWw-mDg
提取碼:name
識別local x;const x;del x;
略
完善變量棧
略
結束了,不做了
function功能不要了,項目越來越爛,已經不想做下去了。Debug模式下,一萬個數的空循環運行消耗從一秒變成了4秒!
因爲語言環境的複雜性,導致變量查找和確認消耗大量時間。比如之前的項目中,我用了二十多個if來判斷字符串是什麼關鍵字,爲什麼不用哈希查找呢?明明哈希只用一次就找到了,不用執行多次——原因是字符串轉哈希值太浪費時間了,項目中現在的語言環境也是通過字符串求哈希值再找到變量的——
寫了一堆垃圾代碼,項目結構也亂七八糟,好多東西都是打的補丁,真出錯了連自己也不知道。不知道具體錯誤這一點呢,因爲異常太難捕獲了,自己設計的打印異常信息的機制也不完善,很多地方出了錯也不知道位置,錯誤信息與錯匹配不上!
計算都是double數據,int數據做了兩個多月也沒使用過!
解釋接口不止一個!
不能計算大數!就比如222222222222222222222222222222222x33333333333333333333333333這樣的就計算不了!
Parser只能處理簡單的語句,導致重複的結構又在Resolver裏寫了一遍!
源碼的掃描不止一遍,浪費了時間!
詞法分析全扔給正則了,鬼知道實際對源碼掃描了幾遍!
語言拋異常也無法定位到準確的行數,或者說根本沒有行數的概念!
語法分析用的相當愚蠢的方法,每次遇到一個Token就更改一下語法樹!這也是因爲不會遞歸!
現在還沒做出函數的功能!單單用後綴表達式的話,在計算機改進版那篇文章裏我已經實現了幾十個函數的使用了!
- 另外說一句,感覺語言的確做出來,雖然很簡單但是的確做出來了。比兩個月以前想要的功能更豐富一點,可是一點成就感也沒有。
這是Suatin編程語言項目目前所有的記錄了:
鏈接:https://pan.baidu.com/s/1ErD6-8pcQN01c4LQFiE7bA
提取碼:58h1