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) 和_
"
'
.
我有以下代码:
%{
#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) 和_
"
'
.