2012-10-17 90 views
5

我應該如何在lex(或flex)中執行程序以從文本中移除嵌套註釋並僅打印不在註釋中的文本? 我應該可能以某種方式識別當我在註釋中的狀態以及塊註釋的開始「標籤」的數量。刪除嵌套註釋bz lex

讓有規則:
1.block評論

/* 
block comment 
*/ 

2.行註釋

// line comment 

3.註釋可以嵌套。

實施例1

show /* comment /* comment */ comment */ show 

輸出:

show show 

實施例2

show /* // comment 
comment 
*/ 
show 

輸出:

show 
show 

例3

show 
///* comment 
comment 
// /* 
comment 
//*/ comment 
// 
comment */ 
show 

輸出:

show 
show 

回答

5

你得到的理論正確的。這是一個簡單的實現;可以改進。

%x COMMENT 
%% 
%{ 
    int comment_nesting = 0; 
%} 

"/*"   BEGIN(COMMENT); ++comment_nesting; 
"//".*   /* // comments to end of line */ 

<COMMENT>[^*/]* /* Eat non-comment delimiters */ 
<COMMENT>"/*" ++comment_nesting; 
<COMMENT>"*/" if (--comment_nesting == 0) BEGIN(INITIAL); 
<COMMENT>[*/] /* Eat a/or * if it doesn't match comment sequence */ 

    /* Could have been .|\n ECHO, but this is more efficient. */ 
([^/]*([/][^/*])*)* ECHO; 
%% 
2

這正是你所需要的:yy_push_state(COMMENT)其使用堆棧來存儲我們的國家,其嵌套的情況來得心應手。

0

恐怕@rici的回答可能是錯誤的。首先,我們需要記錄線路號碼,稍後可能會更改線路指令。第二次給open_sign和close_sign。我們有以下原則:

1) using an integer for stack control: push for open sign, popup for close sign 
2) eat up CHARACTER BEFORE EOF and close sign WITHOUT open sign inside 
<comments>{open} {no_open_sign++;} 
<comments>\n {curr_lineno++;} 
<comments>[^({close})({open})(EOF)] /*EAT characters by doing nothing*/ 
3) Errors might happen when no_open_sign down to zero, hence 
<comments>{close} similar as above post 
4) EOF should not be inside the string, hence you need a rule 
<comments>(EOF) {return ERROR_TOKEN;} 

,以使其更加堅固,你還需要有另一接近檢查排除

而且在實踐中邊之前,您應該使用負的外觀和向後看的正則表達式文法如果你的詞法分析器支持它。