Flex词法分析器的行为不符合预期

问题描述

我正在尝试使用Flex来匹配基本图案并打印一些东西。

%%
 
^[^qA-Z]*q[a-pr-z0-9]*4\n           {printf("userid1,userid2  \n"); return 1;}

%% 
int yywrap(void){return 1;}

int main( int argc,char **argv )
             {
             ++argv,--argc;  /* skip over program name */
             if ( argc > 0 )
                     yyin = fopen( argv[0],"r" );
             else
                     yyin = stdin;

             while (yylex());
             }

解决的哑巴问题

解决方法

我不知道您要做什么,所以我将重点放在眼前的问题上,这是您的最后一个模式:

^[^qA-Z]*q[a-pr-z0-9]*4[a-pr-z0-9]*4[a-pr-z0-9]*\n

该模式始于匹配[^qA-Z]*,它是q也不是大写字母(A-Z)的任意数量。然后它匹配q

这里值得考虑所有不是q也不是大写字母(A-Z)的事物。显然,其中包括小写字母,例如sq除外)。它还包括数字。它包括任何其他字符:标点符号,空格,甚至控制字符。特别是,它包括换行符。

所以当您键入

10s10<newline>

那肯定是最后一个模式的开始。扫描程序尚未看到q,因此它不知道该模式是否最终匹配,但尚未失败。因此,它会继续读取更多字符,包括更多换行符。

当您最终键入q时,扫描仪可以继续其余模式。根据您下一步输入的内容,它可能会或可能无法继续。如果您的输入似乎最终无法匹配该模式,则词法分析器将退回到最长的成功匹配项,这是第一个模式。届时,它将执行第一个动作

负字符类需要谨慎使用。容易陷入这样的陷阱:“不……”仅包括“合理”输入。但这包括了一切。通常,在这种情况下,您至少要排除换行符。