Flex:用于删除 Haskell 中的多注释行的词法分析器

Flex: lexical analyzer to remove multicomment line in Haskell

我有以下代码:

%{
    #include<stdio.h>
%}

%x multicomment

%option noyywrap
%% 

--(.*) ; 
  
"{-"      BEGIN(multicomment);
<multicomment>[^*\n]+    
<multicomment>"*"        
<multicomment>\n         
<multicomment>"-}"    BEGIN(INITIAL);
%% 
  
int main(int argc,char **argv) 
{ 
    yyin=fopen("Code.txt","r"); 
    yyout=fopen("out.c","w");

    yylex(); 
    return 0; 
} 

成就的任务非常简单...从 haskell 代码中删除 single/multiline 注释。

-- 单行; {- -} 表示多行;

如果我使用 "/*"" & "*/" (对于 C 注释)而不是 "{-" & "-}"。当我使用最后两个时,我不知道为什么flex会删除{-.

之后的所有其他字符

例如,假设要清理以下输入文本:

some text

{- some other text
    in multiline
    with haskel comment
-}

/* another text
    always in multiline
    but with C comment
*/

some text without comment

如果上面的代码设置如下:

    "/*"      BEGIN(multicomment);
    <multicomment>[^*\n]+    
    <multicomment>"*"        
    <multicomment>\n         
    <multicomment>"*/"    BEGIN(INITIAL);

with /*" & "*/" 输出是正确的:

some text

{- some other text
    in multiline
    with haskel comment initiator
-}

some text without comment

如果我使用原始代码,而不是

    "{-"      BEGIN(multicomment);
    <multicomment>[^*\n]+    
    <multicomment>"*"        
    <multicomment>\n         
    <multicomment>"-}"    BEGIN(INITIAL);

with "{-" & "-}",它不起作用,输出是:

some text

它会删除 "{-" 直到文件末尾的所有字符,我还尝试了其他论坛推荐的其他设置:

<multicomment>"-\}"    BEGIN(INITIAL);
<multicomment>"-"+"}"    BEGIN(INITIAL);
<multicomment>"-" + "}"    BEGIN(INITIAL);
<multicomment>[-}]    BEGIN(INITIAL);

但在这些情况下,当我尝试使用 flex CommentClean.l 进行编译时,结果如下:

CommentClean.l:16: warning, rule cannot be matched

有人可以帮助我吗?我哪里错了?我该怎么办?

您只更改了开始和结束分隔符,但没有更改规则以匹配内容

原规则说“在multicomment状态下,忽略一个或多个non-asterisks和换行符;忽略一个星号;并忽略换行符”。 longest-match 规则将星号后跟斜线匹配为结束定界符。

    <multicomment>[^*\n]+    
    <multicomment>"*"        
    <multicomment>\n 

当您仅更改定界符时代码中发生的情况是 {- 将开始注释,然后结束定界符 -} 将作为内容的一部分使用,“a non-asterisk/newline 字符系列”,这将获胜,因为它匹配(多!)更长的字符串。

我认为您只需要将星号更改为连字符即可:

    <multicomment>[^-\n]+    
    <multicomment>"-"        
    <multicomment>\n 

但是,请注意,这并没有说明在 Haskell 中,与在 C 中不同,multi-line 注释可能 嵌套 这样的事实:

{-

a multi-line comment

  {-
    containing another comment

    {- containing yet another comment -}

  -}

-}

所以为了严格正确,您还应该包括一个递归匹配 multi-line 评论的规则。还请记住,如果 -- 不是运算符的一部分,它只是一个 single-line 注释,因此例如 -->|-- 是有效的运算符,而不是注释的开头. (是的,人们在实际代码中使用这些!)

您可以在 Haskell Report §2.3 中找到注释规范。它说一个符号是:

  • 这些字符中的任何一个 (ascSymbol): ! # $ % & + . / < = > ? @ \ ^ | - ~ :;或

  • 任何具有符号 (S) 或标点符号 (P) 属性的 Unicode 字符 (uniSymbol),除了 ( ) , ; [ ] ` { } (special) 和_ " '.