[REBOL] Re: Extracting a date..
From: joel:neely:fedex at: 12-May-2001 9:00
Hi, PeO,
Graham has already given you a suggestion for a replacement script.
Let me suggest the reason why your efforts below didn't succeed.
P-O Yliniemi wrote:
...
> The part of the file I want to read from looks like:
>
> fdata: {
> ----------------------------------------------------------------------------
> Some other text here
> May 11 2001
> Some other text here
> ----------------------------------------------------------------------------
> }
>
...
> Setting up a rule for the date format:
>
> digit: charset [#"0" - #"9"]
> mon-abbrev: ["jan" | "feb" | "mar" | "apr" | "may" | "jun" |
> "jul" | "aug" | "sep" | "oct" | "nov" | "dec"]
> date-rule: [mon-abbrev some #" " 1 2 digit some #" " 4 digit]
>
> then.. the problem begins..
>
> >> date: copy "" parse fdata [to date-rule copy date to "^/" to end] print date
> ** Script Error: Invalid argument: mon-abbrev some 1 2 digit some 4 digit
> ** Near: parse fdata [to date-rule copy date to "^/" to end]
>
Contrary to your (quite understandable) expectation, TO does not
like to be
applied to a sub-rule. TO wants to be told *exactly* what to look
for.
> >> date: copy "" parse fdata [to "may" copy date to "^/" to end] print date
> May 11 2001
>
This succeeds because TO now has a literal string for which to
search.
> >> date: copy "" parse fdata [[to "may" | "jun"] copy date to "^/" to end] print date
> May 11 2001
>
This succeeds, but only accidentally. Think of TO has having higher
precedence
than | in your first sub-rule. Parse actually matches that sub-rule
only if:
it can scan forward and find the literal (sub-)string "may"
or
it can *immediately* (at the present location) find the literal
(sub-)string "jun"
> >> date: copy "" parse fdata [[to "apr" | "may" | "jun"] copy date to "^/" to end]
print date
> (nothing)
>
This illustrates the preceding point further, because the initial
sub-rule now is
looking for
"apr" *somewhere* forward from this point (including here)
or
"may" *right here*
or
"jun" *right here*
The same restrictions apply to THRU, as you can see from the
simplified
example below, which tries to find the segment of a string that is
bounded within either parentheses or angle brackets:
>> test-string: {some words go (inside here) and later}
== "some words go (inside here) and later"
>> open-delim: ["<" | "("]
== ["<" | "("]
>> close-delim: [">" | ")"]
== [">" | ")"]
>> result: ""
== ""
>> big-rule: [to open-delim copy result thru close-delim to end]
== [to open-delim copy result thru close-delim to end]
The above BIG-RULE is similar to what you had, in that it tries to
apply both TO and THRU to sub-rules which contain alternatives...
>> parse/all test-string big-rule
** Script Error: Invalid argument: < | (
** Where: halt-view
** Near: parse/all test-string big-rule
... with no better luck than you had. So, let's try explicitly
describing the "scan forward for..." alternatives.
>> to-open-delim: [to "<" | to "("]
== [to "<" | to "("]
>> next-rule: [to-open-delim copy result thru close-delim to
end]
== [to-open-delim copy result thru close-delim to end]
>> parse/all test-string next-rule
** Script Error: Invalid argument: > | )
** Where: halt-view
** Near: parse/all test-string next-rule
Aha! We got past the TO open delimiter, but then ran into the same
kind
of limitation with the THRU closing delimiter. So, we fix that.
>> thru-close-delim: [thru ">" | thru ")"]
== [thru ">" | thru ")"]
>> last-rule: [to-open-delim copy result thru-close-delim to
end]
== [to-open-delim copy result thru-close-delim to end]
>> parse/all test-string last-rule
== true
>> result
== "(inside here)"
> What should I change to make this work?
>
Never use TO or THRU on compound sub-patterns. Either "distribute"
the
TO or THRU across the options (as done in the dinky example above),
or
explicitly say "skip forward until you can match this sub-rule" as
Graham's rewrite did.
> The first try which returned the script error seems to be the most
> logical one...
>
Ah, but as we've been discussing lately (under the topic of
scope
),
things are not always what they "seem to be" in the REBOL universe.
;-)
Hope this helps!
-jn-