我想要匹配这两种标记:
NUM:[0-9_]中的一系列字符,中间有一个可选的.。ID:[a-zA-Z0-9_]中的一系列字符,至少有一个[a-zA-Z]字符。关于这些问题的灵活规则如下:
[0-9_]+([.][0-9_]+)?/[^a-zA-Z0-9_] return NUM;
[a-zA-Z0-9_]*[a-zA-Z][a-zA-Z0-9_]* return ID;
.
.
.注意,NUM需要尾随上下文,因为"123.456ab"应该匹配123-NUM、.-OPER和456ab-ID。没有尾随上下文,它将匹配123.456-NUM & ab-ID。
但现在的问题是,它将无法与NUM后面的EOF匹配。那么,如何在flex规则的尾随上下文中匹配EOF呢?
TL;DR:
我想要的是:NUM而不是[a-zA-Z0-9_]。
我现在得到的是:NUM后面跟着一个除了[a-zA-Z0-9_]以外的字符。
这两者在EOF上有不同之处。
编辑:刚刚知道Re/Flex支持单词边界。如果我从使用Flex转向使用Re/Flex,有什么性能上的缺点吗?或者其他我应该知道的事情?
发布于 2022-05-14 19:57:47
不能将EOF放在尾上下文中这一事实有时令人讨厌,但几乎总是有一个解决办法,通常是基于使用最大munch匹配顺序来确保某些模式在EOF匹配,因为任何其他匹配都会更长。(请记住,尾上下文对于长度比较很重要,即使它不是最终令牌的一部分)。
以下是一个例子:
[0-9_]+/[.][0-9_]*[a-zA-Z] return NUM;
[0-9_]+([.][0-9_]+)? return NUM;
[0-9_]*[a-zA-Z][a-zA-Z0-9_]* return ID;模式一与小数点后面的数字匹配,如果小数点后面跟着可能是ID的东西。
模式二匹配任何数字,不管后面跟着什么(如果有的话)。
模式三匹配一个ID (至少一个字母)。(它的效果与你的第二种模式相同。我只是缩短了第一个字符类;因为*使前缀是可选的,因此带前导字母的ID可以由模式的其余部分直接匹配。)
为了避免模式2的过早匹配,我们依赖于最大吞吐。没有小数点的数字与字母后面的字母在模式3处有更长的匹配;小数点后面的数字与模式3的匹配更长。剩下的只是数字,后面没有字母;对于那些模式,二将适用。
https://stackoverflow.com/questions/72240697
复制相似问题