Flex编译l22_scanner.l报166行rule cannot be matched警告排查
Flex词法文件
rule cannot be matched警告根因定位 这个警告的行号是Flex计算偏移后的结果,你看到的166行空白字符不是触发原因,不用在这行浪费时间排查。警告的根本诱因是两个规则写法问题:
- 首条缩进处理规则模式写错了
你现在写的第一条规则是^.*$,会直接匹配从行首到行尾的全部整行内容。Flex的匹配逻辑是最长匹配优先,这条规则一匹配就是整行长度,优先级天然高于后面所有关键字、标识符、数字、运算符类的短规则。你在动作里调用yyless(0)把全部匹配字符退回输入流的写法属于非标准用法,会直接干扰Flex的规则可达性分析,还会导致行号计算错位,把警告挂到了后面无关的空白行上。
处理缩进的标准写法根本不需要匹配整行,只需要匹配行首的空白序列即可,模式应改为^[ \t]*,只捕获行首的空格、制表符计算缩进层级,完全不需要把整行内容吃进去再回退。额外加一条^[ \t]*$ ;规则直接忽略全空白行即可。 - 存在被完全覆盖的重复运算符规则
你在运算符部分写了两条单字符匹配规则:- 靠前位置:
[-+*/%~<>@?=] return *yytext; - 靠后位置:
[-+*/%()<>={}.?\[\],@:=] return *yytext;
第二条规则里的- + * / % < > @ ? =这些字符,已经完全被前面第一条规则覆盖。Flex对相同长度的匹配会优先选排在前面的规则,这些字符永远不可能走到第二条规则的逻辑里。这个重复定义本身不会触发整条规则失效的警告,但会和前面的整行匹配规则共同干扰Flex的静态分析,最终触发误报。
- 靠前位置:
修复方法
- 替换首条整行匹配的缩进规则为行首空白匹配模式,去掉非标准的整行匹配+全量回退逻辑,这一步做完警告基本就会消失。
- 合并两条重复的单字符运算符规则,把所有需要支持的单字符(括号、方括号、大括号、逗号、冒号、点号等)统一放到同一个字符类中,注意把这条单字符规则放在所有双字符运算符(
>=/<=/==/!=/->)的后面,避免短规则优先匹配截断双字符token。
内容的提问来源于stack exchange,提问作者Martim Correia
相关产品推荐
相关产品推荐

