【问题标题】:How to print comments in lex?如何在 lex 中打印注释?
【发布时间】:2015-05-04 15:17:11
【问题描述】:

所以标题可能有点误导,但我想不出更好的表达方式。

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

希望有人能帮助我:)

另外,如果您需要任何其他信息,请提出,我会提供。

【问题讨论】:

    标签: comments lex lexical-analysis


    【解决方案1】:
    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 cmets 的一种更快的方法是使用单个正则表达式,尽管它有点难以阅读:

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

      在这种情况下,您必须重新扫描注释以计算换行符,除非您使用 flex 来计算行号。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-26
      • 1970-01-01
      • 2020-12-06
      • 1970-01-01
      • 2012-10-08
      • 2018-10-07
      • 2023-03-07
      相关资源
      最近更新 更多