%%
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
是它的法的错误?
%%
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
是它的法的错误?
不,它遵守规范。
规则是(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没有这样的惊喜;所以我建议按原样采取规则。
“一个lex的bug”可能意味着“你的一个bug”。 ;] – ClosureCowboy 2010-12-10 08:28:03
只要你提供一个理由,这很好。 – lex 2010-12-10 08:30:38