5

我应该如何在 lex(或 flex)中编写程序以从文本中删除嵌套注释并仅打印不在注释中的文本?当我在评论和块评论的起始“标签”数量时,我可能应该以某种方式识别状态。

让我们有规则:
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
4

3 回答 3

7

你的理论是对的。这是一个简单的实现;可以改进。

%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;  
%%
于 2012-10-18T07:34:45.547 回答
2

这正是您所需要的:yy_push_state(COMMENT)它使用堆栈来存储我们的状态,这在嵌套情况下很方便。

于 2013-03-09T16:59:56.077 回答
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;}

为了使其更健壮,您还需要有另一个密切检查规则

在实践中,如果您的词法分析器支持,您应该在正则表达式语法之前使用否定查找并在正则表达式语法之后查找。

于 2016-10-06T05:41:34.277 回答