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

それが関連しているかどうかはわかりませんが、Rebol2とRebol3の間で解析する変更のリストを含むRebolWikibookには次のように書かれています。

いくつかのサブルール-R3での不要な無限ループを防ぐために、このルールは、サブルールが入力と一致するがそれを進めない場合にも停止します

(注:StackOverflowチャットで@rgchrisによって提供されたこの簡略化された例は、 「組織の知識」をより適切に保持し、更新を許可するためにここで繰り返されます。)

4

1 に答える 1

4

例のように、ANY(0..n)とSOME(1..n)のどちらを使用するかが実際に重要でない場合は、R3で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]

あるいは、SOMEセマンティクスが本当に必要なためにそれだけでは不十分な場合は、より基本的なプリミティブを使用してSOMEを書き直すことができます。代わりに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(特にR2)ではヒットしないPARSE制限に到達する可能性があります。

于 2013-01-16T11:36:37.067 に答える