了解Parboiled2的'〜'组合器

Kev*_*ith 2 shapeless parboiled2

看看parboiled2部分,Rule Combinators and Modifiers:

在此输入图像描述

我不明白的a,b和再a ~ b图.

到目前为止,我发现文档很简单.但在这里有点失落.

你能解释一下这个街区吗?

axb*_*unt 5

这是以下定义Rule:

class Rule[-I <: HList, +O <: HList]
Run Code Online (Sandbox Code Playgroud)

您链接的文档提供了更多解释,但基本上I是规则的输入,并且O是规则的输出.结肠符号可能有点令人困惑.parboiled2使用堆栈来管理状态.请记住,冒号列表(HList)中的类型是从左到右生成/推送,并从右到左消耗/弹出.在HList A:B:C,C是堆栈的顶部,必须先消耗.

~运行一个规则然后下一个.因此,在第一个a类型的例子中,Rule[, A]什么都不消耗,并且'生成'一个A,而b类型Rule[,B]则不消耗任何东西,并且'生成'一个B.那么有意义的是,如果你a跟着跑b,你会产生一个A后跟一个B.结果类型是Rule[, A:B].

添加输入后,事情变得更加复杂.您需要确保由a(或第一个规则是什么)生成的类型b是将要使用的类型.~就像功能组合一样.如果我们想要编写gf得到g . f,我们需要确保输出的f类型与输入相同g.

让我们看一下表格中的第三个例子.

  • a 有类型 Rule[A, B:C]
  • b 有类型 Rule[D:B:C, E:F]

当我们运行aA是由堆消耗,一个B被添加到堆栈,并且C被添加到堆栈.然后b运行时,首先它消耗了C,那么B,然后它消耗了D堆栈.要在正确的时间出现在正确的地方,那D将需要根据Aa消耗.b然后会产生E一个F.

总的来说,我们消耗了一个D和一个A.该BC不计,因为他们生产和国内消费的规则.消费后DA,我们离开E,并F在堆栈中.所以,类型a ~ bRule[D:A, E:F].

README中的第四个示例给出了一个示例,其中a生成了错误的类型以b供使用.在那种情况下a ~ b是非法的.