2012-04-22 107 views
0

如何自定義flex的默認操作。我發現像< *>,但是當我運行它說「flex scanner jammed」?也是。規則只會添加一條規則,所以它也不起作用。我想要的是Flex默認規則

comment    "/*"[^"*/"]*"*/" 

%% 
{comment}    return 1; 
{default}    return 0; 
<<EOF>>    return -1; 

是否有可能改變匹配最長的行爲首先匹配?如果是的話,我會做這樣的事情

default    (.|\n)* 

但因爲這幾乎總是給人一種更匹配它會隱藏註釋規則。

編輯

我發現{ - }操作手冊中,但是這個例子中,直接從手動給了我 「unrecogized規則」:

[交流] { - } [BZ]

回答

4

flex默認規則匹配單個字符並將其打印在標準輸出上。如果你不想要這樣的行爲,寫一個明確的規則來匹配單個字符並做其他事情。

模式(.|\n)*將整個輸入文件作爲單個令牌進行匹配,因此這是一個非常糟糕的主意。您認爲默認應該是長時間匹配,但實際上您希望儘可能短(但不是空的)。

默認規則的用途是在輸入語言中任何令牌不匹配時執行某些操作。當lex用於標記語言時,這種情況幾乎總是錯誤的,因爲這意味着輸入以不是該語言的任何有效標記開始的字符開始。

因此,「捕捉任何字符」規則被編碼爲錯誤恢復的形式。這個想法是放棄壞字符(只有一個),然後嘗試從該字符後面的字符開始標記。這只是一個猜測,但這是一個很好的猜測,因爲它是基於已知的:即輸入中有一個壞字符。

恢復規則可能是錯誤的。例如,假設語言的標記不以@開頭,程序員想寫字符串文字"@abc"。只是,她忘記了開頭"並寫了@abc"。正確的解決方法是插入缺失的",而不是放棄@。但是這需要在詞法分析器中有一套更聰明的規則。

無論如何,通常當丟棄一個不好的字符時,您希望爲這種情況發出一條錯誤消息,如「在第42行第3列中跳過無效字符〜」。

將lex用於文本過濾時,將不匹配字符複製到標準輸出的默認規則/操作很有用。然後,默認規則帶來了正則表達式搜索的語義(與正則表達式匹配相反):想法是在輸入中搜索詞法分析器的令牌識別狀態機的匹配,同時打印該搜索所跳過的所有材料。

因此,舉例來說,僅包含規則的法規範:

"foo" { printf("bar"); } 

將實施

sed -e 's/foo/bar/g' 
1

沒有這樣的事情。這聽起來像一個XY problem - 你問我們如何定製flex的默認動作(Y),但你真的想要它實現一些其他的目標,X.

什麼是X?

Re:你的問題,爲什麼要加「。」不要做詭計?如果沒有匹配的數量,你不能執行一個動作,所以所問的問題可能沒有意義。如果沒有匹配,flex將不會執行任何操作,因此要添加「默認」規則,只需使其匹配。

0

我解決了這個問題改爲手動,如果試圖規則的補充匹配相當於。這很好,因爲在這種情況下涉及的匹配模式非常簡單。