我为Flex做了这个实验,看看我是否输入ABC,是否会看到所有A,AB,ABC或只有ABC,或只是表达列表中的第一个匹配。
%{
#include <stdio.h>
%}
%%
A puts("got A");
AB puts("got AB");
ABC puts("got ABC");
%%
int main(int argc, char **argv)
{
yylex();
return 0;
}
当我在编译并运行程序后进入ABC时,它会响应&#34;获得ABC&#34;这真让我感到惊讶,因为我认为lex并没有跟踪访问过的文本,只发现了第一场比赛;但实际上,它似乎找到了最长的匹配。
当且仅当不再匹配时,Flex使用什么策略来响应A?
答案 0 :(得分:3)
(F)lex使用maximal-munch原则这一事实应该不足为奇,因为Flex manual中有详细记载:
当生成的扫描程序运行时,它会分析其输入,查找与其任何模式匹配的字符串。如果它找到多个匹配项,则需要匹配最多文本的那个...如果找到两个或多个相同长度的匹配项,则会选择Flex输入文件中第一个列出的规则。 (“输入如何匹配”一节的第一段)
精确的算法非常简单:每次请求令牌时,flex都会扫描文本,在DFA中移动。每次遇到接受状态时,它都会记录当前的文本位置。当不再有可能的转换时,它将返回到最后记录的接受位置,并且它将成为令牌的结束。
结果是(F)lex可以多次扫描相同的文本,尽管它只扫描每个令牌一次。
一组需要过多反向跟踪的词法规则会减慢词法扫描速度。这将在Flex手册部分Performance Considerations中讨论,并提供一些避免此问题的策略。但是,除病理情况外,反向跟踪的开销并不明显。