2009-04-25

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


/*[flex] 的指令參數
* ( flex -FLi8 %f )
* -l 最大兼容性法則
* -i 不區分大小寫
* -f 產生不壓縮的完整表格,效率快,所需空間大
* -F 最佳效率與空間優化
* -L 在產生的程式碼中不加入 #line
* -7 使用 7 bit 掃瞄文字(預設)
* -8 使用 8 bit 掃瞄文字
*
* -+ 產生 C++ 掃瞄 Class
*
* -oOutputName 指定輸出檔案名稱
*
* -h 參數說明
* -V 版本顯示
* -T 顯示追蹤記錄
* */


/* [定義段落] */
%{
#include <stdio.h>

%}

/* 告知沒有自訂的 unput() */
%option nounput

/* 初始狀態 */
%s START
/* 多行註解狀態 */
%s COMMENTS

/* 換行符號 */
EN [\r\n]
/* 換行符號及空白字元 */
SP [ \t\r\n] //
/* 單引號字串 */
//STR1 (\'([^\'\r\n]|"\\\'")*\')
/* 雙引號字串 */
//STR2 (\"([^\"\r\n]|"\\\"")*\")


%% /* [規則段落] */

/* 多行註解模式 */
<COMMENTS>"*/"{SP}* { BEGIN START; }
<COMMENTS>.|{SP} ;

/* 初始模式 */
<START>"/*" { BEGIN COMMENTS; }
<START>"//".*{EN}+ ;
<START>. {fprintf(yyout,"%s",yytext);}


%% /* [自訂函數段落] */

/* 程式執行方式與檔案參數
* 程式.exe 文件1.txt 文件2.txt 文件3.txt
* 或使用文件拖放至程式上
* */
char **fileList;
unsigned currentFile = 0;
unsigned nFiles;

int main(int argc,char **argv){
// 沒有檔案
if(argc<2){
printf("沒有給予檔案參數");return 0;

}else{
// 取得檔案參數
fileList = argv+1;
nFiles = argc-1;

// 嘗試開啟第一個檔案
yywrap();
}

// 執行文字解析器
yylex();
/* 文字解析器會在檔案結束時
* 自動呼叫 yywrap() 開啟下一個檔案
* */

return 0;
}

/* 當沒自訂的 yywrap() 時
* 記得在前加上 "%option noyywrap"
* */
int yywrap(){
// 關閉上次開啟的檔案
if ((currentFile > 0) && (nFiles >= 1) && (currentFile <= nFiles)) {
// 關閉輸入與輸出的文件
fclose(yyin); fclose(yyout);

// 將暫存檔覆蓋原始輸入文件
remove(fileList[currentFile-1]);
rename("temp",fileList[currentFile-1]);
}

FILE *fileIn = NULL;
while ((currentFile < nFiles)) {
// 檢查副檔名
if(strstr(fileList[currentFile],".txt")!= NULL){
// 設定初始狀態
BEGIN START;
}else{
// 跳過不符合的檔案
continue;
}


// 嘗試開啟檔案
fileIn = fopen(fileList[currentFile++], "r");
if (fileIn != NULL) {
// 指定輸入與輸出的文件指標
yyin = fileIn;
yyout = fopen("temp","w");

// 成功開啟檔案跳出迴圈
break;
}
printf("無法開啟檔案: %s\n",fileList[currentFile-1]);
}
// 回傳狀態 ( 0:成功開啟 , 1:開啟失敗 )
return (fileIn ? 0 : 1);
}


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

3 回應:

Wei 提到...

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

胡忠晞 提到...

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

wei 提到...

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