PARSE: how to terminate an iteration

Carl Sassenrath, CTO
REBOL Technologies
10-Oct-2009 3:02 GMT

Article #0268
Main page || Index || Prior Article [0267] || Next Article [0269] || 8 Comments || Send feedback

In parse code like this:

parse "a" [some ["a" | none (do something)]]

what causes the SOME loop to terminate? There are three possible choices:

  1. the input has ended
  2. the input has not advanced
  3. just keep looping until failure

In prior versions (up through A87) the first choice was used. But, our friend Ladislav submitted CureCode ticket #1268, a claim that iterated and recursive cases were not equivalent. And as usual, he was correct.

The problem is that the iteration will not even be attempted if the input has ended. So the "do something" never happens.

The third choice, which is technically "the most correct" can be pretty harsh. If you don't provide an explicit termination, and one of the rule alternatives is true, it loops forever. So, the line above would loop forever.

To fix it, you would need to change the line to:

parse "a" [some ["a" | none (do something) fail]]

So, that means that many of your existing parse rules would hang, because they do not include that FAIL keyword.

In A88 I'm testing an alternative: choice #2 above.

Technically, there is "an implied requirement" that at least one of the rules in a block match the input, otherwise the rule has failed. Therefore, a test can be made to determine if the input has advanced by the end of the rule block, and if not, terminate the loop.

This is a fairly easy condition to handle and for most coders to remember. It keeps our code easy-to-write and prevents code that would become an infinite loop.

Of course, I am quite certain that Ladislav the logic guru will be able to produce an example that shows why the A88 solution is not precisely correct... So, we may need to return to this issue at some later date and weigh the issue of usability.


Updated 21-Mar-2017 - Edit - Copyright REBOL Technologies -