2009-04-25 16:58

[LEX] 使用命令列參數開啟檔案

  1. /*[flex] 的指令參數 
  2. * ( flex -FLi8 %f ) 
  3. * -l 最大兼容性法則 
  4. * -i 不區分大小寫 
  5. * -f 產生不壓縮的完整表格,效率快,所需空間大 
  6. * -F 最佳效率與空間優化 
  7. * -L 在產生的程式碼中不加入 #line 
  8. * -7 使用 7 bit 掃瞄文字(預設) 
  9. * -8 使用 8 bit 掃瞄文字 
  10. * 
  11. * -+ 產生 C++ 掃瞄 Class 
  12. * 
  13. * -oOutputName 指定輸出檔案名稱 
  14. * 
  15. * -h 參數說明 
  16. * -V 版本顯示 
  17. * -T 顯示追蹤記錄 
  18. *  */ 
  19.  
  20.  
  21.    /* [定義段落] */ 
  22. %{ 
  23. #include <stdio.h> 
  24.  
  25. %} 
  26.  
  27.    /* 告知沒有自訂的 unput() */ 
  28. %option nounput 
  29.  
  30.    /* 初始狀態 */ 
  31. %s START 
  32.    /* 多行註解狀態 */ 
  33. %s COMMENTS 
  34.  
  35.    /* 換行符號 */ 
  36. EN [\r\n] 
  37.    /* 換行符號及空白字元 */ 
  38. SP [ \t\r\n]  // 
  39.    /* 單引號字串 */ 
  40. //STR1 (\'([^\'\r\n]|"\\\'")*\') 
  41.    /* 雙引號字串 */ 
  42. //STR2 (\"([^\"\r\n]|"\\\"")*\") 
  43.  
  44.  
  45. %%  /* [規則段落] */ 
  46.  
  47.    /* 多行註解模式 */ 
  48. <COMMENTS>"*/"{SP}*     { BEGIN START; } 
  49. <COMMENTS>.|{SP}        ; 
  50.  
  51.    /* 初始模式 */ 
  52. <START>"/*"             { BEGIN COMMENTS; } 
  53. <START>"//".*{EN}+      ; 
  54. <START>.                {fprintf(yyout,"%s",yytext);} 
  55.  
  56.  
  57. %%  /* [自訂函數段落] */ 
  58.  
  59. /* 程式執行方式與檔案參數 
  60. * 程式.exe 文件1.txt 文件2.txt 文件3.txt 
  61. * 或使用文件拖放至程式上 
  62. * */ 
  63. char **fileList; 
  64. unsigned currentFile = 0; 
  65. unsigned nFiles; 
  66.  
  67. int main(int argc,char **argv){ 
  68.    // 沒有檔案 
  69.    if(argc<2){ 
  70.        printf("沒有給予檔案參數");return 0; 
  71.  
  72.    }else{ 
  73.        // 取得檔案參數 
  74.        fileList = argv+1; 
  75.        nFiles = argc-1; 
  76.  
  77.        // 嘗試開啟第一個檔案 
  78.        yywrap(); 
  79.    } 
  80.  
  81.    // 執行文字解析器 
  82.    yylex(); 
  83.    /* 文字解析器會在檔案結束時 
  84.     * 自動呼叫 yywrap() 開啟下一個檔案 
  85.     * */ 
  86.  
  87.    return 0; 
  88. } 
  89.  
  90. /* 當沒自訂的 yywrap() 時 
  91. * 記得在前加上 "%option noyywrap" 
  92. * */ 
  93. int yywrap(){ 
  94.    // 關閉上次開啟的檔案 
  95.    if ((currentFile > 0) && (nFiles >= 1) && (currentFile <= nFiles)) { 
  96.        // 關閉輸入與輸出的文件 
  97.        fclose(yyin); fclose(yyout); 
  98.  
  99.        // 將暫存檔覆蓋原始輸入文件 
  100.        remove(fileList[currentFile-1]); 
  101.        rename("temp",fileList[currentFile-1]); 
  102.    } 
  103.  
  104.    FILE *fileIn = NULL; 
  105.    while ((currentFile < nFiles)) { 
  106.        // 檢查副檔名 
  107.        if(strstr(fileList[currentFile],".txt")!= NULL){ 
  108.            // 設定初始狀態 
  109.            BEGIN START; 
  110.        }else{ 
  111.            // 跳過不符合的檔案 
  112.            continue; 
  113.        } 
  114.  
  115.  
  116.        // 嘗試開啟檔案 
  117.        fileIn = fopen(fileList[currentFile++], "r"); 
  118.        if (fileIn != NULL) { 
  119.            // 指定輸入與輸出的文件指標 
  120.            yyin = fileIn; 
  121.            yyout = fopen("temp","w"); 
  122.  
  123.            // 成功開啟檔案跳出迴圈 
  124.            break; 
  125.        } 
  126.        printf("無法開啟檔案: %s\n",fileList[currentFile-1]); 
  127.    } 
  128.    // 回傳狀態 ( 0:成功開啟 , 1:開啟失敗 ) 
  129.    return (fileIn ? 0 : 1); 
  130. } 

相關連結:Yacc 与 Lex 快速入门

3 回應:

Wei 提到...

請問為什麼我在flex的時候
48 49 行為什麼都會出現
unrecognized rule

Jax Hu 提到...

抱歉!我很久沒寫 Lex 了,但這段程式是可以編譯的,不知道你用的 fLex 是哪一個版本,你可以試試在 Ubuntu Linux 上的 fLex。

wei 提到...

我是在使用windows上使用flex 2.5.4a
不過 謝謝 我解決了
EN [\r\n]
SP [ \t\r\n]
好像無效..我把規則段落的EN跟SP直接給[\r\n]
就正常了 謝謝