2010-12-10 70 views
0

规则:这是一个lex的bug吗?

%% 
AAAA  print("AAAA  : %s\n",yytext); 
AAA  print("AAA  : %s\n",yytext); 
AA  print("AA  : %s\n",yytext); 

和输入是AAAAA,输出为:

AAAA  : AAAA 
A 

相反的:

AAA  : AAA 
AA  : AAA 

是它的法的错误?

+1

“一个lex的bug”可能意味着“你的一个bug”。 ;] – ClosureCowboy 2010-12-10 08:28:03

+0

只要你提供一个理由,这很好。 – lex 2010-12-10 08:30:38

回答

1

不,它遵守规范。

规则是(man 1p lex

在模式匹配,应法搜索组模式为单最长可能的匹配。在匹配相同数量字符的规则中,首先应选择规则。

所以它会一直贪婪地搜索最长的AAAA首先。这个规则在很多语言的词汇约定中很常见。例如。 C++:

void f(void*=0); 

将无法​​解析,这是因为字符*=被解释为分配-乘法运算符(其是最长的匹配),不*然后=

这条规则背后的原因是它可以有效地实施。使用此规则的扫描器只需要O(1)空间(包括输入,即输入不需要装入内存)和O(N)时间。如果要检查输入的其余部分是否可以进行标记,则需要O(N)空间和O(N^2)时间。特别是当所有汇编都是以线性方式完成时,内存消耗在中世纪的计算中至关重要。我相信,在解析今天的数十万行源文件(例如包含头文件的C文件)时,您不会感激O(N^2)运行时间。其次,这样生成的扫描器速度非常快,并且在解析时帮助很大。

最后但并非最不重要的是,规则很容易理解。作为一个相反的例子,考虑ANTLR的标记化规则,即使当前标记的前缀是一个标记,并且输入减去该标记的前缀是可标记的,该规则有时也不能匹配。例如:

TOK1 : 12 
TOK2 : (13)+ 

将无法​​匹配'12131312'。 lex没有这样的惊喜;所以我建议按原样采取规则。