我可以在 lex 代码中指定模式匹配优先级吗?
Could I specify pattern match priority in lex code?
我在站点中有一个相关主题()
我遇到的问题是关于“贪婪”的 lex 如何进行模式匹配,例如我有我的 lex 文件:
$ cat b.l
%{
#include<stdio.h>
%}
%%
"12" {printf("head\n");}
"34" {printf("tail\n");}
.* {printf("content\n");}
%%
我想说的是,遇到“12”,打印“head”;当遇到“34”时,打印“tail”,否则为不包含“12”或“34”的最长匹配打印“content”。
但事实是,“.*”是贪婪匹配,无论我输入什么,它都会打印“内容”。
我的要求是,当我使用
12sdf2dfsd3sd34
作为输入,输出应该是
head
content
tail
看来有两种可能的方法:
1, To specify a match priority for ".*", it should work only when neither "12" and "34" works to match. Does lex support "priority"?
2, to change the 3rd expression, as to match any contiguous string that doesn't contain sub-string of "12", or "34". But how to write this regular expression?
- (f)lex 是否支持优先级?
(F)lex 总是产生最长的可能匹配。如果多个规则匹配相同的最长匹配项,则选择第一个,因此在这种情况下它支持优先级。但是它不支持较短匹配的优先级,也没有实现非贪婪匹配。
- 如何匹配不包含一个或多个序列的字符串?
通过一些工作,您可以创建一个正则表达式来匹配不包含指定子字符串的字符串,但这并不是特别容易,而且 (f)lex 不为此类正则表达式提供简单的语法。
一个更简单(但效率稍低)的解决方案是分段匹配字符串。作为粗略的概述,您可以执行以下操作:
"12" { return HEAD; }
"34" { if (yyleng > 2) {
yyless(yyleng - 2);
return CONTENT;
}
else
return TAIL;
}
.|\n { yymore(); }
在不可能跳过定界符的情况下,通过匹配多个字符可以提高效率;将最后一条规则更改为:
.|[^13]+ { yymore(); }
yymore()
导致保留当前标记,以便下一个匹配附加到当前标记而不是开始一个新标记。 yyless(x)
returns 除了第一个 x
个字符到输入流;在这种情况下,它用于导致在识别 CONTENT 令牌后重新扫描结束定界符 34
。
(假设您实际上想要标记输入流,而不是仅仅打印一条调试消息,这就是我将其称为大纲解决方案的原因。)
我在站点中有一个相关主题(
我遇到的问题是关于“贪婪”的 lex 如何进行模式匹配,例如我有我的 lex 文件:
$ cat b.l
%{
#include<stdio.h>
%}
%%
"12" {printf("head\n");}
"34" {printf("tail\n");}
.* {printf("content\n");}
%%
我想说的是,遇到“12”,打印“head”;当遇到“34”时,打印“tail”,否则为不包含“12”或“34”的最长匹配打印“content”。
但事实是,“.*”是贪婪匹配,无论我输入什么,它都会打印“内容”。
我的要求是,当我使用
12sdf2dfsd3sd34
作为输入,输出应该是
head
content
tail
看来有两种可能的方法:
1, To specify a match priority for ".*", it should work only when neither "12" and "34" works to match. Does lex support "priority"?
2, to change the 3rd expression, as to match any contiguous string that doesn't contain sub-string of "12", or "34". But how to write this regular expression?
- (f)lex 是否支持优先级?
(F)lex 总是产生最长的可能匹配。如果多个规则匹配相同的最长匹配项,则选择第一个,因此在这种情况下它支持优先级。但是它不支持较短匹配的优先级,也没有实现非贪婪匹配。
- 如何匹配不包含一个或多个序列的字符串?
通过一些工作,您可以创建一个正则表达式来匹配不包含指定子字符串的字符串,但这并不是特别容易,而且 (f)lex 不为此类正则表达式提供简单的语法。
一个更简单(但效率稍低)的解决方案是分段匹配字符串。作为粗略的概述,您可以执行以下操作:
"12" { return HEAD; }
"34" { if (yyleng > 2) {
yyless(yyleng - 2);
return CONTENT;
}
else
return TAIL;
}
.|\n { yymore(); }
在不可能跳过定界符的情况下,通过匹配多个字符可以提高效率;将最后一条规则更改为:
.|[^13]+ { yymore(); }
yymore()
导致保留当前标记,以便下一个匹配附加到当前标记而不是开始一个新标记。 yyless(x)
returns 除了第一个 x
个字符到输入流;在这种情况下,它用于导致在识别 CONTENT 令牌后重新扫描结束定界符 34
。
(假设您实际上想要标记输入流,而不是仅仅打印一条调试消息,这就是我将其称为大纲解决方案的原因。)