为了账号安全,请及时绑定邮箱和手机立即绑定

Ragel 转移动作和状态动作之间的区别

Ragel 转移动作和状态动作之间的区别

Go
小唯快跑啊 2023-07-10 17:39:42
状态机、术语和工具对我来说都是新的,尽管我最近一直在尝试通过各种在线资源来理解它们。当我想在 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 的基于状态的操作。使用基于状态的操作总是感觉有点像黑客。


查看完整回答
反对 回复 2023-07-10
  • 1 回答
  • 0 关注
  • 84 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信