使用Flex检测和跳过行注释

ado*_*srs 3 c compiler-construction flex-lexer

如何在Flex中检测到一行注释如"//"并跳过此行?

并且:

如果使用下面的"/*"注释即可.它会起作用吗?

   "/*"         { comment(); }
  %%

    comment()
    {
        char c, c1;
    loop:
        while ((c = input()) != '*' && c != 0)
            putchar(c);

        if ((c1 = input()) != '/' && c != 0)
        {
            unput(c1);
            goto loop;
        }

        if (c != 0)
            putchar(c1);
    }
Run Code Online (Sandbox Code Playgroud)

ric*_*ici 17

为什么不使用正则表达式来识别注释?重点lex/flex是避免手动编写词法扫描仪.您提供的代码应该可以工作(如果您将模式/*放在行的开头),但它有点难看,并且它不起作用是不明显的.

您的问题是您要跳过评论,但您提供的代码putchar()用于打印评论,但/*开头除外.你想做什么?如果要回显注释,可以使用ECHO操作而不是什么都不做.

以下是正则表达式:

单行评论

这个很容易,因为在lex/flex中,.不会匹配换行符.所以以下内容将匹配//到行尾,然后什么都不做.

"//".*                                    { /* DO NOTHING */ }
Run Code Online (Sandbox Code Playgroud)

多行评论

这有点棘手,而且*正则表达式字符以及注释标记的关键部分这一事实使得以下正则表达式有点难以阅读.我[*]用作识别角色的图案*; 在flex/lex中,您可以使用"*".使用您认为更具可读性的任何一个.本质上,正则表达式匹配以(字符串)结尾的字符序列,*直到找到下一个字符为a的字符串/.换句话说,它具有与C代码相同的逻辑.

[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/]       { /* DO NOTHING */ }
Run Code Online (Sandbox Code Playgroud)

以上要求终止*/; 未终止的注释将强制词法分析器返回到注释的开头并接受一些其他令牌,通常是/除法运算符.这可能不是你想要的,但是从未经评论的评论中恢复并不容易,因为没有真正好的方法可以知道评论应该在哪里结束.因此,我建议添加错误规则:

[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/]       { /* DO NOTHING */ }
[/][*]                                    { fatal_error("Unterminated comment"); }
Run Code Online (Sandbox Code Playgroud)