为什么跳过flex正则表达式?

时间:2014-09-04 18:09:21

标签: regex flex-lexer

对于我的生活,我不能弄清楚我的正则表达式是什么问题。

我想要标记的是两(2)种字符串,这两种字符串都包含在一行中。一个字符串可以是任何字符串(除了新行),另一个字符串可以是任何字母数字(ASCII)字符和文字'_','/'' - '和'。'。

灵活代码片段是:

nl    \n|\r\n|\r|\f|\n\r
...
%%
...
\"[^\"]+{nl} { frx_parser_error("Label is missing trailing double quote."); }
\"[a-zA-Z0-9_\.\/\-]+\" {
      if (yyleng > 1024) frx_parser_error("File name too long.");
      yytext[yyleng - 1] = '\0';
      frx_parser_lval.str = strdup(yytext+1);
      fprintf(stderr,"TOSP_FILENAME: %s\n", frx_parser_lval.str);
      return (TOSP_FILENAME);
   }
\"[^{nl}]+\" {
      yytext[yyleng - 1] = '\0';
      frx_parser_lval.str = strdup(yytext+1);
      fprintf(stderr,"TOSP_IDENTIFIER:\n%s\n",  frx_parser_lval.str);
      return (TOSP_IDENTIFIER);
   }

当我运行解析器时,fprintf吐出了这个:

TOSP_FILENAME: ModStar-Picture-Analysis.txt
TOSP_FILENAME: ModStar-Rubric.log.txt
TOSP_IDENTIFIER:
picture-A"
Progress (26,255)   camera 'C' root("picture-C-
Syntax (line 34): syntax error

无论出于何种原因,picture-A之后的引用都被错过了。为什么?我检查了引号字符出现的八个位置的ASCII值,它们都是0x22(其中出现了双倍的quutoes)。

如果我在"picture-A"的末尾添加一些字符,它有时会起作用;添加“.par”,“。pbr”不能按预期工作,但“.pnr”可以。

我甚至添加了一个特定的非regexy令牌:

\"picture-A\"    { frx_parser_lval.str = strdup("picture-A"); return TOSP_FILENAME; }

到lex文件,被跳过。

我在lex文件中使用flex 2.5.39,没有flex库,一个选项(%option prefix=frx_parser_),而flex命令行是:

flex -t script-lexer.l  > script-lexer.c

是什么给出了?

编辑我需要在实际系统上对此进行测试,但单元测试显示此标记符更加强大(基于rici的答案):

nl      \n|\r\n|\r|\f|\n\r
...
%%
...
["][^"]+{nl}           { printf("Missing trailing quote.\n%s\n",yytext); }
["][[:alnum:]_./-]+["] { printf("File name:\n%s\n",yytext); }
["][^"]+["]            { printf("String:\n%s\n",yytext); } 

编辑规则["].+["]将连续多个字符串吞为一个大字符串。它已更改为["][^"]+["]

1 个答案:

答案 0 :(得分:3)

问题在于你的模式:

\"[^{nl}]+\" 

您尝试在字符类中扩展定义,但这是不可能的;在字符类中,{始终只是{,而不是flex运算符。请参阅flex manual

  

请注意,在字符类内部,除了escape('\')和字符类运算符' - ',']]'之外,所有正则表达式运算符都失去了它们的特殊含义,并且在类的开头, '^'。

定义不是宏。相反,定义定义了一个新的正则表达式运算符。

由于上述原因,您可以将[^\"]简称为[^"]而将\"[a-zA-Z0-9_\.\/\-]+\"写为\"[a-zA-Z0-9_./-]+\"-需要在结束或开始。)就个人而言,我将第二种模式写为:

["][[:alnum:]_./-]+["]

但每个人都有自己的风格。