gpt4 book ai didi

ruby - Parslet 子树不触发

转载 作者:数据小太阳 更新时间:2023-10-29 08:38:58 26 4
gpt4 key购买 nike

Resume(我把下面的长篇大论缩成了简单的问题)

tree = {:properties => [{:a => 'b'}, {:c => 'd'}]}
big_tree = {:properties => [{:a => 'b'}, {:c => 'd'}], :moves => [{:a => 'b'}, {:c => 'd'}]}

trans = Parslet::Transform.new do
rule(:properties => subtree(:nested)) do
out = {}
nested.each {|pair| out = out.merge pair}
{:properties => out}
end
end

pp tree
pp trans.apply(tree)
pp big_tree
pp trans.apply(big_tree)

# OUTPUT

{:properties=>[{:a=>"b"}, {:c=>"d"}]}
{:properties=>{:a=>"b", :c=>"d"}} # Worked with small tree
{:properties=>[{:a=>"b"}, {:c=>"d"}], :moves=>[{:a=>"b"}, {:c=>"d"}]}
{:properties=>[{:a=>"b"}, {:c=>"d"}], :moves=>[{:a=>"b"}, {:c=>"d"}]} # Didn't work with bigger tree

=========================完整故事(在标题之后不那么相关)

我正在使用 Parslet 制作 SGF 文件解析器。

现在我正处于制作变形金刚的阶段。

从解析器我已经得到了这样的结构:

[{:properties=>
[{:name=>"GM"@2, :values=>[{:value=>"1"@5}]},
{:name=>"FF"@7, :values=>[{:value=>"4"@10}]},
{:name=>"SZ"@12, :values=>[{:value=>"19"@15}]},
{:name=>"AP"@18, :values=>[{:value=>"SmartGo Kifu:2.2"@21}]},
{:name=>"GN"@40, :values=>[{:value=>"2013-05-11g"@43}]},
{:name=>"PW"@57, :values=>[{:value=>"Dahan"@60}]},
{:name=>"PB"@68, :values=>[{:value=>"SmartGo"@71}]},
{:name=>"DT"@81, :values=>[{:value=>"2013-05-11"@84}]},
{:name=>"KM"@97, :values=>[{:value=>"6.5"@100}]},
{:name=>"RE"@106, :values=>[{:value=>"W+R"@109}]},
{:name=>"RU"@115, :values=>[{:value=>"AGA (Area)"@118}]},
{:name=>"ID"@129, :values=>[{:value=>"ch0"@132}]}],
:moves=>
[{:player=>"B"@137, :place=>"oq"@139},
{:player=>"W"@143, :place=>"dd"@145},
{:player=>"B"@149, :place=>"oo"@151},
...etc...

我用来转换的规则集:

    # Rewrite player: COLOR, place: X to COLOR: X
rule( player: simple(:p), place: simple(:pl)) do
if p == 'W'
{ white: pl }
elsif p == 'B'
{ black: pl }
end
end
# Un-nest single-value hash
rule( value: simple(:v)) { v }
# Rewrite name: KEY, values: SINGLE_VALUE to KEY: SINGLE_VALUE
rule( name: simple(:n), values: [ simple(:v) ]) { {n.to_sym => v} }
# A Problem!!!
rule( properties: subtree(:props) ) do
out = {}
props.each {|pair| pair.each {|k, v| out[k] = v}}
{ properties: out }
end

有了这样的规则,我得到了以下结构:

[{:properties=>
[{:GM=>"1"@5},
{:FF=>"4"@10},
{:SZ=>"19"@15},
{:AP=>"SmartGo Kifu:2.2"@21},
{:GN=>"2013-05-11g"@43},
{:PW=>"Dahan"@60},
{:PB=>"SmartGo"@71},
{:DT=>"2013-05-11"@84},
{:KM=>"6.5"@100},
{:RE=>"W+R"@109},
{:RU=>"AGA (Area)"@118},
{:ID=>"ch0"@132}],
:moves=>
[{:black=>"oq"@139},
{:white=>"dd"@145},
{:black=>"oo"@151},
...etc...

一切都很完美。我的唯一问题是:属性哈希数组。

最后我想拥有

[{:properties=>
{:GM=>"1"@5,
:FF=>"4"@10,
:SZ=>"19"@15,
:AP=>"SmartGo Kifu:2.2"@21,
:GN=>"2013-05-11g"@43,
:PW=>"Dahan"@60,
:PB=>"SmartGo"@71,
:DT=>"2013-05-11"@84,
:KM=>"6.5"@100,
:RE=>"W+R"@109,
:RU=>"AGA (Area)"@118,
:ID=>"ch0"@132},
:moves=>
[{:black=>"oq"@139},
{:white=>"dd"@145},
{:black=>"oo"@151},
...etc...

你看到了吗?在 :properties 中合并所有排列的哈希值,因为在之前的转换之后,它们现在具有唯一键。也将结构展平一点。

嘿!我可以手动完成。我的意思是运行一个单独的方法,比如

merged_stuff = {}
tree.first[:properties].each {|pair| pair.each {|k, v| merged_stuff[k] = v}}
tree.first[:properties] = merged_stuff

但为什么我不能使用整洁的转换规则来做到这一点,将所有转换逻辑放在一个地方?

重点是 rule( properties: subtree(:props) ) 根本不会被触发。即使我只是从 block 中返回 nil,它也不会改变任何东西。所以,看起来,这个 subtree 没有捕获东西,或者我没有。

最佳答案

问题是 :properties:moves 是同一个哈希中的键,而 subtree 显然不想匹配部分的哈希。如果删除 :moves,规则将被执行。有点解释in the documentation :

A word on patterns

Given the PORO hash

{ 
:dog => 'terrier',
:cat => 'suit' }

one might assume that the following rule matches :dog and replaces it by 'foo':

rule(:dog => 'terrier') { 'foo' }

This is frankly impossible. How would 'foo' live besides :cat => 'suit' inside the hash? It cannot. This is why hashes are either matched completely, cats n’ all, or not at all.

虽然我必须承认这不是一个非常明显的例子。

所以问题规则应该是这样的:

rule( properties: subtree(:props), moves: subtree(:m) ) do
out = {}
props.each {|pair| pair.each {|k, v| out[k] = v}}
{ properties: out , moves: m}
end

关于ruby - Parslet 子树不触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16509369/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com