[REBOL] Re: coding the closing parentheses correctly
From: moliad::gmail at: 1-May-2008 16:06
parse is very flexible.
in your example, I used parse recursively (calling parse within parse
rules), because the counts are given within the data, its easier to do
it this way. We could have done it differently using just one parse
call, a stack, and words for the counts, but then, its pretty
complicated to make.
one thing to know is that parse only works on string and block types,
so you have to convert your binary into a string first.
are you parsing EDI data?
another detail is that rebol only supports signed 32 bit ints, so you
are effectively limited to a length of 31 bits for your lists.
here is the code to solve your specific needs if you look at the
difference between my previous example and this one, I think you'll be
able to see how to expand on this one.
note that the code below expects input to be valid and does no kind of
error checking whatsoever. if input data is bad, its possible that the
parser will stop, its also possible that a voluntary malign
construction would let parser go into infinite loops. This is not to
say that I see a place where such an infinite loop is possibe, only
that sometimes, the parser ends up doing so when no time is spent
making sure the rule is bullet-proof.
if you are acting on unverified user-input, you might want to verify
things like the count values, or other anomalies, and throw an error
with make error!
HTH :-)
-MAx
;---------------------------------8<--------------------------------
TUPLE: to-string #{68}
LIST: to-string #{6C}
NULL: to-string #{6A}
STRING: to-string #{6B}
load-container: func [
str
/local entity cursor output count data
][
output: copy ""
; recursive parse rule
entity: [
[
LIST copy count 4 skip
cursor: ; where do we start parsing next depth
(
count: to-integer to-binary count
append output "["
)
; the count for the entity rule was set dynamically
count entity
(
remove/part skip tail output -2 2 ; remove trailing ", " we are at
end of a container
append output "], "
)
:cursor ;continue where recursive parses left-off
NULL
cursor:
] |
[
TUPLE copy count skip
cursor: ; where do we start parsing next depth
(
count: to-integer to-binary count
append output "{"
)
; the count for the entity rule was set dynamically
count entity
(
remove/part skip tail output -2 2 ; remove trailing ", " we are at
end of a container
append output "}, "
)
:cursor ;continue where recursive parses left-off
] |
[
STRING copy count 2 skip (
; here we change the count for the rule dynamically
count: to-integer to-binary count
)
copy data count skip
cursor: ; where do we continue parsing after these items
(
append output join data ", "
)
]
]
parse/all str entity
remove/part skip tail output -2 2 ; remove trailing ", " we are at
end of a container
return output
]
load-container to-string #{
6C000000046B0001436B000244456C000000026B0001436B000244456A68046B
0001436B000244456C000000026B0001436B000244456A68026B0001436B0002
44456A}
== "[C, DE, [C, DE], {C, DE, [C, DE], {C, DE}}]"
;---------------------------------8<--------------------------------
On Thu, May 1, 2008 at 1:23 PM, DougEdmunds <dougedmunds-gmail.com> wrote: