Flex不在多行注释上正确计算行数

时间:2014-08-21 00:15:30

标签: c compiler-construction flex-lexer

我使用上面的正则表达式来识别Flex中的多行注释:

[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/]       { /* DO NOTHING */ }

但在我看来,flex / bison没有正确地返回行计数器。 例如:

输入:

1  ___bqmu7ftc
2 // _qXnFEgQL9Zsyn8Ohtx7zhToLK68xbu3XRrOvRi 
3 /* "{ output 6 = <=W if u7 do nN)T!=$||JN,a9vR)7" 
4  -758939 
5 -31943.6165480 
6 // "RND" 
7  '_' 
8 */
9 [br _int]

输出:

1 TK_IDENT [___bqmu7ftc]
4 [
4 TK_IDENT [br]
4 TK_IDENT [_int]
4 ]

该行应为9而不是4。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

我不知道您在问题中如何生成测试输出,但这是一个(几乎)如何使用yylineno的最小示例。它适用于我:

%{
  #define ID 257
%}

%option yylineno
%option noinput nounput noyywrap

%%

[[:space:]]+                            { /* DO NOTHING */ }
"//".*                                  { /* DO NOTHING */ }
[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/]     { /* DO NOTHING */ }
[[:alpha:]_][[:alnum:]_]*               { return ID; }
.                                       { return *yytext; }

%%

int main(int argc, char** argv) {
  for (;;) {
    int token = yylex();
    switch (token) {
      case 0:   printf("%4d: %s\n",       yylineno, "EOF"); return 0;
      case ID:  printf("%4d: %-4s[%s]\n", yylineno, "ID", yytext); break;
      default:  printf("%4d: %c\n",       yylineno, token); break;
    }
  }
}

答案 1 :(得分:1)

这是我在Flex manual

上找到的解决方案

请记住在定义范围内声明int comment_caller;

%x comment 
%x foo
%%

"/*" {comment_caller = INITIAL;
    BEGIN(comment);
      }

     <foo>"/*"  {
      comment_caller = foo;
      BEGIN(comment);
      }

     <comment>[^*\n]*    {}
     <comment>"*"+[^*/\n]*   {}
     <comment>\n       {++line_num;}
     <comment>"*"+"/"    BEGIN(comment_caller);

答案 2 :(得分:0)

我在使用flex多行注释时遇到了同样的问题。我使用了this stackoverflow question中建议的正则表达式(与您在此问题中提到的正则表达式相同)

此正则表达式还在多行注释中获取新行。因此,如果您用\ n计算当前行的数量,则会遇到麻烦。因为可能存在多行注释,所以正则表达式会一次选择整个多行注释。因此,它不允许您计算新行。

因此,我找到了另一种方法来保持行数,即使使用正则表达式也是如此。在下面解释:

您知道flex将匹配的表达式保留在yytext变量中。因此,我们可以在多行注释中计算换行的数量,并且该代码与我测试的任何代码均能完美配合。 这是我的代码: 注意:numberOfCurrentLine变量是我用来保存当前行号的全局变量。

[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/] {
        // The code below, the counts number of occurance of \n and then adds
        // the number to the numberOfCurrentLine variable
        // to keep the number of current line

        char* str = yytext;
        int i = 0;
        char *pch=strchr(str,'\n');
        while (pch!=NULL) {
            i++;
            pch=strchr(pch+1,'\n');
        }

        numberOfCurrentLine+=i;
    }

此代码计算所选注释中\ n的数量,并将其添加到正在计算当前行号的全局变量中。

我上面使用的用于计算char出现次数的代码来自this post。 因此,使用上面的代码,我总是拥有正确的当前行号,并且代码运行正常。