[REBOL] Re: A little parse help
From: lmecir:mbox:vol:cz at: 26-Aug-2001 1:39
Hi,
> I have been implementing my own document language. The main difference
> is that it is a natural language and the lack of this parsing feature is
> making my work Extremely complicated.
>
> That is because I do not want to impose strict format structure... so I
> do not know if the document writer is going to end his line right away
> or if he wishes to continue on the same line or if he'll put a space or
> two, or put a space just before the end of the line...
>
> Add to this the fact that the keywords themselves are plain english (or
> any other language, in fact :-) and ARE allowed within the content
> itself and it makes the parsing a little bit harder still!
>
> This parsing feature alone would have cut my development time in half at
> least!
>
here is my solution:
cfunc: function [
{make a closure}
[catch]
spec [block!]
body [block!]
] [locals in-new-context spec2 body2 i] [
locals: copy []
spec2: copy [[throw]]
body2: reduce ['do 'func spec2 body]
i: 1
repeat item spec [
if all [any-word? :item not set-word? :item] [
append locals to word! :item
append spec2 reduce [to word! :item [any-type!]]
append body2 reduce ['get/any 'pick 'locals i]
i: i + 1
]
]
in-new-context: func [
{do body with locals in new context}
[throw]
locals
] body2
throw-on-error [
func spec reduce [:in-new-context locals]
]
]
a-b: cfunc [
{Generate an A-B parse rule}
a [block!]
b [block!]
/local finish
] [
[
[
b (finish: [to end skip]) |
(finish: a)
]
finish
]
]
comment {
Example:
a: [any "a" "b"]
b: ["aa"]
parse "ab" a-b a b
parse "aab" a-b a b
}
not-rule: cfunc [
{Generate a not A parse rule}
a [block!]
/local finish
] [
[
[
a (finish: [to end skip]) |
(finish: [])
]
finish
]
]
comment {
Example:
a: [any "a" "b"]
parse "ab" not-rule a
parse "b" not-rule a
parse "" not-rule a
}
to-rule: cfunc [
{generate a to A parse rule}
a [block!]
/local nxt finish
] [
[
(
finish: [to end skip]
nxt: [skip]
)
any [a (nxt: [to end skip] finish: []) nxt | nxt] finish
]
]
comment {
Example:
space-or-br: to-rule [" " | "<br>"]
result: ""
parse/all "aa" [space-or-br copy result to end]
probe result
parse/all "a a<br>" [space-or-br copy result to end]
probe result
parse/all "ab<br> " [space-or-br copy result to end]
probe result
}