1
在以下情況下捕獲內部文本的最佳方式是什麼?捕獲不明確的文本片段的最佳方法是什麼?
inner_text = any*;
tag_cdata = '<![CDATA[' inner_text >cdata_start %cdata_end ']]>';
的問題是,它似乎像cdata_end
動作閃光幾次由於事實inner_text可以匹配]
。
在以下情況下捕獲內部文本的最佳方式是什麼?捕獲不明確的文本片段的最佳方法是什麼?
inner_text = any*;
tag_cdata = '<![CDATA[' inner_text >cdata_start %cdata_end ']]>';
的問題是,它似乎像cdata_end
動作閃光幾次由於事實inner_text可以匹配]
。
我找到了解決方案。你需要處理非確定性。目前還不清楚最初,但正確的解決辦法是這樣的:
inner_text = any*;
tag_cdata = '<![CDATA[' inner_text >text_begin %text_end ']]>' %cdata_end;
action text_begin {
text_begin_at = p;
}
action text_end {
text_end_at = p;
}
action cdata_end {
delegate.cdata(data.byteslice(text_begin_at, text_end_at-text_begin_at))
}
從本質上講,你等到你確信你射擊的回調,使用信息,您先前捕獲的前解析一個完整的CDATA標籤。
此外,我發現Ragel中的某些形式的非確定性需要使用優先級明確處理。雖然這看起來有點難看,但它在某些情況下是唯一的解決方案。
在處理諸如(a+ >a_begin %a_end | b)*
這樣的模式時,您會發現遇到的每個單個a
都會調用這些事件,而不是最長的子序列。在某些情況下,可以使用最長匹配kleene星形**
來解決這個模糊問題。它所做的是喜歡匹配現有的模式而不是環繞。
令我驚訝的是,這實際上也改變了事件被調用的方式。作爲一個例子,這將產生一個機器調用回調時,這是無法在一個時間緩衝不止一個字符:
%%{
machine example;
action a_begin {}
action a_end {}
main := ('a'+ >a_begin %a_end | 'b')*;
}%%
產地:
你會發現,它調用a_begin
和a_end
每次。
與此相反,我們可以使內環和事件處理貪婪:
%%{
machine example;
action a_begin {}
action a_end {}
main := ('a'+ >a_begin %a_end | 'b')**;
}%%
主要生產:
是不是很奇怪,當你發現自己的解決方案一年未來和想法,我真的寫了那個!? :) – ioquatix