2011-10-04 18 views
0

我從用戶獲得第一個輸入,它是一棵樹(具有顯着的高度和深度)的節點。每個節點都包含一個正則表達式和修飾符。這棵樹被保存在內存中。這僅在應用程序啓動時進行一次。eval在某段時間後無法匹配正則表達式

第二個輸入是一個從樹的根節點開始匹配直到找到完全匹配的葉節點(深度優先搜索)的值。

my $evalstr = <<EOEVAL; 
if(\$input_value =~ /\$node_regex/$node_modifiers){ 
    1; 
}else{ 
    -1; 
} 
EOEVAL 

no strict 'refs'; 
my $return_value = eval "no strict;$evalstr"; 

第二輸入由源連續地提供在整個應用程序的生命時間:匹配確定如下。

問題: 上面的代碼在一段時間內(大約10小時)工作得很好,但是在這段時間連續輸入之後,eval會不斷開始失敗,我在$ return_value中得到-1。應用程序的所有其他功能都可以很好地工作,包括其他比較語句。如果我重新啓動應用程序,匹配會再次啓動並提供正確的結果。

觀察: 1)我多次得到深度遞歸警告,但是我在某處讀取它是正常的,因爲考慮到輸入樹的大小,對於我來說堆棧大小會超過100倍。 2)如果我使用簡單的邏輯進行正則表達式匹配而沒有使用eval,那麼對於應用程序的任何連續運行我都沒有問題。

if($input_value =~ /$node_regex/){ 
    $return_value=1; 
}else{ 
    $return_value=-1; 
} 

但後來我不得不犧牲動態調節劑,按Dynamic Modifiers

檢查: 1)我檢查$ @,但它是空的。 2)同時打印$ input_value,$ node_regex和$ node_modifiers的相應值,它們是正確的,應該在失敗點與正則表達式匹配。 3)我檢查了內存使用情況,但是在perl進程的時間內它是相當穩定的。 4)使用perl 5.8.8然後更新到5.12,但仍然面臨同樣的問題。

問題: 上述問題的原因是什麼?爲什麼在一段時間後失敗,但在應用程序重新啓動時運行良好?

+0

正則表達式從哪裏來?這是一個瘋狂的猜測,但也許它正在陷入災難性的回溯行爲,這種行爲在通過樹進行更深入更深入的搜索時性能下降是有意義的。你可以發佈一些正則表達式嗎?一些他們應該匹配的文本? –

+0

爲什麼你需要在eval中使用'no strict;'?沒有它的代碼不工作嗎? – Dallaylaen

+0

請注意,如果您預編譯正則表達式並將它們存儲在樹中而不是始終進行字符串轉義,那該怎麼辦?參見: 節點初始化(或修改,如果樹不是r/o): 'my $ cached_regex = eval「qr/\ $ node_regex/$ node_modifiers」;' 而後面在主循環中: 'my $ return_value = $ input_value =〜/ $ cached_regex /?1:-1;' – Dallaylaen

回答

0

一個明確的答案需要比我更多的perl內部知識。但考慮到你在做什麼,連續分析大型樹木,假設正在達到一些限制似乎是安全的,某些資源已經耗盡。我會仔細研究一下,並確保在每次解析迭代之間釋放所有資源。我會特別關注複雜結構中的循環引用,並確保沒有。