2013-03-23 50 views
1

我正在嘗試編寫一個flex文件,它將(-! comment !-)識別爲一個稱爲comment的令牌。以下是我的文件:flex中的排除規則

%{ 
#include <stdio.h> 

void showToken(char* name); 
void error(); 
void enter(); 

int lineNum=1; 
%} 

%option yylineno 
%option noyywrap 

whitespace ([\t ]) 
enter  ([\n]) 
startcomment (\(\-\!) 
endcomment (\!\-\)) 
comment (^\!\-\)) 

%% 

{startcomment}{comment}*{endcomment} showToken("COMMENT"); 
{enter} enter(); 
{whitespace} 
. error(); 

%% 

void showToken(char* name){ 
    printf("%d %s %s %d% \n",lineNum,name, yytext); 
} 

void enter(){ 
    lineNum++; 
} 

void error(){ 
printf("%d error %s \n",lineNum,yytext); 
} 

,但我失敗了簡單(-! comment !-)輸入,此文件不承認(-!!-),但沒有認識到我的comment規則。我嘗試用comment (^{endcomment})替換它,但它沒有工作,有什麼建議嗎?

回答

2

你似乎認爲^表示以下模式不應該匹配,但它意味着匹配行的開始。在角色類^內部確實意味着除了角色類以外的所有東西,但在角色類之外它的含義完全不同。

在回答你的問題替代。您的問題類似於C評論/* comment */。下面的表達式匹配C-評論:

"/*"([^*]|"*"+[^/*])*"*"+"/" 

或者,更直觀的(如果你喜歡)你可以使用一個子自動機:

%x comment 
%% 
"/*"    { BEGIN(comment); } 
<comment>(.|"\n") { /* Skip */ } 
<comment>"*/"  { BEGIN(INITIAL); } 
%% 

我會離開它作爲一個練習應用此以您的評論風格。將!-)作爲評論的結尾,使第一個解決方案更加複雜一些。

請注意,通常第二種解決方案是首選,因爲它不會導致使用大緩衝區。第一種解決方案將創建一個包含完整註釋(可能較大)的緩衝區,而第二個解決方案的緩衝區需求長度最多爲兩個字符。因爲flex將跟蹤變量int yylineno中的行號。或者,您可以計算yytext中的換行數。在第二種解決方案中,您可以拆分第二個規則併爲"\n"製作一個單獨的案例,並在那裏計算行號。

+0

謝謝你的迴應,現在我有兩個問題: 如果我使用第一種方法建議我無法增加行號「lineNum」(一些int我定義)時\ n在評論中是我需要做的事情。 如果我使用第二種方法,我無法使用yytext,並且由於我沒有綁定到註釋的長度,我不能使用緩衝區和指針。 – user44874 2013-03-25 16:57:47