因此标题可能会有点误导,但我无法想出更好的方法来表达它。
基本上,我正在使用cygwin / lex编写词法扫描程序。代码的一部分读取令牌/ *。它进入预定义的状态C_COMMENT,并在C_COMMENT" / *"时结束。以下是实际代码
"/*" {BEGIN(C_COMMENT); printf("%d: /*", linenum++);}
<C_COMMENT>"*/" { BEGIN(INITIAL); printf("*/\n"); }
<C_COMMENT>. {printf("%s",yytext);}
当评论在一行中时,代码可以工作,例如
/* * Example of comment */
它将打印当前行号,后面有注释。但如果评论跨越多行,它就无法发挥作用。将第3行重写为
<C_COMMENT>. {printf("%s",yytext);
printf("\n");}
不起作用。这将导致为评论中的每个字母打印\ n。我猜这与 C 没有任何字符串有关,或者我使用错误的状态。
希望有人能够帮助我:)
此外,如果您需要任何其他信息,请询问,我会提供。
答案 0 :(得分:2)
回显模式扫描的令牌的最简单方法是使用特殊操作ECHO
:
"/*" { printf("%d: ", linenum++); ECHO; BEGIN(C_COMMENT); }
<C_COMMENT>"*/" { ECHO; BEGIN(INITIAL); }
<C_COMMENT>. { ECHO; }
以上规则均不符合评论中的换行符,因为在(f)中lex .
与新换行符不匹配:
<C_COMMENT>\n { linenum++; ECHO; }
识别C注释的一种更快捷的方法是使用单个正则表达式,尽管它有点难以理解:
[/][*][^*]*[*]+([^/*][^*][*]+)*[/]
在这种情况下,您必须重新扫描评论以计算换行符,除非您灵活地进行行号计数。
如果您请求该功能(使用yylineno
),则flex扫描程序会在%option yylineno
中保留行号。它通常比自己保持计数更有效率,更可靠。但是,在操作中,yylineno
的值是模式末尾的行号计数,而不是开头的行号,这可能会误导多行模式。常见的解决方法是在令牌扫描开始时将yylineno
的值保存在另一个变量中。