用lex處理C語言的註釋

最近在實踐中遇到一個需求:需要把一個C語言代碼文件中的註釋中的非空白字符全部替換爲空格(目的是讓新文件的長度和原來的一樣)..用flex鼓搗了兩個小時,得到了下面的代碼

%{	
#include<iostream>
#include<sstream>
#include<fstream>
#include <iterator>
#include <vector>
#include <algorithm>

using namespace std;
ostringstream oss;
void replace();

%}

%start LINE_COMMENT BLOCK_COMMENT STRING
 
%%

%{
// 處理字符串常量,lex的註釋必須寫在%{和%}之內!!
%}
<INITIAL>\"	{ cout << yytext; BEGIN STRING;}
<STRING>[^\\]\"	{ cout << yytext; BEGIN 0; }
<STRING>.	{ cout << yytext;}


<INITIAL>"//"  {cout << " ";BEGIN LINE_COMMENT;}
<LINE_COMMENT>"\n" {cout << endl; BEGIN 0; }
<LINE_COMMENT>"\r" {cout << yytext; }
<LINE_COMMENT>. {	replace();	}

<INITIAL>"/*"  {cout << " ";BEGIN BLOCK_COMMENT;}
<BLOCK_COMMENT>"*/"  {cout << " ";BEGIN 0;}
<BLOCK_COMMENT>[\r\n] {cout<<yytext; }
<BLOCK_COMMENT>. {	replace();	}

<INITIAL>[\r\n] {cout<<yytext; }
<INITIAL>. {cout<<yytext; }


%%

//將註釋裏的非空字符替換爲空格輸出
void replace(){
	unsigned char c = yytext[0];
	if (!isspace(c))
		c =' ';
    cout << c;
}
 
int yywrap(void)
{  
	return 1;  
}

int main(int argc, char* argv[])
{
	bool write_back_to_file = false;
	string filename;
    --argc;
    ++argv;
    if(argc > 0){
		write_back_to_file = true;
		filename = argv[0];  
        yyin = fopen(argv[0],"r");  
		cout.rdbuf(oss.rdbuf());  //輸出重定向到字符串流裏,以便複製到文件中
	}
    else{
        yyin = stdin;
	}
    
    yylex();
	
	if (write_back_to_file){
		//把輸出寫回文件
		if(yyin != NULL)
			fclose(yyin);
		
		//把字符串流的內容拷貝到文件中
		ofstream ofs(argv[0]);	
		const string & str = oss.str();
		copy(str.begin(),str.end(),ostream_iterator<char>(ofs));//從字符串流讀取數據寫入輸出流
	}

    return 0;
}

然後在vs2017中編譯通過,

測試文件內容爲:

//行註釋測試
int main(){
	const char* p ="//字符串裏的註釋" ;
	/*
	塊註釋
	*/
	return  0;
}

運行後文件的新內容爲

           
int main(){
	const char* p ="//字符串裏的註釋" ;
	 
	      
	 
	return  0;
}

運行成功.

 

linux下的實驗過程爲:

sudo apt-get install flex  #安裝flex包
sudo apt-get install bison #按照bison
flex demo.l      #編譯剛纔寫的demo.l文件,會自動生成一個lex.yy.c文件
g++ -Wall -Wextra -o remove_comment lex.yy.c # 編譯之
./remove_comment test1.c    #消除test1.c中的所有註釋

 

vs中如何使用flex 可以見這篇文章:

vs2017下使用flex+bison

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章