4

想象一个包含单词的块的简化示例:

samples: [
    [a a c a]
    [a a c b]
    [b a c a]
    [c a c b]
    [c c c c]
]

每个块都需要[c c c c]。因此,如果值为'a,则将其更改为'b。如果值为'b,则将其更改为'c。如果值为'c,我们打印“C”并继续:

repeat i length? samples [
    prin ["^/Sample" i "- "]
    parse samples/:i [
        some [
            s: 'a (change s 'b) :s
            | s: 'b (change s 'c) :s
            | 'c (prin "C")
        ]
    ]
]

在 Rebol 2 中,这按预期工作:

Sample 1 - CCCC
Sample 2 - CCCC
Sample 3 - CCCC
Sample 4 - CCCC
Sample 5 - CCCC

但是 Rebol 3 似乎有一个问题(错误?):

Sample 1 - 
Sample 2 - 
Sample 3 - 
Sample 4 - C
Sample 5 - CCCC

我不知道它是否相关,但包含Rebol 2 和 Rebol 3 之间要解析的更改列表的 Rebol Wikibook说:

某些子规则 - 为了防止 R3 中出现不必要的无限循环,当子规则与输入匹配但不推进它时,此规则也会停止

(注意:@rgchris 在 StackOverflow 聊天中提供的这个简化示例,在此重复以更好地保留“机构知识”并允许更新。)

4

1 回答 1

4

如果您使用 ANY (0..n) 还是 SOME (1..n) 实际上并不重要,就像您的示例中的情况一样,您可以在 R3 中使用 WHILE。WHILE 基本上匹配 R2 的 ANY:

>> blk: [a a c a]

>> parse blk [while [s: 'a (change s 'b) :s | s: 'b (change s 'c) :s | 'c]]
== true

>> blk
== [c c c c]

或者,如果这还不够,因为你真的需要一些语义,你可以使用更基本的原语重写一些。而不是rule: [some subrule]你可以使用rule: [subrule opt rule]

 >> blk: [a a c a]

 >> subrule: [s: 'a (change s 'b) :s | s: 'b (change s 'c) :s | 'c]     
 >> parse blk rule: [subrule opt rule]
 == true

 >> blk
 == [c c c c]

但是,这可能会使您达到一些原始 SOME 不会达到的 PARSE 限制(尤其是在 R2 中)。

于 2013-01-16T11:36:37.067 回答