狀態機、術語和工具對我來說都是新的,盡管我最近一直在嘗試通過各種在線資源來理解它們。當我想在 Ragel 和 Go 中構建一個比正則表達式更快的解析器時,就開始了這一點。Ragel 文檔的第 3 章涵蓋了操作,這讓我很困惑。我不清楚與狀態轉換相關的操作與狀態本身之間有什么區別。這些示例僅存在狀態嵌入操作的錯誤,因此我不確定何時使用to和from運算符。我做了一個簡單的例子:package mainimport (? ? "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 startfoo endbar startbar endbaz startbaz end但是,如果我使用相同的周圍代碼將其替換為狀態嵌入操作:main := "foo" >~fooStart %*fooEnd "bar" >~barStart %*barEnd "baz" >~bazStart %*bazEnd;我得到以下輸出,其中的順序和缺失的行對我來說沒有意義:bar startfoo endbaz startbar end我的最初印象是,當您只想在整個狀態機中的某些點運行操作而不是更精細的轉換時,請使用狀態嵌入操作。這仍然讓我對它們的執行順序感到困惑,以及為什么不執行“foo”的啟動“to-state”操作。所以我的問題是,使用狀態操作而不是轉換操作有哪些實際原因或示例?用外行人的話來說,它們的工作方式有何不同?這是狀態嵌入操作的圖表。
1 回答

臨摹微笑
TA貢獻1982條經驗 獲得超2個贊
通常您需要使用轉換操作。實際上我很少使用基于狀態的操作。大多數情況下,只有當我想要初始化某些東西并且我希望它在查看角色之前執行時。例如,在執行條件之前。目前,基于國家的行動是實現這一目標的唯一途徑。
有一段時間,我夢想有一個解決方案,您可以嵌入在測試條件之前運行的基于轉換的操作,這樣您就不需要 init 的基于狀態的操作。使用基于狀態的操作總是感覺有點像黑客。
- 1 回答
- 0 關注
- 158 瀏覽
添加回答
舉報
0/150
提交
取消