%%
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