johnk
johnk

Reputation: 1102

Using a nested rule with parse

I am trying to parse some data which is formatted as follows.

data: [a b x b x x b a a x x b b x ]

What I need it to extract the a's and b's in order and perform a different action for each a and b.

The expected output would be:

a
b
b
b
a
a
b
b
== true

I have come up with this so far, but it fails for repeated a's.

parse data [
  some [
    thru 'a (print "a")
    some [
      any [
        to 'b (print "b")
      ]
      to 'a
    ]
  ]
  to end
]

Any pointers? Thanks

Upvotes: 2

Views: 114

Answers (3)

Graham Chiu
Graham Chiu

Reputation: 4886

>> data: [a b x b x x b a a x x b b x ]
== [a b x b x x b a a x x b b x]

>> parse data [ some [ 'a (print "a") | 'b (print "b") | skip ] ]
a
b
b
b
a
a
b
b
== true

Upvotes: 4

BrianH
BrianH

Reputation: 2186

It's the to and thru, you don't really need them. Let's take advantage of R3 here and do without.

parse data [
    some [
        'a (print "a")
        any [
            'b (print "b") |
            and 'a break |
            skip
        ]
    ]
    to end
]

The and does a lookahead, and the break breaks out of the any rule. That lets you stop the inner loop when you reach the beginning of the next one.

The to and thru will skip past stuff that you don't want to skip past, and in the case of the to 'b in your code it didn't actually do anything most of the time. You were lucky that the any loop that you wrapped the to 'b in was changed in R3 to not continue if it doesn't advance, because it was not advancing.

As for your first problem, the inner some after the (print "a") should have been an any, to make it optional. The some wasn't optional so it didn't work for runs of a with no intervening data.

PARSE can be tricky, but you get the hang of it.

Upvotes: 3

I may be missing something...but isn't what you want simply:

 parse data [
     any [
         thru ['a (print "a") | 'b (print "b")]
     ]
     to end
 ]

That generates the output you request.

Upvotes: 4

Related Questions