regex Lex的意外行为

ddarikpa  于 2023-03-20  发布在  其他
关注(0)|答案(1)|浏览(233)

我在bas.l文件中编写了这段代码

digit [0-9]

%% 
{digit}{1,5} {printf("Small Number");}
^{digit}+$ {printf("Big Number");}
%%

int main(void){
    yylex();
    return 0;
}

现在我使用lexcc命令构建词法分析器并输出可执行文件。
确切命令:

lex bas.l
cc lex.yy.c -ll

当我输入任何1-5大小的数字时,lex分析器不会匹配第一个reg表达式,它总是匹配第二个,并打印 Big Number

Input:43
Output : Big Number

Input:4341
Output : Big Number

Input:434111
Output : Big Number

我希望分析器在输入一组大于5的数字时输出 Big Number,在输入小于5的数字时输出 Small Number
我试着删除第二个reg表达式中的 ^$,它起作用了。分析器用第二个reg表达式匹配大于5位数的数字并打印 Big Number。它用第一个reg表达式匹配小于5位数的数字并打印 Small Number
我想知道为什么它在第一个例子中不起作用,第二个表达式中的 ^$ 是如何与第一个表达式匹配的,当输入的是简单的三位数,比如324,提前感谢。
附言:我确实知道 ^ 匹配行首的匹配项,而 $ 匹配行尾的匹配项。但是我不明白为什么第一个表达式没有被匹配。

goqiplq2

goqiplq21#

我认为锚定模式(^...$)总是匹配的原因是它还包括换行符,所以它总是“较长”的匹配,正如Flex手册所述:

  • 运行生成的扫描程序时,它会分析其输入,查找与其任何模式匹配的字符串。如果找到多个匹配项,它将采用与文本匹配最多的那个(对于尾随上下文规则,这包括尾随部分的长度,即使它随后将返回到输入)。*

在(f)lex中,$是一个“尾随上下文操作符”,它匹配零个字符,后面跟着一个换行符,所以换行符包含在匹配的长度中,另一个尾随上下文操作符是\,所以foo$foo/\n相同。

相关问题