[英]Difference between Ragel transition actions and state actions
狀態機,術語和工具對我來說都是全新的,盡管最近我一直在嘗試通過各種在線資源來解決這些問題。 當我想在Ragel和Go中構建比正則表達式更快的解析器時,就開始了。 我迷住了Ragel文檔的第3章,其中涵蓋了動作。
我不清楚與狀態轉換相關的動作與狀態本身之間的區別是什么。 這些示例僅對狀態嵌入操作有錯誤,因此我不確定何時使用to
和from
運算符。 我舉了一個簡單的例子:
package main
import (
"fmt"
)
%% machine scanner;
%%{
action fooStart { fmt.Println("foo start")}
action fooEnd { fmt.Println("foo end")}
action barStart { fmt.Println("bar start")}
action barEnd { fmt.Println("bar end")}
action bazStart { fmt.Println("baz start")}
action bazEnd { fmt.Println("baz end")}
main := "foo" >fooStart @fooEnd "bar" >barStart @barEnd "baz" >bazStart @bazEnd;
}%%
%% write data;
func main() {
ParseEmbedding([]byte("foobarbaz"))
}
func ParseEmbedding(data []byte) {
cs, p, pe := 0, 0, len(data)
%%{
write init;
write exec;
}%%
}
哪個輸出以下是我期望的:
foo start
foo end
bar start
bar end
baz start
baz end
但是,如果我使用相同的周圍代碼將其替換為狀態嵌入動作:
main := "foo" >~fooStart %*fooEnd "bar" >~barStart %*barEnd "baz" >~bazStart %*bazEnd;
我得到以下輸出,其順序和缺少的行對我來說沒有意義:
bar start
foo end
baz start
bar end
我最初的印象是,當您只想在整個狀態機中的某些點而不是更精細的過渡上運行動作時,將使用狀態嵌入動作。 這仍然使我對它們的執行順序以及為什么不執行“ foo”的start“ to-state”動作感到困惑。
所以我的問題是,使用狀態動作而不是過渡動作的一些實際原因或示例是什么? 在外行方面,他們的工作方式有何不同?
通常,您要使用過渡動作。 實際上,我很少使用基於狀態的操作。 通常只在我想初始化某些東西並希望在看角色之前執行它時才可以。 例如,在執行條件之前。 當前,基於狀態的操作是實現這一目標的唯一方法。
有一陣子,我夢想着有一個解決方案,其中您可以嵌入在測試條件之前運行的基於過渡的操作,這樣您就不需要用於初始化的基於狀態的操作。 使用基於狀態的操作總是感覺有點像黑客。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.