我想在 flex 中制定一个规则来使用像 /* */ 这样的 c 样式注释
我有以下
c_comment "/*"[\n.]*"*/"
但它永远不会匹配。知道为什么吗?如果您需要更多我的代码,请告诉我,我将提交整个内容。感谢任何回复的人。
我想在 flex 中制定一个规则来使用像 /* */ 这样的 c 样式注释
我有以下
c_comment "/*"[\n.]*"*/"
但它永远不会匹配。知道为什么吗?如果您需要更多我的代码,请告诉我,我将提交整个内容。感谢任何回复的人。
我建议您改用开始条件。
%x C_COMMENT
"/*" { BEGIN(C_COMMENT); }
<C_COMMENT>"*/" { BEGIN(INITIAL); }
<C_COMMENT>\n { }
<C_COMMENT>. { }
请注意,规则和规则之间不能有任何空格。<condition>
%x C_COMMENT
定义 C_COMMENT 状态,并且规则/*
启动它。一旦它开始,*/
它会回到初始状态(INITIAL
预定义),并且所有其他字符都将被消耗而无需任何特定操作。当两条规则匹配时,Flex 会通过匹配最长的一条来消除歧义,因此点规则不会阻止*/
匹配。该\n
规则是必要的,因为点匹配除换行符之外的所有内容。
该%x
定义使 C_COMMENT 成为排他状态,这意味着词法分析器将仅匹配<C_COMMENT>
进入状态后“标记”的规则。
这是一个小例子词法分析器,它通过打印除里面的所有内容来实现这个答案/* comments */
。
这是一个示例,以防万一有人对如何使用 zneak 的答案感到困惑:
(基本上,您将“%x C_COMMENT”放在第一部分,其余部分放在第二部分,正如他的有用链接所解释的那样)
foo.l
%{
// c code..
%}
%x C_COMMENT
%%
"/*" { BEGIN(C_COMMENT); }
<C_COMMENT>"*/" { BEGIN(INITIAL); }
<C_COMMENT>. { }
%%
// c code..
希望对某人有所帮助!蒂夫
不知道为什么它没有被选中,但我知道这种模式可以产生大量的词汇元素。仅检测开始注释标记并将所有内容都扔到 bitbucket 中直到找到结束标记会更有效。
这个网站有代码可以做到这一点:
"/*" {
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;
}
}
}
我相信这个解决方案更简单:
"/*"((\*+[^/*])|([^*]))*\**"*/"
我已经尝试了几个建议的解决方案,结果如下。
paxdiablo 的答案很有效,并且具有易于阅读的优点。我进一步修改如下:
"/*" { int c1 = 0, c2 = input(); 为了(;;) { 如果(c2 == EOF)中断; 如果(c1 == '*' && c2 == '/') 休息; c1 = c2; c2 = 输入(); } }
Flex 手册中有一个工作示例,它可以正确处理粗糙的边缘情况:
<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++;
另一个例子:
"/*"([^*]*|(\*+[^/]))*"*/"
忽略空格和换行符
"/*"
(
"/"*
(
"*"*
[^*/]
"/"*
)*
"*"*
)*
"*/"
Kenneth C. Louden - Compiler Construction_Principles and Practice (1997) 第 2.2.3 节