Make

方法 make 的文档由以下类型组装而成:

Match 类

来自于 Match

make 方法

method make(Match:D: Mu $payload)
sub make(Mu $payload)

将任意有效载荷(payload)存储到 Match 对象中,稍后可通过 .made / .ast 方法重新取回它。

这通常用于 grammar 的 action 类方法中,其中一个方法存储一段数据,然后由另一个方法取回。这取决于你存储什么数据。它可以是树节点,计算结果或值的列表。

sub 形式的 make 操作当前的 $/,这可能是一个简写:

method my-action ($/) {
    make "foo: $/";
}

make 会把数据结构附加到各自的 Match 对象上, 随后通过 .made 方法取回。使用 Match.perl 方法可以看到, Match 里面有一个 made 属性:

> if 'abc' ~~ /\w+/ { $/.make: {'a' => 'bc', 'd' => 'wsl'}; say $/.made }
{a => bc, d => wsl}
> $/.WHAT
(Match)
> $/.perl
Match.new(list => (), made => {:a("bc"), :d("wsl")}, pos => 3, hash => Map.new(()), orig => "abc", from => 0)
> if 'abc' ~~ /\w+/ { $/.make: {'a' => 'bc', 'd' => 'wsl'}; say $/.ast }
{a => bc, d => wsl}
> $/.perl
Match.new(list => (), made => {:a("bc"), :d("wsl")}, pos => 3, hash => Map.new(()), orig => "abc", from => 0)

除了可以在 regex 中 make/made 数据外,还可以在 Action 类中做同样的事情:

grammar MathExpression {
    token TOP    { <sum>              } 
    rule sum     { <product>+ % '+'   } 
    rule product { <term>+    % '*'   } 
    rule term    { <number> | <group> } 
    rule group   { '(' <sum> ')'      } 
    token number { \d+                }
}

class MathEvalAction {
    method TOP($/) {
        make $<sum>.made;
    }
    method sum($/) {
        make [+] $<product>».made;
    }
    method product($/) {
        make [*] $<term>».made;
    }
    method term($/) {
        make $/.values[0].made;
    }
    method group($/) {
        make $<sum>.made;
    }
    method number($/) {
        make $/.Int;
    }
}

my $match = MathExpression.parse(
    '4 + 5 * (1 + 3)',
    actions => MathEvalAction.new,
);

say $match.made; # Output: 24
say $match.perl; # 会打印一个 Match 的数据结构

Output:

MathExpression=(
	:list(List=()),
	:pos(15),
	:made(24),
	:hash(Map=(
		:sum(MathExpression=(
			:list(List=()),
			:pos(15),
			:made(24),
			:hash(Map=(
				:product(Array=[
					MathExpression=(
							:list(List=()),
							:pos(2),
							:made(4),
							:hash(Map=(
								:term(Array=[
									MathExpression=(
											:list(List=()),
											:pos(2),
											:made(4),
											:hash(Map=(
												:number(MathExpression=(
													:list(List=()),
													:pos(1),
													:made(4),
													:hash(Map=()),
													:orig("4 + 5 * (1 + 3)"),
													:to(1),
													:from(0)
												))
											)),
											:orig("4 + 5 * (1 + 3)"),
											:to(2),
											:from(0)
									)
								])
							)),
							:orig("4 + 5 * (1 + 3)"),
							:to(2),
							:from(0)
					),
					MathExpression=(
							:list(List=()),
							:pos(15),
							:made(20),
							:hash(Map=(
								:term(Array=[
									MathExpression=(
											:list(List=()),
											:pos(6),
											:made(5),
											:hash(Map=(
												:number(MathExpression=(
													:list(List=()),
													:pos(5),
													:made(5),
													:hash(Map=()),
													:orig("4 + 5 * (1 + 3)"),
													:to(5),
													:from(4)
												))
											)),
											:orig("4 + 5 * (1 + 3)"),
											:to(6),
											:from(4)
									),
									MathExpression=(
											:list(List=()),
											:pos(15),
											:made(4),
											:hash(Map=(
												:group(MathExpression=(
													:list(List=()),
													:pos(15),
													:made(4),
													:hash(Map=(
														:sum(MathExpression=(
															:list(List=()),
															:pos(14),
															:made(4),
															:hash(Map=(
																:product(Array=[
																	MathExpression=(
																			:list(List=()),
																			:pos(11),
																			:made(1),
																			:hash(Map=(
																				:term(Array=[
																					MathExpression=(
																							:list(List=()),
																							:pos(11),
																							:made(1),
																							:hash(Map=(
																								:number(MathExpression=(
																									:list(List=()),
																									:pos(10),
																									:made(1),
																									:hash(Map=()),
																									:orig("4 + 5 * (1 + 3)"),
																									:to(10),
																									:from(9)
																								))
																							)),
																							:orig("4 + 5 * (1 + 3)"),
																							:to(11),
																							:from(9)
																					)
																				])
																			)),
																			:orig("4 + 5 * (1 + 3)"),
																			:to(11),
																			:from(9)
																	),
																	MathExpression=(
																			:list(List=()),
																			:pos(14),
																			:made(3),
																			:hash(Map=(
																				:term(Array=[
																					MathExpression=(
																							:list(List=()),
																							:pos(14),
																							:made(3),
																							:hash(Map=(
																								:number(MathExpression=(
																									:list(List=()),
																									:pos(14),
																									:made(3),
																									:hash(Map=()),
																									:orig("4 + 5 * (1 + 3)"),
																									:to(14),
																									:from(13)
																								))
																							)),
																							:orig("4 + 5 * (1 + 3)"),
																							:to(14),
																							:from(13)
																					)
																				])
																			)),
																			:orig("4 + 5 * (1 + 3)"),
																			:to(14),
																			:from(13)
																	)
																])
															)),
															:orig("4 + 5 * (1 + 3)"),
															:to(14),
															:from(9)
														))
													)),
													:orig("4 + 5 * (1 + 3)"),
													:to(15),
													:from(8)
												))
											)),
											:orig("4 + 5 * (1 + 3)"),
											:to(15),
											:from(8)
									)
								])
							)),
							:orig("4 + 5 * (1 + 3)"),
							:to(15),
							:from(4)
					)
				])
			)),
			:orig("4 + 5 * (1 + 3)"),
			:to(15),
			:from(0)
		))
	)),
	:orig("4 + 5 * (1 + 3)"),
	:to(15),
	:from(0)
)
make 

comments powered by Disqus