我正在尝试编写一个flex文件,该文件将(-! comment !-)
识别为一个名为comment
的标记。以下是我的档案:
%{
#include <stdio.h>
void showToken(char* name);
void error();
void enter();
int lineNum=1;
%}
%option yylineno
%option noyywrap
whitespace ([\t ])
enter ([\n])
startcomment (\(\-\!)
endcomment (\!\-\))
comment (^\!\-\))
%%
{startcomment}{comment}*{endcomment} showToken("COMMENT");
{enter} enter();
{whitespace}
. error();
%%
void showToken(char* name){
printf("%d %s %s %d% \n",lineNum,name, yytext);
}
void enter(){
lineNum++;
}
void error(){
printf("%d error %s \n",lineNum,yytext);
}
但我输入简单(-! comment !-)
时失败,此文件确实识别(-!
和!-)
,但无法识别我的comment
规则。我确实尝试用comment (^{endcomment})
替换它,但它没有用,有什么建议吗?
答案 0 :(得分:2)
您似乎认为^
表示以下模式不匹配,但它表示匹配行的开头。在角色类^
内部确实意味着除了角色类之外的所有东西,但在角色类之外它的含义完全不同。
回答你的问题以寻找替代方案。您的问题类似于C-comment /* comment */
。以下表达式与C-comment匹配:
"/*"([^*]|"*"+[^/*])*"*"+"/"
或者更直观(如果您愿意),您可以使用子自动机:
%x comment
%%
"/*" { BEGIN(comment); }
<comment>(.|"\n") { /* Skip */ }
<comment>"*/" { BEGIN(INITIAL); }
%%
我会将其作为练习将其应用于您的评论风格。将!-)
作为评论的结束,使第一个解决方案变得更复杂。
请注意,通常第二种解决方案是首选,因为它不会导致使用大缓冲区。第一个解决方案将创建一个包含完整注释的缓冲区(可能很大),而第二个解决方案的缓冲区要求最多为两个字符。
维护行号的最简单方法是使用%option yylineno
作为flex
,然后跟踪变量int yylineno
中的行号。或者,您可以计算yytext
中新行的数量。在第二个解决方案中,您可以拆分第二个规则,为"\n"
创建一个单独的案例,并在那里计算行号。