2016-09-21 73 views
0

我在网站上有相关线索(My lex pattern doesn't work to match my input file, how to correct it?我可以在lex代码中指定模式匹配优先级吗?

我遇到的问题是关于“greedy”lex如何进行模式匹配,我有我的lex文件:

$ cat b.l 
%{ 
#include<stdio.h> 
%} 
%% 
"12" {printf("head\n");} 
"34" {printf("tail\n");} 
.* {printf("content\n");} 
%% 

我想说的是,当遇到“12”时,打印“头”;当遇到“34”时,打印“尾巴”,否则打印“内容”为不包含“12”或“34”的最长匹配。

但事实是,“。*”是一个贪婪的匹配,无论我输入什么,它都会打印“内容”。

我的要求是,当我使用

12sdf2dfsd3sd34

为输入,输出应该是

head 
content 
tail 

所以似乎还有就是2点可能的方式:

1,To s规定匹配优先级为“。*”,只有在“12”和“34”都不匹配时才能工作。 lex支持“优先”吗?

2,更改第三个表达式,以匹配任何不包含“12”或“34”子字符串的连续字符串。但是如何写这个正则表达式呢?

回答

1
  1. 是否(f)lex支持优先?

(F)lex总是会产生最长的匹配。如果多个规则匹配相同的最长匹配,则选择第一个匹配,因此在这种情况下它支持优先级。但它不支持较短匹配的优先级,也不支持非贪婪匹配。

  1. 如何匹配不包含一个或多个序列的字符串?

可以与一些工作,创造出的字符串不包含指定子串匹配正则表达式,但它是特别不容易和(f)法并不适用于此类的正则表达式提供一个简单的语法。

一个更简单(但效率稍低)的解决方案是匹配字符串。作为一个大致的轮廓,你可以做到以下几点:

"12"  { return HEAD; } 
"34"  { if (yyleng > 2) { 
      yyless(yyleng - 2); 
      return CONTENT; 
      } 
      else 
      return TAIL; 
     } 
.|\n  { yymore(); } 

这可以由通过匹配多个字符时,有没有跳过一个分隔符的机会,更高效;改变过去的规则:

.|[^13]+ { yymore(); } 

yymore()导致保留当前令牌,以便在下次比赛追加到当前令牌,而不是开始一个新的令牌。 yyless(x)将除第一个x以外的所有字符都返回给输入流;在这种情况下,用于在识别CONTENT令牌后重新扫描结束分隔符34

(即假定你真正想要来标记输入流,而不是仅仅打印调试消息,这就是为什么我把它叫做一个轮廓的解决方案。)

+0

这确实满足我的要求,只是改变了“12”规则是像你的“34”规则。谢谢! –

相关问题