目前正在为Rebol 3中的Firmata protocol解析Midi消息,并遇到了我以前见过的情况。
基本上,我有一个通用规则来复制成帧字节之间的字节。然而,该规则正在吃帧化字节。我已将代码缩减为以下内容:
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
问题是some [copy pin 1 skip]
正在吞噬sysex-end
二进制文件。
我有没有办法重组规则(不将sysex-end
移到子规则中)?
是否有一个解析关键字可以帮助解决这个问题?
(注意:我知道我没有根据规范解释数据。)
答案 0 :(得分:3)
当它以某种方式击中sysex-end时,你需要打破循环。
你可以在循环中每次匹配sysex-end,在命中时匹配,或者只匹配不是sysex-end的所有内容。
第一个选项显然将sysex-end引入了子规则,但它似乎很简单。如果我像这样重塑你的问题:
problem-rule: [
(matched-bytes: none)
copy matched-bytes some [skip]
]
然后使用NOT关键字的第一个解决方案可能是:
alternative-1: [
(matched-bytes: none)
copy matched-bytes some [
not sysex-end
skip
]
]
第二种选择不会将sysex-end引入子规则。你搞砸了!匹配除sysex-end之外的所有内容(247对应于十六进制F7):
not-sysex-end: bits: make bitset! [0 - 246 248 - 255]
alternative-2: [
(matched-bytes: none)
copy matched-bytes some [not-sysex-end]
]
我对Rebol 3位集不够熟悉,知道是否有更好的方法来指定它。
这里的第二种选择可能更好,因为它符合您的要求,并且可能比第一种选择更快。
答案 1 :(得分:2)
你可以(至少在Rebol2中)使用
pin-set: complement charset to-string #{F7}
received-rule: [
sysex-start
capability-response-rule
sysex-end
]
capability-response-rule: [
capability-response
[
capability-end |
some [copy pin pin-set ]
]
]
parse data received-rule
== true