我想在flex中制定规则来使用像/ * * /
这样的c风格的注释我有以下
c_comment "/*"[\n.]*"*/"
但它永远不会匹配。知道为什么吗?如果您需要更多我的代码请告诉我,我会提交整件事。感谢任何回复的人。
答案 0 :(得分:41)
我建议你改用start conditions。
%x C_COMMENT
"/*" { BEGIN(C_COMMENT); }
<C_COMMENT>"*/" { BEGIN(INITIAL); }
<C_COMMENT>\n { }
<C_COMMENT>. { }
请注意必须是<condition>
和规则之间的任何空格。
%x C_COMMENT
定义了C_COMMENT状态,规则/*
启动了它。一旦启动,*/
将使其返回到初始状态(INITIAL
已预定义),并且所有其他角色将在没有任何特定操作的情况下被消费。当两个规则匹配时,Flex会通过选择具有最长匹配的规则来消除歧义,因此点规则不会阻止*/
匹配。 \n
规则是必要的,因为a dot matches everything except a newline。
%x
定义使C_COMMENT成为独占状态,这意味着词法分析器只会匹配一旦进入状态后被“标记”<C_COMMENT>
的规则。
这是一个tiny example lexer,通过打印/* comments */
内的所有内容来实现此答案。
答案 1 :(得分:9)
以下是一个例子,以防万一有人对如何处理zneak的答案感到困惑:
(基本上,你将“%x C_COMMENT”放在第一部分,其余部分放在第二部分,正如他的有用链接所解释的那样)
foo.l
%{
// c code..
%}
%x C_COMMENT
%%
"/*" { BEGIN(C_COMMENT); }
<C_COMMENT>"*/" { BEGIN(INITIAL); }
<C_COMMENT>. { }
%%
// c code..
希望有人帮助! TIFF
答案 2 :(得分:7)
不确定为什么它没有被拾取但是我知道那种模式可以产生大的词汇元素。在找到结束标记之前,只检测开始注释标记并将所有内容丢弃在bitbucket中会更有效。
This site有代码可以执行此操作:
"/*" {
for (;;) {
while ((c = input()) != '*' && c != EOF)
; /* eat up text of comment */
if (c == '*') {
while ((c = input()) == '*')
;
if (c == '/')
break; /* found the end */
}
if (c == EOF) {
error ("EOF in comment");
break;
}
}
}
答案 3 :(得分:2)
我相信这个解决方案更简单:
"/*"((\*+[^/*])|([^*]))*\**"*/"
答案 4 :(得分:1)
在the Flex manual中有一个有效的例子,它可以获得正确的边缘案例:
<INITIAL>"/*" BEGIN(IN_COMMENT);
<IN_COMMENT>"*/" BEGIN(INITIAL);
<IN_COMMENT>[^*\n]+ // eat comment in chunks
<IN_COMMENT>"*" // eat the lone star
<IN_COMMENT>\n yylineno++;
答案 5 :(得分:0)
答案 6 :(得分:0)
我已经尝试了几种建议的解决方案,结果如下。
paxdiablo的答案奏效,并且具有易于阅读的优点。我进一步修改如下:
"/*" { int c1 = 0, c2 = input(); for(;;) { if(c2 == EOF) break; if(c1 == '*' && c2 == '/') break; c1 = c2; c2 = input(); } }
答案 7 :(得分:0)
另一个例子:
"/*"([^*]*|(\*+[^/]))*"*/"
答案 8 :(得分:-2)
"/*"(.|\n)"*/"
将您的正则表达式更改为此,它肯定会有效。