TCC(TinyC)编译器汉化(中文编译器、汉语编程)之一:主文件汉化
生活随笔
收集整理的這篇文章主要介紹了
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之一:主文件汉化
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
源碼下載:https://download.csdn.net/download/yuan722723/13191360
一直想學習編譯器,偶然的機會接觸到TCC(TinyC)編譯器源碼。分析源代碼是學習一個項目的最好的學習途徑之一。自己最愛的母語—中文(漢語或華語)竟然沒有一個編譯器。果斷自己漢化一個?,F將漢化源碼分享出來??梢詫崿F編譯器自舉(自我迭代)。
特別聲明:本編譯器基于tcc(TCC - Tiny C Compiler。 Copyright ? 2001-2004 Fabrice Bellard)優化漢化。
全中文編程測試代碼:
運行結果如圖:
基于win32api可以實現界面編程,測試效果圖:
zhi.c完整源碼如下:
#導入 "zhi.h" #如果 是_源文件 # 導入 "hexinku.c" #結束如果 #導入 "工具集.c"/*****************************幫助*****************************/ 靜態 常量 字符型 幫助[] ="————————————————————————————————————————————————\n"" 知心編譯器 "ZHI_VERSION" - 版權 (C) 2020-2020 Fabrice Bellard \n""————————————————————————————————————————————————\n"" 用法: zhi [選項...] [-o 輸出文件] [-c] 輸入文件...\n"" zhi [選項...] -run 輸入文件 [參數...]\n""————————————————————————————————————————————————\n""常規指令:\n"" -c 僅編譯-生成目標文件(zhi -c 文件名.c -o 文件名.o)\n"" -o outfile 設置輸出文件名(zhi 文件名.c -o 文件名.exe)\n"" -run run 編譯源文件。\n"" -fflag 設置或重置 (帶“ no-”前綴)“ flag”(詳見zhi -hh)\n"" -std=c99 符合ISO 1999 C標準 (默認).\n"" -std=c11 符合ISO 2011 C標準.\n"" -Wwarning 設置或重置 (帶“ no-”前綴)“警告”(請參見zhi -hh)\n"" -w 禁用所有警告\n"" -version/-v 顯示版本信息\n"" -vv 顯示搜索路徑或加載的文件\n"" -h -hh 顯示幫助,顯示更多幫助\n"" -bench 顯示編譯統計\n"" -幫助/-about 顯示關于知心編譯器的信息\n"" - use stdin pipe as infile\n"" @listfile 從列表文件讀取參數\n""————————————————————————————————————————————————\n""預處理指令:\n"" -Idir 添加包含路徑“ dir”\n"" -Dsym[=val] 用值'val'def'sym'\n"" -Usym 未定義的 'sym'\n"" -E 僅預處理(zhi -E 文件名.c -o 文件名.i)\n""————————————————————————————————————————————————\n""鏈接器指令:\n"" -Ldir 添加庫路徑“ dir”\n"" -llib 與動態或靜態庫“ lib”鏈接\n"" -r 生成(可重定位)目標文件\n"" -shared 生成共享庫/ dll。(zhi -shared dll.c,生成dll.dll文件。).\n"" -rdynamic 將所有全局符號導出到動態鏈接器\n"" -soname 設置要在運行時使用的共享庫的名稱\n"" -Wl,-opt[=val] 設置鏈接器選項(請參見zhi -hh)\n""————————————————————————————————————————————————\n""調試器指令:\n"" -g 生成運行時調試信息\n" #如果已定義 配置_ZHI_邊界檢查" -b 使用內置內存和邊界檢查器進行編譯(隱含-g)\n" #結束如果 #如果已定義 ZHI_配置_記錄回滾" -bt[N] 與backtrace鏈接(堆棧轉儲)支持[顯示最多N個調用者]\n" #結束如果"————————————————————————————————————————————————\n""綜合指令:\n"" -x[c|a|b|n] 指定下一個文件的類型(C,ASM,BIN,NONE)\n"" -nostdinc 不使用標準系統包含路徑\n"" -nostdlib 不與標準crt和庫鏈接\n"" -Bdir 設置zhi的私有include / library目錄\n"" -MD 生成make的依賴文件\n"" -MF file 指定依賴文件名\n" #如果 已定義(ZHI_TARGET_I386) || 已定義(ZHI_TARGET_X86_64)" -m32/64 遵循i386 / x86_64交叉編譯器\n" #結束如果"————————————————————————————————————————————————\n""工具:\n"" 創建庫 : zhi -ar [rcsv] lib.a 文件\n" #如果已定義 ZHI_TARGET_PE" 創建定義文件: zhi -impdef lib.dll [-v] [-o lib.def]\n" #結束如果"————————————————————————————————————————————————\n""特殊指令:\n"" -P -P1 使用-E:無/替代#line輸出\n"" -dD -dM 使用-E:輸出#define指令\n"" -pthread 與-D_REENTRANT和-lpthread相同\n"" -On 與-D__OPTIMIZE__對于n相同 > 0\n"" -Wp,-opt 與-opt相同\n"" -include file 在每個輸入文件上方包含“文件”\n"" -isystem dir 將'dir'添加到系統包含路徑\n"" -static 鏈接到靜態庫(不推薦)\n"" -dumpversion 印刷版\n"" -print-search-dirs 打印搜索路徑\n"" -dt 使用-run / -E:自動定義“ test _...”宏\n""————————————————————————————————————————————————\n""忽略的指令:\n"" --param -pedantic -pipe -s -traditional\n""-W... 警告:\n"" all 打開一些(*)警告\n"" error 第一次警告后停止\n"" unsupported 警告有關被忽略的選項,編譯指示等。\n"" write-strings 字符串是常量\n"" implicit-function-declaration 警告缺少原型 (*)\n""-f[no-]... 標記:\n"" 無符號-字符型 默認字符是無符號的\n"" signed-字符型 默認字符已簽名\n"" common 使用公共部分而不是bss\n"" leading-underscore 修飾外部符號\n"" ms-extensions 在結構中允許匿名結構\n"" dollars-in-identifiers 在C符號中允許使用'$'\n""-m... 針對特定選項:\n"" ms-bitfields 使用MSVC位域布局\n" #如果已定義 ZHI_TARGET_ARM" float-abi hard/softfp on arm\n" #結束如果 #如果已定義 ZHI_TARGET_X86_64" no-sse 在x86_64上禁用浮動\n" #結束如果"————————————————————————————————————————————————\n""-Wl,... 連接器指令:\n"" -nostdlib 不要與標準crt / libs鏈接\n"" -[no-]whole-archive 完全/僅根據需要加載庫\n"" -export-all-symbols 與-rdynamic相同\n"" -export-dynamic 與-rdynamic相同\n"" -image-base= -Ttext= 設置可執行文件的基地址\n"" -section-alignment= 在可執行文件中設置節對齊\n" #如果已定義 ZHI_TARGET_PE" -file-alignment= 設置PE文件對齊\n"" -stack= 設置PE堆棧儲備\n"" -large-address-aware 設置相關的PE選項\n"" -subsystem=[console/windows] 設置PE子系統\n"" -oformat=[pe-* binary] 設置可執行輸出格式\n""————————————————————————————————————————————————\n""預定義的宏:\n"" zhi -E -dM - < nul\n" #否則" -rpath= 設置動態庫搜索路徑\n"" -enable-new-dtags 設置DT_RUNPATH而不是DT_RPATH\n"" -soname= 設置DT_SONAME elf標簽\n"" -Bsymbolic 設置DT_SYMBOLIC elf標簽\n"" -oformat=[elf32/64-* binary] 設置可執行輸出格式\n"" -init= -fini= -as-needed -O (忽略)\n""————————————————————————————————————————————————\n""預定義的宏:\n"" zhi -E -dM - < /dev/null\n" #結束如果"————————————————————————————————————————————————\n""另請參見知心編譯器手冊以獲取更多詳細信息.\n""————————————————————————————————————————————————\n";靜態 常量 字符型 關于[] =" 知心編譯器是完全支持中文(漢語或華語)的全中文編譯器,可跨平臺(windows和linux)。\n"" 目標:為中文提供更好的中文編程開源編譯器,編譯出的源代碼更優化更高效。\n"" 知心編譯器、知音IDE和知意server共同構建完善的編程環境。開源編譯器源碼下載。\n"" 特別聲明:本編譯器基于tcc(TCC - Tiny C Compiler。 Copyright (c) 2001-2004 Fabrice Bellard)優化漢化。\n"" 為編譯器學習愛好者提供更好的完整的開源的中文編譯器。\n"" 郵 箱:121118882@qq.com \n"" 碼云:https://gitee.com/zhi-yu-yan/zhixin.git\n";靜態 常量 字符型 版本信息[] ="zhi 版本 "ZHI_VERSION" (" #如果已定義 ZHI_TARGET_I386"i386" #否則如果 已定義 ZHI_TARGET_X86_64"x86_64" #否則如果 已定義 ZHI_TARGET_C67"C67" #否則如果 已定義 ZHI_TARGET_ARM"ARM" #否則如果 已定義 ZHI_TARGET_ARM64"AArch64" #否則如果 已定義 ZHI_TARGET_RISCV64"riscv64" #結束如果 #如果已定義 ZHI_ARM_HARDFLOAT" Hard Float" #結束如果 #如果已定義 ZHI_TARGET_PE" Windows" #否則如果 已定義(ZHI_TARGET_MACHO)" Darwin" #否則如果 已定義(__FreeBSD__) || 已定義(__FreeBSD_kernel__)" FreeBSD" #否則" Linux" #結束如果")\n";靜態 無類型 打印_目錄(常量 字符型 *目錄類型, 字符型 **paths, 整數型 數量_paths) {整數型 i;printf("%s:\n%s", 目錄類型, 數量_paths ? "" : " -\n");循環(i = 0; i < 數量_paths; i++)printf(" %s\n", paths[i]); }靜態 無類型 打印搜索目錄(知心狀態機 *s) {printf("安裝路徑: %s\n", s->zhi_庫_路徑);打印_目錄("文件導入路徑", s->系統包含_路徑, s->數量_系統包含_路徑);打印_目錄("動態庫路徑", s->庫_路徑, s->數量_庫_路徑); #如果已定義 ZHI_TARGET_PEprintf("hexinku1:\n %s/lib/"ZHI_HEXINKU1"\n", s->zhi_庫_路徑); #否則printf("hexinku1:\n %s/"ZHI_HEXINKU1"\n", s->zhi_庫_路徑);打印_目錄("crt", s->crt_路徑, s->數量_crt_路徑);printf("elfinterp:\n %s\n", 默認_ELF解釋程序路徑(s)); #結束如果 } 靜態 無類型 設置系統環境變量(知心狀態機 *s) {字符型 * path; /*該函數返回一個以 null 結尾的字符串,該字符串為被請求環境變量的值。如果該環境變量不存在,則返回 NULL。* 函數是一個用于獲取環境變量的函數,根據提供不同的參數可以獲取不同的環境變量*/path = getenv("C_INCLUDE_PATH");如果(path != NULL) {添加到系統包含路徑(s, path);}path = getenv("CPATH");如果(path != NULL) {添加包含路徑(s, path);}path = getenv("LIBRARY_PATH");如果(path != NULL) {添加庫路徑(s, path);} }靜態 字符型 *默認_輸出文件獲取擴展名(知心狀態機 *s, 常量 字符型 *源文件) {字符型 buf[1024];字符型 *擴展名;常量 字符型 *name = "a";如果 (源文件 && strcmp(源文件, "-"))name = 取_文件基本名(源文件);snprintf(buf, 取大小(buf), "%s", name);擴展名 = 取_文件擴展名(buf); #如果已定義 ZHI_TARGET_PE如果 (s->輸出_類型 == ZHI_輸出_DLL)strcpy(擴展名, ".dll");否則如果 (s->輸出_類型 == ZHI_輸出_EXE)strcpy(擴展名, ".exe");否則 #結束如果如果 (s->輸出_類型 == ZHI_輸出_目標文件 && !s->選項_可重定位目標文件 && *擴展名)strcpy(擴展名, ".o");否則strcpy(buf, "a.out");返回 字符串_寬度加1(buf); }靜態 無符號 獲取時鐘毫秒數(無類型) { #如果已定義 _WIN32返回 GetTickCount(); #否則結構體 timeval tv;gettimeofday(&tv, NULL);返回 tv.tv_sec*1000 + (tv.tv_usec+500)/1000; #結束如果 }整數型 主函數(整數型 參數數量, 字符型 **參數數組) {知心狀態機 *狀態機, *狀態機1; /*s1不能換成其他名稱,對其他文件有依賴*/整數型 返回值, 編譯指令, n = 0, 測試 = 0, 完成;無符號 開始_時間 = 0;常量 字符型 *源文件;整數型 參數數量0; 字符型 **參數數組0;FILE *打開的文件流 = stdout;/*FILE在stdio.h里的結構體;stdout,在stdio.h里的宏擴展,*/重復執行:參數數量0 = 參數數量, 參數數組0 = 參數數組;狀態機 = 狀態機1 = 初始化狀態機();編譯指令 = 解析命令行參數(狀態機, &參數數量0, &參數數組0, 1);/*****************************解析命令行參數結果處理,結束于:第79行*****************************/如果 (n == 0) {如果 (編譯指令 == 指令_HELP){fputs(幫助, stdout);如果 (!狀態機->顯示信息)返回 0;++編譯指令;}如果 (編譯指令 == 指令_ABOUT){fputs(關于, stdout);返回 0;}如果 (編譯指令 == 指令_M32 || 編譯指令 == 指令_M64)編譯器工具交叉(狀態機, 參數數組0, 編譯指令); /* 提示無法運行:“無法運行i386-win32-zhi.exe” */如果 (狀態機->顯示信息)printf(版本信息);如果 (編譯指令 == 指令_AR)返回 創建靜態庫文件(狀態機, 參數數量0, 參數數組0);#如果已定義 ZHI_TARGET_PE如果 (編譯指令 == 指令_IMPDEF)返回 創建定義文件(狀態機, 參數數量0, 參數數組0);#結束如果如果 (編譯指令 == 指令_V)返回 0;如果 (編譯指令 == 指令_打印_目錄){設置系統環境變量(狀態機);設置輸出類型(狀態機, ZHI_輸出_內存中運行);打印搜索目錄(狀態機);返回 0;}如果 (狀態機->數量_文件數 == 0)錯誤_打印("沒有輸入文件\n");如果 (狀態機->輸出_類型 == ZHI_輸出_預處理){如果 (狀態機->輸出文件 && 0!=strcmp("-",狀態機->輸出文件)){打開的文件流 = fopen(狀態機->輸出文件, "w");/*fopen()打開“狀態機->輸出文件”文件,進行寫操作。w:只允許寫;r:只允許讀;rb:只允許按照二進制讀;wb:只允許二進制寫*/如果 (!打開的文件流)錯誤_打印("無法寫 '%s'", 狀態機->輸出文件);}} 否則 如果 (狀態機->輸出_類型 == ZHI_輸出_目標文件 && !狀態機->選項_可重定位目標文件){如果 (狀態機->數量_庫數)錯誤_打印("無法使用-c指定庫");如果 (狀態機->數量_文件數 > 1 && 狀態機->輸出文件)錯誤_打印("無法使用-c指定輸出文件");}如果 (狀態機->顯示_編譯統計)開始_時間 = 獲取時鐘毫秒數();} /*****************************解析命令行參數結果處理,結束于:第29行*****************************/設置系統環境變量(狀態機);如果 (狀態機->輸出_類型 == 0)狀態機->輸出_類型 = ZHI_輸出_EXE;設置輸出類型(狀態機, 狀態機->輸出_類型);狀態機->預處理輸出文件 = 打開的文件流;如果 ((狀態機->輸出_類型 == ZHI_輸出_內存中運行|| 狀態機->輸出_類型 == ZHI_輸出_預處理)&& (狀態機->DX標號 & 16)){ /* -dt 選項 */如果 (測試)狀態機->DX標號 |= 32;狀態機->運行_測試 = ++測試;如果 (n)--n;}/* 編譯或添加每個文件或庫 */源文件 = NULL, 返回值 = 0;執行{文件名稱類型結構 *文件 = 狀態機->文件數[n];狀態機->文件類型 = 文件->類型;如果 (文件->類型 & 文件格式_類型_庫){如果 (添加庫錯誤(狀態機, 文件->名稱) < 0)返回值 = 1;} 否則{如果 (1 == 狀態機->顯示信息)printf("-> %s\n", 文件->名稱);如果 (!源文件)源文件 = 文件->名稱;如果 (添加文件(狀態機, 文件->名稱) < 0)//添加讀取文件流,開始編譯文件。返回值 = 1;}完成 = 返回值 || ++n >= 狀態機->數量_文件數;} 判斷 (!完成 && (狀態機->輸出_類型 != ZHI_輸出_目標文件 || 狀態機->選項_可重定位目標文件));如果(狀態機->運行_測試){測試 = 0;}否則 如果 (狀態機->輸出_類型 == ZHI_輸出_預處理){;}否則 如果 (0 == 返回值){如果 (狀態機->輸出_類型 == ZHI_輸出_內存中運行){#如果已定義 ZHI_是_本機返回值 = ZHI_運行(狀態機, 參數數量0, 參數數組0);//運行腳本執行的這句#結束如果}否則{如果 (!狀態機->輸出文件)狀態機->輸出文件 = 默認_輸出文件獲取擴展名(狀態機, 源文件);如果 (輸出可執行文件或庫文件或目標文件(狀態機, 狀態機->輸出文件))返回值 = 1;否則 如果 (狀態機->生成_依賴)生成_makedeps(狀態機, 狀態機->輸出文件, 狀態機->依賴_輸出文件);}}如果 (狀態機->顯示_編譯統計 && 完成 && !(測試 | 返回值))顯示編譯統計信息(狀態機, 獲取時鐘毫秒數() - 開始_時間);釋放狀態機(狀態機);如果 (!完成)去向 重復執行; /* 用-c編譯更多文件 */如果 (測試)去向 重復執行; /* 使用-dt -run運行更多測試 */如果 (打開的文件流 && 打開的文件流 != stdout)fclose(打開的文件流);返回 返回值; }總結
以上是生活随笔為你收集整理的TCC(TinyC)编译器汉化(中文编译器、汉语编程)之一:主文件汉化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北京数码视讯s905l固件_数码视讯Q6
- 下一篇: 在贵州大数据峰会上,马云再次语出惊人!