【问题标题】:Removing nested comments bz lex删除嵌套注释 bz lex
【发布时间】:2012-10-08 05:41:16
【问题描述】:
我应该如何在 lex(或 flex)中编写程序以从文本中删除嵌套的 cmets 并仅打印不在 cmets 中的文本?
当我在评论和块评论的起始“标签”数量时,我可能应该以某种方式识别状态。
让我们有规则:
1.阻止评论
/*
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
【问题讨论】:
标签:
comments
lex
flex-lexer
lexical-analysis
【解决方案1】:
你的理论是对的。这是一个简单的实现;可以改进。
%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) 它使用堆栈来存储我们的状态,这在嵌套情况下很方便。
【解决方案3】:
恐怕@rici 的回答可能是错误的。首先我们需要记录行号,以后可能会更改文件 line 指令。第二个给出 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;}
为了使其更健壮,您还需要在
之外设置另一个密切检查规则
在实践中,如果您的词法分析器支持,您应该在正则表达式语法之前使用否定查找并在正则表达式语法之后查找。