查看parboiled2部分,Rule Combinators and Modifiers
:
我不理解a
,b
,然后a ~ b
图表。
到目前为止,我发现文档很简单。但我在这里有点迷失。
你能解释一下这个街区吗?
答案 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
将要使用的类型。 ~
就像功能组合一样。如果我们想要g
和f
来获取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
。
总共我们消耗了D
和A
。 B
和C
不计算在内,因为它们是在规则内部生成和使用的。在使用D
和A
后,我们会在堆栈上留下E
和F
。因此,a ~ b
的类型为Rule[D:A, E:F]
。
README中的第四个示例给出了一个示例,其中a
生成了b
要使用的错误类型。在这种情况下,a ~ b
是非法的。