Difference between Rebol 2 and Rebol 3 when mixing SOME syntax with CHANGE

Imagine a simplified example of a block of blocks containing words:

samples: [ [aaca] [aacb] [baca] [cacb] [cccc] ] 

Each block must be [cccc] . Therefore, if the value is 'a , it changes to 'b . If the value is 'b , it changes to 'c . If the value is 'c , we type ā€œCā€ and move on:

 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") ] ] ] 

In Rebol 2, this works as expected:

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

But Rebol 3 has a problem (bug?):

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

I don't know if this is related, but Rebol Wikibook, which contains a list of parsing changes between Rebol 2 and Rebol 3 , talks about it

SOME subrule - to prevent unwanted endless loops in R3, this rule also stops when the subrule matches the input but does not advance it

(Note: This simplified example provided by @rgchris in the StackOverflow chat is repeated here to better preserve "institutional knowledge" and allow updates.)

+4
source share
1 answer

If it doesn't really matter if you use ANY (0..n) or SOME (1..n), as is the case in your example, you can use WHILE in R3. WHILE basically corresponds to R2 ANY:

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

Otherwise, if this is not enough because you really need SOME semantics, you can rewrite SOME using simpler primitives . Instead of rule: [some subrule] you can use rule: [subrule opt rule] :

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

However, this may force you to press some PARSE restrictions that you will not beat with the original SOME (especially in R2).

+4
source

All Articles