2012-10-10 82 views
1

我一直在使用Flex /野牛約6小時,現在,這裏是我不縫的第一個問題是能夠解決:Flex正則表達式不匹配?

我有以下的文件...

state state1: { 
    1-3: 255 
    4: 255 
} 

...我用cat和|傳遞給我的flex/bison程序。 柔性文件包含此行:

\bstate\b { return STATE; } 

進一步壓低這一個:

.*   { fprintf(stderr, "Lexer error on line %d: \"%s\"\n", linenum, yytext); exit(-1); } 

每個人都應該認爲\ bstate \乙方應在文件中得到匹配,但事實並非如此。相反,我得到以下輸出:

"exer error on line 1: "state state1: { 

這在很多方面都很奇怪。首先,Lexer接縫中的L被替換爲「,但更重要的是,狀態沒有得到匹配。爲什麼???當然,\ bstate \ b在。*之前,它們是在右側部分。

感謝您的幫助, 揚

回答

4

(F)萊克斯不會搜索輸入匹配。它試圖在當前輸入位置所有模式,並選擇一個它與大多數文本匹配,或者如果多於一個文本匹配相同數量的文本,則最早的一個匹配。下一個lex匹配將在前一個匹配結束時開始。

.*與該行的其餘部分匹配。 \bstate\b只能匹配七個字符。所以.*會贏。但是\bstate\b實際上並不匹配,因爲這是lex,而不是<在這裏插入您最喜歡的正則表達式>和\b意味着退格,就像它在C程序中一樣。

字母L被報價覆蓋的原因可能是您的輸入文件是在Windows上創建的,並且在行尾有\ r \ n。 .*將匹配包括\r,這是一個回車。因此,當您輸入printf "%s"\n時,替換%s的字符串中的最後一個字符是一個回車符,它將導致光標移動到當前行中的第一個點,該點在該點中具有L。然後「打印在L的頂部,然後最後打印換行符,它開始一個新行。

沒有Lex等效於詞邊界聲明\b但這很少是一個問題。對於幾乎所有的編程語言來說,掃描程序都必須處理保留字也將與標識符的模式相匹配的問題;但是,最長匹配規則和首次匹配規則的組合使得輕鬆實現這一點很簡單,簡單地說,總是把保留字圖案第一例如:

do    { return DO; } 
double   { return DOUBLE; } 
if    { return IF; } 
/* ... */ 
[a-z][a-z0-9]* { return ID; } 

在你把順序在上面的例子中,和double無關緊要,因爲double比較長,但我總覺得應該按照字母順序來保留字以保持整潔。但重要的是ID模式要持續下去,因爲它也會匹配所有的保留字。

現在考慮如何獲取以保留字開頭的標識符,如dog。在這種情況下,DO模式和ID模式都會匹配,但ID匹配比較長,所以儘管稍後會獲勝。

+0

好的,這是有道理的。我雖然只有第一場比賽會被採取。關於這個問題的兩個問題:1:是否有一些關於Flex Regexes的文檔(我應該用什麼來代替\ b?)2:有沒有其他方法匹配時匹配。*,無論匹配更多? – Jan

+0

1)'info flex'是我的指南(也可從http://flex.sourceforge.net/manual/獲得)。模式是第6節。1a)由於順序標記算法,我從來沒有覺得需要\ b。對我來說幸運,因爲我不認爲有一個。 2)不,但通常的做法是匹配列表末尾的「。\ n」。如果這是你想要做的,或者使用開始條件(參見第10節),你可以跳到行動的最後。 – rici

+0

@Jan,如上所示,萬一SO沒有通知你。很明顯,我太晚了。 – rici