Elan wrote:
> Nice work. (I was planning to get started on something like that myself.
Haven't had time yet.)
Thanks!
> One little bug I found (adding ?! to the first sample regex string):
> a) "noty" causes an error in
>
> > "?!" (append RegExp_Parser [noty]) |
>
> here:
> "intruder"
> [noty "ted" | "admin" | "bobr" | "andrew" | "elan" | "keith" | "cheryl" |
> "joel" | "brady" end]
> ** Script Error: noty has no value.
> ** Where: parse/all probe Exp probe RegExp_Parse
>
> Probably you meant "not". I don't think that the REBOL parse dialect
supports the word "not".
Yes ::blush:: My mistake. I plan to use complemented character sets, when
the "?!" appears.
> 2. Doesn't * mean zero or more? you appear to replace it by | none.
> > "*" (append RegExp_Parser [| none]) |
>
> That would not account for repetitive patterns. It should be replace by
something like any xxx where xxx would be whatever it is that may appear
zero or more times.
'any would work, except I couldn't think of a way to get it the right
place. "| none" would allow this.
> Come to think of it, I think regexs are a little more complicated then
this and cannot be implemented by a one-to-one mapping of regex symbols to
REBOL parse words.
>
> Let me think about it a little longer, but IMHO you will need some kind of
state machine to do it correctly.
You could well be write, but I'm hopeful. Here's what I've got so far:
RegExp_Parse: function [RegExp [string!]] [
Stack RegExp_Parser Match Match_Character Match_Characters
Parenthesis_Rules RegExp_Rules Nest
][
Stack: Stack!
RegExp_Parser: make block! 4 * length? RegExp
Match: make string! 0
Match_Character: charset [#"0" - #"9" #"A" - #"Z" #"a" - #"z"]
Match_Characters: [some Match_Character]
append RegExp_Parser [to]
Nest: head RegExp_Parser
Parenthesis_Rules: [
"|" (append Nest [|]) |
"(" (append/only Nest [] Stack/Push Nest Nest: last Nest) some
Parenthesis_Rules ")" (Nest: Stack/Pop) |
copy Match Match_Characters (append Nest Match)
]
RegExp_Rules: [
"^^" (if 'to = first probe Nest [remove head Nest]) |
"*" (append Nest [| none]) |
"?!" "(" (append Nest ["complement"]) ")" |
"|" (append Nest [|]) |
"$" (append Nest [end]) |
"(" (append/only Nest [] Stack/Push Nest Nest: last RegExp_Parser) some
Parenthesis_Rules ")" (Nest: Stack/Pop) |
copy Match Match_Characters (append Nest Match)
]
parse/all RegExp [some RegExp_Rules]
if not 'end = last RegExp_Parser [append RegExp_Parser [to end]]
RegExp_Parser
]
RegExp: func [RegExp [string!] Exp [string!]] [
parse/all probe Exp probe RegExp_Parse RegExp
]
print RegExp "^^(ted|admin|bobr|andrew|elan|keith|cheryl|joel|brady)$"
"intruder"
print RegExp "^^(ted|admin|bobr|andrew|elan|keith|cheryl|joel|brady)$"
"cheryl"
It doesn't quite work properly, the complement doesn't, and I haven't
figured out nesting of parenthesis yet.
Here's what 'stack! looks like:
>> source stack!
stack!: func [][
make object! [
Stack: make block! 0
Push: func [Item] [
append/only Stack Item
]
Pop: function [] [Item] [
if empty? Stack [exit]
Item: last Stack
remove back tail Stack
Item
]
]
]
Andrew Martin
Learning more about 'Parse and RegExp every day...
ICQ: 26227169
[EMAIL PROTECTED]
http://members.xoom.com/AndrewMartin/
-><-