2013-03-23 52 views
1

我正在尝试编写一个flex文件,它将(-! comment !-)识别为一个称为comment的令牌。以下是我的文件:flex中的排除规则

%{ 
#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})替换它,但它没有工作,有什么建议吗?

回答

2

你似乎认为^表示以下模式不应该匹配,但它意味着匹配行的开始。在角色类^内部确实意味着除了角色类以外的所有东西,但在角色类之外它的含义完全不同。

在回答你的问题替代。您的问题类似于C评论/* comment */。下面的表达式匹配C-评论:

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

或者,更直观的(如果你喜欢)你可以使用一个子自动机:

%x comment 
%% 
"/*"    { BEGIN(comment); } 
<comment>(.|"\n") { /* Skip */ } 
<comment>"*/"  { BEGIN(INITIAL); } 
%% 

我会离开它作为一个练习应用此以您的评论风格。将!-)作为评论的结尾,使第一个解决方案更加复杂一些。

请注意,通常第二种解决方案是首选,因为它不会导致使用大缓冲区。第一种解决方案将创建一个包含完整注释(可能较大)的缓冲区,而第二个解决方案的缓冲区需求长度最多为两个字符。因为flex将跟踪变量int yylineno中的行号。或者,您可以计算yytext中的换行数。在第二种解决方案中,您可以拆分第二个规则并为"\n"制作一个单独的案例,并在那里计算行号。

+0

谢谢你的回应,现在我有两个问题: 如果我使用第一种方法建议我无法增加行号“lineNum”(一些int我定义)时\ n在评论中是我需要做的事情。 如果我使用第二种方法,我无法使用yytext,并且由于我没有绑定到注释的长度,我不能使用缓冲区和指针。 – user44874 2013-03-25 16:57:47