尾随上下文匹配 EOF flex-lexer
Trailing context match EOF flex-lexer
我想匹配这两个标记:
1. NUM
:[0-9_]
中的一系列字符,中间有一个可选的.
。
2. 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
,会有任何性能下降吗?或者我应该注意的任何其他事项?
您不能将 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(至少一个字母)。 (它与您的第二个模式具有相同的效果。我只是缩短了第一个字符 class;因为 *
使前缀成为可选的,所以带有前导字母的 ID 可以直接与其余字符匹配模式。)
我们依靠最大咀嚼来避免模式二过早匹配。没有小数点后跟字母的数字将在模式三处有更长的匹配;带有小数点后跟字母的数字与模式三的匹配时间更长。剩下的就是数字后面没有字母;对于那些模式,两个将适用。
我想匹配这两个标记:
1. NUM
:[0-9_]
中的一系列字符,中间有一个可选的.
。
2. 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
,会有任何性能下降吗?或者我应该注意的任何其他事项?
您不能将 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(至少一个字母)。 (它与您的第二个模式具有相同的效果。我只是缩短了第一个字符 class;因为 *
使前缀成为可选的,所以带有前导字母的 ID 可以直接与其余字符匹配模式。)
我们依靠最大咀嚼来避免模式二过早匹配。没有小数点后跟字母的数字将在模式三处有更长的匹配;带有小数点后跟字母的数字与模式三的匹配时间更长。剩下的就是数字后面没有字母;对于那些模式,两个将适用。