How to Parse a Nested Block
[1/5] from: tim::johnsons-web::com at: 17-Sep-2001 14:50
I swear I'm as dumb as stump when it comes to parsing: but
I've got "problem" whose "solution" should enlighten me immensely.
Here 'tis:
I want to parse rebol code so that I "extract" the interface block
from a function.
The following script "isolates" the code in a block, but not if
there are inner blocks:
rule: [thru "[" copy block-contents to "]" (print block-contents)]
parse/all {["This is a block"]} rule
; returns:
This is a block
; okay, that's what I want. Cool!
parse/all {[text[string!] size[integer!]]} rule
; returns only
[text[string! ; bummer, not what I wanted
; I wanted to see: text[string!] size[integer!]
; in other words parsed to the matching closing bracket
; What else to I need to do?
TIA
Tim
[2/5] from: sterling:rebol at: 17-Sep-2001 15:39
I heavily suggest that you parse the block as a block and not a
string. In most cases this make the best sense. For instance, what
I think you want is this:
data: [some stuff that is not a block [text[string!] size[integer!]]]
; you want the parse to return: [text[string!] size[integer!]] right?
rule: [to block! copy block-contents block! (probe block-contents/1)]
parse data rule
If there is a necessity for having it be in string form it is still
possible. The problem you would be trying to solve there is of
matching brackets which has been done before and maybe somebody on
this list will post it in response.
But, why not make use of the fact that REBOL understands REBOL?
Sterling
[3/5] from: ryanc:iesco-dms at: 17-Sep-2001 15:53
The problem is that there is no recursiveness to your rule, so it is
only capable of parsing one block depth. The block, {[text[string!]
size[integer!]]}, is two deep. By ignoring any depth, should return
that value {[text[string!} since the second #"[" is blindly copied
with the 'copy 'to.
Some advice... Since your parsing rebol formatted words, load and
parse them. something like this should then work:
rule: [
any [ string! copy str (print ["purpose:" str])]
some [
word! copy wrd (print ["parameter:" wrd]) |
block! copy blk (print ["types:" blk]) |
string! copy str (print ["description:" str]) |
refinement! copy ref (print ["refinement:" ref])
]
]
--Ryan
Tim Johnson wrote:
> I swear I'm as dumb as stump when it comes to parsing: but
> I've got "problem" whose "solution" should enlighten me immensely.
<<quoted lines omitted: 19>>
> [rebol-request--rebol--com] with "unsubscribe" in the
> subject, without the quotes.
--
Ryan Cole
Programmer Analyst
www.iesco-dms.com
707-468-5400
[4/5] from: greggirwin:starband at: 17-Sep-2001 17:09
Hi Tim,
<< I want to parse rebol code so that I "extract" the interface block
from a function. >>
If the goal is to get the interface to a function, I think the easiest
way is via reflection:
fn-interface: func [f[word!]] [
first get f
]
; fn-interface 'if
fn-spec: func [f[word!]] [
third get f
]
; fn-spec 'if
; Works only on mezzanine functions
fn-body: func [f[word!]] [
second get f
]
; fn-body 'if
If the goal is to get parse to parse nested blocks, in general, then
Carl's parse-code example shows probably the best way with the use
of a recursive parse rule. Notice that blk-rule is used inside the
blk-rule definition when an left paren or left bracket is found.
REBOL [
Title: "Parse REBOL Source"
Author: "Carl Sassenrath"
File: %parse-code.r
Date: 30-May-2000
Purpose: {An example of how to parse REBOL source code.}
Category: [script util text 2]
]
parse-code: func [
"Parse REBOL source code."
text /local str new
][
parse text blk-rule: [
some [ ; repeat until done
str:
newline |
#";" [thru newline | to end] new: (probe copy/part str new) |
[#"[" | #"("] blk-rule |
[#"]" | #")"] |
skip (set [value new] load/next str probe :value) :new
]
]
]
;example: parse-code read %parse-code.r
Hope this helps,
--Gregg
[5/5] from: tim:johnsons-web at: 17-Sep-2001 16:33
Thanks to all : Stuart, Ryan and Greg. I've now got much to chew over
and will play with all code examples:
However, I guess I should mention my ultimate goal is to build
documentation for c/c++, perl, rebol and python assets, all of
which I or partners work with.
Thanks again, I'll look over all examples and see if I get
any smarter.
regards
tim
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted