使用 flex“||”时无法匹配规则

rule cannot be matched when using flex "||"

如果我删除了第 41 行,那么就没有警告

"lex.l", line 41: warning, rule cannot be matched

line 41: "||" {printf("26,\"%s\"\n",yytext);}

digit [0-9]
letter [A-Za-z]
id ({letter}|[_])({letter}|{digit}|[_])*
%%
[ |\t|\n]+
"var" {printf("28,\"%s\"\n",yytext);}
"if" {printf("29,\"%s\"\n",yytext);}
"then" {printf("30,\"%s\"\n",yytext);}
"else" {printf("31,\"%s\"\n",yytext);}
"while" {printf("32,\"%s\"\n",yytext);}
"for" {printf("33,\"%s\"\n",yytext);}
"begin" {printf("34,\"%s\"\n",yytext);}
"writeln" {printf("35,\"%s\"\n",yytext);}
"procedure" {printf("36,\"%s\"\n",yytext);}
"end" {printf("37,\"%s\"\n",yytext);}
{id} {printf("1,\"%s\"\n",yytext);}
{digit}+ {printf("2,\"%s\"\n",yytext);}

...

"+=" {printf("23,\"%s\"\n",yytext);}
"-=" {printf("24,\"%s\"\n",yytext);}
"==" {printf("25,\"%s\"\n",yytext);}
"||" {printf("26,\"%s\"\n",yytext);}
"&&" {printf("27,\"%s\"\n",yytext);}
%%
#include <ctype.h>
int main(){
    yylex ( );
    return 0 ;
}
yywrap(){
    return 1;
}

这个:

[ |\t|\n]

是一个字符class,匹配以下四个字符之一:

  • space
  • 竖线(|)
  • 选项卡
  • 换行

竖线在class中出现了两次,但由于字符class是一个集合,所以忽略重复。

所以

[ |\t|\n]+

匹配任何仅由上述字符组成的非空序列。一个这样的序列是 ||。由于该规则出现在 "||" 规则之前,它将用于匹配 ||,因此规则 "||" 永远无法匹配,如警告所述。

您应该认真考虑使用 [[:space:]] 来匹配任何白色 space 字符,[[:alpha:]] 来匹配字母,而 [[:digit:]] 来匹配数字。与尝试写出集合相比,这些更像是自我记录。但是,如果您要写出集合,请不要包含竖线,除非您打算包含它。

Flex 模式记录在 flex manual 中。值得一读。