如何在lex中打印评论?

时间:2015-05-04 15:17:12

标签: comments lex lexical-analysis

因此标题可能会有点误导,但我无法想出更好的方法来表达它。

基本上,我正在使用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 没有任何字符串有关,或者我使用错误的状态。

希望有人能够帮助我:)

此外,如果您需要任何其他信息,请询问,我会提供。

1 个答案:

答案 0 :(得分:2)

  1. 回显模式扫描的令牌的最简单方法是使用特殊操作ECHO

    "/*"            { printf("%d: ", linenum++); ECHO; BEGIN(C_COMMENT); }
    <C_COMMENT>"*/" { ECHO; BEGIN(INITIAL); }
    <C_COMMENT>.    { ECHO; }
    
  2. 以上规则均不符合评论中的换行符,因为在(f)中lex .与新换行符不匹配:

    <C_COMMENT>\n   { linenum++; ECHO; }
    
  3. 识别C注释的一种更快捷的方法是使用单个正则表达式,尽管它有点难以理解:

    [/][*][^*]*[*]+([^/*][^*][*]+)*[/]
    

    在这种情况下,您必须重新扫描评论以计算换行符,除非您灵活地进行行号计数。

  4. 如果您请求该功能(使用yylineno),则flex扫描程序会在%option yylineno中保留行号。它通常比自己保持计数更有效率,更可靠。但是,在操作中,yylineno的值是模式末尾的行号计数,而不是开头的行号,这可能会误导多行模式。常见的解决方法是在令牌扫描开始时将yylineno的值保存在另一个变量中。