Flex规则无法匹配求助:匹配特定格式模式编译报错
刚上手Flex的时候踩这些语法和规则优先级的坑太正常啦!我帮你梳理下代码里的几个关键问题,应该就能解决规则无法匹配的警告了:
1. 正则语法错误:多余的分隔符
你最后一条规则的结尾多了个竖线 |:
"ss\:Name\=\"Number\""|"ss\:Name\="\"{string}\"|
这个多余的竖线会让Flex认为你还有一个空的备选规则,直接触发语法警告,甚至导致编译失败,先把它删掉。
2. 宏引用和转义的错误
- 冒号不需要转义:在Flex的字面量字符串里,冒号
:是普通字符,不需要加反斜杠转义。你写的ss\:Workshop会被Flex当成匹配ss\Workshop(带反斜杠),这和你要匹配的ss:Workshop完全不符,这是核心问题之一! - 不能在引号里引用宏:你写的
"ss\:Name\="\"{string}\""里,{string}会被当成普通的字符序列({、s、t...),而不是你之前定义的string宏。要正确匹配带引号的字符串,应该把引号和宏分开写,比如ss:Name="({string})"。
3. string宏的定义有缺陷
你定义的string要求至少两个字符:
string ({letter}|{digit}|{other_characters})({letter}|{digit}|{other_characters})+
但如果遇到ss:Name="a"这种单字符字符串就匹配不到了,应该改成允许至少一个字符:
string ({letter}|{digit}|{other_characters})+
4. 规则顺序导致的匹配优先级问题
Flex会优先选择最长的匹配,同时靠前的规则优先级更高。你把通用的TEXTMSG规则放在最前面,会先匹配到ss:Name里的ss、Name这些片段,导致后面的ss:Workshop、ss:Name=...这些具体规则根本没机会触发。
解决方法很简单:把具体的规则(ss:Workshop、ss:Name相关)放在最前面,再写通用的TEXTMSG规则。
修正后的示例代码
把这些问题都修复后,代码大概是这样的:
%{ #include "y.tab.h" #include <stdio.h> #include <stdlib.h> #include <string.h> %} %option noyywrap letter [a-zA-Z] digit [0-9] other_characters [./\-_] /* 横杠放在最后或转义,避免被当成范围符 */ whitespace [ \t] newline [\n] string ({letter}|{digit}|{other_characters})+ %% /* 先写具体规则,保证优先级 */ ss:Workshop {printf("%s", yytext); return WORKSHOP;} ss:Name="Number" {printf("%s", yytext); return NAME;} ss:Name="({string})" {printf("%s", yytext); return NAME;} /* 再写通用文本规则 */ {string}({whitespace}|{string})* {printf("%s", yytext); return TEXTMSG;} /* 跳过空白和换行,避免Flex默认输出未匹配的空白 */ {whitespace}+ | {newline}+ {} %%
额外小提示
- 定义字符集时,横杠
-如果放在中间会被当成范围符号(比如a-z),所以要么放在字符集最后,要么转义成\-。 - 一定要处理空白和换行,否则Flex会把未匹配的空白默认输出到控制台,干扰你的预期输出。
内容的提问来源于stack exchange,提问作者Dimitris Delis
相关产品推荐
相关产品推荐

