红色解析并用 <> 替换双 % 不起作用

red parsing and replacing double % with <> doesn't work

我要变身

 test: "bla bla %bla bla% bla bla bla bla %bla% bla"

进入

 test: "bla bla <bla bla> bla bla bla bla <bla> bla"

使用此代码,红色不起作用:

 rules: [
    (toggle: -1)
    to "%" mark: (
        (toggle: 0 - toggle)
        either (toggle = 1) [change mark {<}][change mark {>}]
    )
    thru "%"
    |
    to end
]

parse test rules

输出是

>> test
== "bla bla <bla bla% bla bla bla bla %bla% bla"

您的解析规则中没有任何迭代构造(SOME、ANY、WHILE 等),因此它执行一次替换并停止也就不足为奇了。

这将为您提供所需的输出,并有一些其他更改供您考虑(尽管仅包括 any [... | skip] 修改即可修复您的代码):

rules: [
    (toggle: true)
    any [
        to "%" mark: thru "%" (
            change mark pick [{>} {<}] (toggle: not toggle)
        )
    |
        skip
    ]
]

parse test rules

(我不是最喜欢将 PICK 与 LOGIC 一起使用的人!...如果为真,它会为您提供第一个元素,如果为假,则为您提供第二个元素,但将其扔在这里是为了好玩。 )

两种解决方案:一种不解析

test: "bla bla %bla bla% bla bla bla bla %bla% bla"
replace test "%" "<"
replace test "%" ">"
replace test "%" "<"
replace test "%" ">"

还有一个带解析

test: "bla bla %bla bla% bla bla bla bla %bla% bla"
parse test [some [to "%" change skip "<"  to "%" change skip ">"] to end]

还有一个是为了好玩

parse test [(tog: next [">" "<"]) some [to "%" change skip tog  (reverse head tog)] to end]

您的规则需要多加注意,尤其是在使用关键字 'to'thru 时。按照您编写规则的方式,替换将发生一次,然后 to end 将使您前进到输入的末尾——这不是您想要的。

我会慢慢讲的。

第一条规则,to "%",这会将输入推进到第一个“%”字符。这是一条成功的规则,因此您的 parens 表达式会执行并修改输入,即将“%”更改为“<”。一切都很好:第一个替换已完成,输入中的下一个字符现在是“<”。 但是 你的下一个规则是 thru "%"。这会使输入 超过 输入中的下一个“%”字符——您想要更改为“>”的字符。

这里的另一个关键部分(正如 HostileFork 指出的那样)是您的替换规则没有重复。您的解析规则运行一次然后就结束了。然后您的替代规则 to end 接管并将输入一直跳到最后。为了获得重复扫描整个输入的规则,您需要使用 someanywhileskip.[=22= 设置规则]

这里是对规则的快速修改,保留了大部分代码,但实现了我认为您想要的结果。

test: "bla bla %bla bla% bla bla bla bla %bla% bla"
toggle: -1
rules: [any [
    to "%" mark: (
        toggle: negate toggle 
        either toggle = 1 [change mark "<"][change mark ">"]
    ) 
    ]
]
parse test rules
test
 == "bla bla <bla bla> bla bla bla bla <bla> bla"

我可能会更改代码中的其他内容,例如切换,您可以看到我去掉了不必要的括号,但现在我主要关注 parse 的工作方式.