Currently parsing Midi messages for the Firmata protocol in Rebol 3, and came across a situation I haven't seen before.
Basically, I have a generic rule to copy bytes between the framing bytes. However that rule is eating the framing bytes. I have reduced the code to the following:
data: #{
F06C00010101040E7F000101010308040E7F00010101040E7F0001010103
08040E7F000101010308040E7F00010101040E7F00010101040E7F0001010103
08040E7F000101010308040E7F000101010308040E7F00010101040E7F000101
01040E7F00010101020A7F00010101020A7F00010101020A7F00010101020A7F
00010101020A06017F00010101020A06017FF7
}
sysex-start: #{F0}
sysex-end: #{F7}
capability-query: #{6B}
capability-response: #{6C}
capability-end: #{7F}
received-rule: [
sysex-start
capability-response-rule
sysex-end
]
capability-response-rule: [
capability-response
[
capability-end |
some [copy pin 1 skip]
]
]
parse data received-rule
The issue is that some [copy pin 1 skip]
is gobbling up the sysex-end
binary.
Is there a way I can restructure the rule (without moving sysex-end
into the subrule)?
Is there a parse keyword that would help in this case of breaking out of the subrule?
(Note: I'm aware that I'm not interpreting the data according to the spec.)
You'll need to break the loop when it hits sysex-end one way or another.
You either match sysex-end each time around the loop and break when it hits, or you only match against everything which is not a sysex-end.
The first option obviously brings sysex-end into the subrule, but it seems straightforward. If I recast your problem like this:
problem-rule: [
(matched-bytes: none)
copy matched-bytes some [skip]
]
Then the first solution using the NOT keyword might be:
alternative-1: [
(matched-bytes: none)
copy matched-bytes some [
not sysex-end
skip
]
]
The second alternative will not bring sysex-end into the subrule. You make a bitset! to match everything except sysex-end (247 corresponds to hex F7):
not-sysex-end: bits: make bitset! [0 - 246 248 - 255]
alternative-2: [
(matched-bytes: none)
copy matched-bytes some [not-sysex-end]
]
I'm not familiar enough with Rebol 3 bitsets to know if there is a better way to specify this.
The second alternative here is probably better because it meets your requirement and will likely perform much faster than the first alternative.