查看parboiled2部分,Rule Combinators and Modifiers
:
我不明白a
,b
和 thena ~ b
图表。
到目前为止,我发现文档很简单。但我在这里有点迷路了。
你能解释一下每个块吗?
查看parboiled2部分,Rule Combinators and Modifiers
:
我不明白a
,b
和 thena ~ b
图表。
到目前为止,我发现文档很简单。但我在这里有点迷路了。
你能解释一下每个块吗?
这是 的定义Rule
:
class Rule[-I <: HList, +O <: HList]
您链接的文档提供了更多解释,但本质上I
是规则的输入,也是规则O
的输出。冒号表示法可能有点令人困惑。parboiled2
使用堆栈来管理状态。请记住,冒号列表 ( HList
) 中的类型是从左到右生成/推送,从右到左消费/弹出。其中HList
A:B:C
,C
是栈顶,必须先被消费。
~
运行一个规则,然后运行下一个。因此,在a
type 的第一个示例中,Rule[, A]
不消耗任何内容并“产生” an A
,而b
of typeRule[, B]
不消耗任何内容并“产生” a B
。那么这是有道理的,如果你a
跟着跑b
,你会产生一个A
跟着一个B
。结果类型是Rule[, A:B]
.
当您添加输入时,事情变得更加复杂。您需要确保a
(或任何第一条规则)生成的类型b
是要使用的类型。~
就像函数组合一样。如果我们想组合g
并f
得到g . f
,我们需要确保 的输出与f
的输入类型相同g
。
让我们看一下表中的第三个示例。
a
有类型Rule[A, B:C]
b
有类型Rule[D:B:C, E:F]
当我们运行a
一个A
从栈中消费的时候,aB
被添加到栈中,aC
被添加到栈中。然后b
运行,首先它消耗C
,然后是B
,然后它消耗D
堆栈外的 a。要在正确的时间出现在正确的地方,那D
将需要低于A
消耗量a
。b
然后会产生一个E
然后一个F
。
总的来说,我们消耗了 aD
和 an A
。和不计算在内,因为它们是在规则内部生产和消费的B
。C
使用D
and之后A
,我们将E
andF
留在堆栈上。所以,类型a ~ b
是Rule[D:A, E:F]
。
自述文件中的第四个示例给出了一个示例,该示例a
生成了错误的b
消费类型。在这种情况下a ~ b
是非法的。