Strange parse "bug"/behavior?
[1/5] from: petr:krenzelok:trz:cz at: 17-Mar-2007 12:23
Hi,
in my recent tries with REBOL parser, I mistakenly thought, that if I
want to skip one char, I need to do "skip 1", instead of "1 skip" or
skip
. But follow following code:
1)
rule: [any [copy char skip 1 (prin char)]]
parse/all "this is a test string" rule
result:
this is a test string== true
2)
rule: [any [copy char skip 1]]
parse/all "this is a test string" rule
result:
** Script Error: Invalid argument:
** Near: parse/all "this is a test string" rule
And my question is - what is going on here? Should not case 1) fail too?
How is that string is properly parsed, just because there is "(prin
char)" added, if integer 1 contained in rule is not correct?
Thanks,
-pekr-
[2/5] from: rebol-list2::seznam::cz at: 17-Mar-2007 15:26
rule: [any [copy char skip 2 (prin char)]]
parse/all "this is a test string" rule
;==
tthhiiss iiss aa tteesstt ssttrriinngg== true
so it looks that the number means to repeat the action 2 times
it's feature, not a bug
d.
PK> Hi,
PK> in my recent tries with REBOL parser, I mistakenly thought, that if I
PK> want to skip one char, I need to do "skip 1", instead of "1 skip" or
PK> "skip". But follow following code:
PK> 1)
PK> rule: [any [copy char skip 1 (prin char)]]
PK> parse/all "this is a test string" rule
PK> result:
PK> this is a test string== true
PK> 2)
PK> rule: [any [copy char skip 1]]
PK> parse/all "this is a test string" rule
PK> result:
PK> ** Script Error: Invalid argument:
PK> ** Near: parse/all "this is a test string" rule
PK> And my question is - what is going on here? Should not case 1) fail too?
PK> How is that string is properly parsed, just because there is "(prin
PK> char)" added, if integer 1 contained in rule is not correct?
PK> Thanks,
PK> -pekr-
[3/5] from: petr::krenzelok::trz::cz at: 17-Mar-2007 15:40
rebOldes wrote:
> rule: [any [copy char skip 2 (prin char)]]
> parse/all "this is a test string" rule
> ;> tthhiiss iiss aa tteesstt ssttrriinngg== true
>
> so it looks that the number means to repeat the action 2 times
> it's feature, not a bug
>
> d.
>
ahh, now I see - I wondered WHAT action should it repeat - now I see -
the paren block action, because:
>> rule: [any [copy char skip 2]]
== [any [copy char skip 2]]
>> parse/all "this is a test string" rule
** Script Error: Invalid argument:
** Near: parse/all "this is a test string" rule
-pekr-
[4/5] from: pwawood:gmai:l at: 17-Mar-2007 22:55
Hi Petr
I'm no expert but perhaps the following examples will help a little
> 1)
> rule: [any [copy char skip 1 (prin char)]]
> parse/all "this is a test string" rule
>
> result:
> this is a test string== true
>> alphaorspace: charset [#"a" - #"z" #"A" - #"Z" #" "]
== make bitset! #{
0000000001000000FEFFFF07FEFFFF0700000000000000000000000000000000
}
>> rule: [any [copy char alphaorspace (prin char) skip]]
== [any [copy char alphaorspace (prin char) skip]]
>> parse/all "this is a test string" rule
ti sats tig== false
My understanding of this rule is:
1. any tells parse to look for zero or more occurrences of the pattern
in the following block
2. the pattern in the block is a single alphaorspace followed by a skip.
3. if the pattern is found, parse will copy the character that matches
alphaorspace into the "variable" char and execute the rebol code
enclosed in parentheses.
4. It will then look for the next pattern to match that in the block
until it doesn't find one of it reaches the end of the string.
If we change the rule slightly to put the code after the skip, we get :
>> rule: [any [copy char alphaorspace skip (prin char)]]
== [any [copy char alphaorspace skip (prin char)]]
>> parse/all "this is a test string" rule
ti sats ti== false
My understanding of the subtle change, the "g" of string is not printed
is that with this rule parse reached the end of the string after the
g
so the skip didn't "match" so the code in parentheses was not
executed.
Putting skip before the copy char alphaorspace gives:
>> rule: [any [skip copy char alphaorspace (prin char)]]
== [any [skip copy char alphaorspace (prin char)]]
>> parse/all "this is a test string" rule
hsi etsrn== false
Probably what we expected.
If we only look for alpha characters instead of alpha or spaces, we get
the following result:
>> alpha: charset [#"a" - #"z" #"A" - #"Z"]
== make bitset! #{
0000000000000000FEFFFF07FEFFFF0700000000000000000000000000000000
}
>> rule: [any [copy char alpha (prin char) skip]]
== [any [copy char alpha (prin char) skip]]
>> parse/all "this is a test string" rule
ti== false
As I understand:
1. parse matches "th" and prints "t"
2. parse matches "is" and prints "i"
3. parse cannot match the space so stops.
> And my question is - what is going on here? Should not case 1) fail
> too?
> How is that string is properly parsed, just because there is "(prin
> char)" added, if integer 1 contained in rule is not correct?
I'm afraid I couldn't work out why case 1 worked either.
Regards
Peter
[5/5] from: petr:krenzelok:trz:cz at: 17-Mar-2007 16:44
Peter,
thanks for the input, but I already found out, why or why my case did
not work:
rule: [any [copy char skip 1 (prin char)]]
... simply means, that 0 or more times 1 char is copied into 'char word.
What does 1 mean here is - perform 1-time what follows = (print char).
Let's verify it:
rule: [any [copy char skip 5 (prin char)]]
parse/all "this is a test string" rule
results in:
ttttthhhhhiiiiisssss iiiiisssss aaaaa
ttttteeeeesssssttttt ssssstttttrrrrriiiiinnnnnggggg== true
Simply the rule will perform paren (rebol code) given number of times,
which is 5 times here. I did not expect it being possible, as I did not
consider paren being a typical part of parse dialect ....
But thanks for the input.
Petr