[英]Understanding Parboiled2's '~' Combinator
Looking at the parboiled2 section, Rule Combinators and Modifiers
:查看parboiled2部分,
Rule Combinators and Modifiers
:
I don't understand the a
, b
, and then a ~ b
diagram.我不明白
a
, b
,然后a ~ b
图表。
So far I've found the documentation straightforward.到目前为止,我发现文档很简单。 But I am a bit lost here.
但我在这里有点失落。
Can you please explain each block?你能解释一下每个块吗?
Here's the definition of Rule
:下面是
Rule
的定义:
class Rule[-I <: HList, +O <: HList]
The documentation you linked gives more explanation, but essentially I
is the input to the Rule and O
is the output of the Rule.您链接的文档提供了更多解释,但基本上
I
是规则的输入, O
是规则的输出。 The colon notation can be a little confusing.冒号表示法可能有点混乱。
parboiled2
uses a stack to manage the state. parboiled2
使用堆栈来管理状态。 Just remember that the types in the colon lists ( HList
) are produced/pushed from left to right, and consumed/popped from right to left.请记住,冒号列表 (
HList
) 中的类型HList
生成/推送,从右到左消耗/弹出。 In the HList
A:B:C
, C
is the top of the stack, and has to be consumed first.在
HList
A:B:C
, C
是栈顶,必须先被消耗。
~
runs one rule then the next. ~
运行一个规则然后下一个。 So in the first example a
of type Rule[, A]
consumes nothing and 'produces' an A
, while b
of type Rule[, B]
consumes nothing and 'produces' a B
.因此,在第一个例子中
a
类型的Rule[, A]
消耗无关和“产生”的A
,而b
类型的Rule[, B]
消耗无关和“产生”一B
。 It makes sense then, that if you ran a
followed by b
, you would produce an A
followed by a B
.那么有道理,如果你跑
a
后跟b
,你会产生一个A
后跟一个B
。 The resulting type is Rule[, A:B]
.结果类型是
Rule[, A:B]
。
Things become much more complicated when you add inputs.添加输入时,事情变得更加复杂。 You need to make sure that the types produced by
a
(or whatever the first rule is) are the types that b
is going to consume.您需要确保
a
(或任何第一条规则)生成的类型是b
将要使用的类型。 ~
is just like function composition. ~
就像函数组合。 If we want to compose g
and f
to get g . f
如果我们想组合
g
和f
来得到g . f
g . f
, we need to be sure that the output of f
is the same type as the input of g
. g . f
,我们需要确保f
的输出与g
的输入类型相同。
Let's look at the third example in the table.让我们看看表中的第三个例子。
a
has type Rule[A, B:C]
a
有类型Rule[A, B:C]
b
has type Rule[D:B:C, E:F]
b
类型为Rule[D:B:C, E:F]
When we run a
an A
is consumed from the stack, a B
is added to the stack, and a C
is added to the stack.当我们运行
a
一个A
从堆栈中被消耗,一个B
被添加到堆栈中,一个C
被添加到堆栈中。 Then b
is run, first it consumes the C
, then the B
, then it consumes a D
off the stack.然后
b
运行,首先它消耗C
,然后是B
,然后它消耗堆栈外的D
。 To be in the right place at the right time, that D
would need to be under the A
that a
consumed.要在正确的时间出现在正确的地方,那
D
将需要下A
是a
消耗。 b
would then produce an E
then an F
. b
然后会产生一个E
然后一个F
。
In total, we consumed a D
and an A
.我们总共消耗了一个
D
和一个A
。 The B
and C
don't count because they were produced and consumed internally to the rule. B
和C
不计算在内,因为它们是在规则内部产生和消耗的。 After consuming D
and A
, we leave E
and F
on the stack.消耗完
D
和A
,我们将E
和F
留在堆栈中。 So, the type of a ~ b
is Rule[D:A, E:F]
.所以,
a ~ b
的类型是Rule[D:A, E:F]
。
The fourth example in the README gives an example where a
produces the wrong types for b
to consume. README 中的第四个示例给出了一个示例,其中
a
生成了错误的类型供b
使用。 In that case a ~ b
is illegal.在那种情况下
a ~ b
是非法的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.