了解Parboiled2'〜' Combinator的

时间:2015-03-20 03:18:02

标签: shapeless parboiled2

查看parboiled2部分,Rule Combinators and Modifiers

enter image description here

我不理解ab,然后a ~ b图表。

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

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

1 个答案:

答案 0 :(得分:5)

以下是Rule

的定义
class Rule[-I <: HList, +O <: HList]

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

~运行一个规则,然后运行下一个规则。因此,在a类型Rule[, A]的第一个示例中,A消耗任何内容并“生成”b,而类型Rule[,B]的{​​{1}}不消耗任何内容并“生成”a 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]

当我们运行a并从堆栈中消耗A时,会向堆栈添加B,并向堆栈添加C。然后运行b,首先它消耗C,然后消耗B,然后消耗堆栈中的D。要在正确的时间出现在正确的位置,D需要位于A消耗的a之下。然后,b会生成E,然后生成F

总共我们消耗了DABC不计算在内,因为它们是在规则内部生成和使用的。在使用DA后,我们会在堆栈上留下EF。因此,a ~ b的类型为Rule[D:A, E:F]

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