r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[I'm new] Ask any question, and a helpful person will try to answer.

Henrik
30-Apr-2009
[1949x2]
Because the contents of a function is really a context, and once 
that function is created, it doesn't disappear, including the blocks 
and series that are existing in that function. (We have to be careful 
here about using the word "context" to describe what we say, and 
the concept of "contexts" in REBOL. Don't mix it up.)
The document you link to is exactly that phenomenon. It's both fundamental 
and very useful in REBOL for many things.
mhinson
30-Apr-2009
[1951]
to store a dynamic value called by several parts of the code perhaps?
Henrik
30-Apr-2009
[1952]
It's not a unique phenomenon. It's everywhere in REBOL.
Sunanda
30-Apr-2009
[1953]
It is initially confusing, because the apparent strange behaviour 
is limited to series, not (not sure what the official term is) numbers.

If you try this:
f: func [a /local b c] [b: [] c: 0 append b a c: c + a]
f 1
f 2
source f


You can see that (quite literally, in a metaphorical sense) the in-memory 
copy of function f has been changed:
f: func [a /local b c] [b: [] c: 0 append b a c: c + a]
f 1
f 2
source f


To not have it change in that way (or to re-initialise b, if you 
like):
f: func [a /local b c] [b: COPY [] c: 0 append b a c: c + a]
f 1
f 2
source f

But 'c has not changed in either case:
  c: 0
means exactly what it says.
mhinson
1-May-2009
[1954]
I have a reasonable understanding of functions now thanks to all 
your help. 


Now I have decided to have another go at understanding parsing & 
what I have picked up in more general terms seems to have helped 
my understanding of the documentation a bit better.  The question 
I am trying to solve at the moment is: Is there a straight forward 
way to extract the string "two.txt" from the following string {randomXXXrandom.log 
XXXrandom.txtrandom}  

My limited skills let me extract from the first XXX to .txt, but 
not from the XXX that preceeds the .txt alone.
Pekr
1-May-2009
[1955]
what do you mean by "two.txt"? I can't see it in your string ...
mhinson
1-May-2009
[1956]
I changed my string... doh...  it is "random.txt" now
Graham
1-May-2009
[1957]
what's a sample of what you are trying to do ?
mhinson
1-May-2009
[1958x4]
{randomXXXrandom.log XXXrandom.txtrandom}   is the testing string 
& I am trying to extract only the string after XXX which ends with 
.txt
using parse ... as a learning exercise.   so the only way I can identify 
the string I want is by what comes after it, but it must be before 
the next occurance of XXX
if it was a regular expression it would be something like XXX[a-z]*\.txt
I cant see a way to make the parse function be non-greedy, perhaps 
I just need to look at this in a different way all together? This 
is the sort of thing I have been trying that dosen't work.
spacer: charset reduce [tab newline #" "]
non-space: complement spacer

probe parse/all {randomXXXrandom.log XXXrandom.txtrandom} any [to 
"XXX" copy result thru non-space to ".txt"]
print result
Maxim
1-May-2009
[1962]
parse is entirely different from regexp.  it works by supplying grammar, 
where as regexp thinks in terms of patterns.. this may sound similar, 
but in detail its very different.
Gregg
1-May-2009
[1963]
If you want to be non-greedy, you may need to use alternate rules 
and skip. e.g.

s: {randomXXXrandom.log XXXrandom.txtrandom}
parse/all s [
    any [
        "XXX" mark-1:
        | [mark-2: ".txt"] (
           if all [mark-1 mark-2] [print copy/part mark-1 mark-2]
        )
        | skip
    ]
]
Maxim
1-May-2009
[1964]
I was used to regexp, when I used to program in python in particular, 
and that probably is one of the reasons I had soooo much of a hard 
time grasping parse (even after years of trying)
Gregg
1-May-2009
[1965]
Yes, parse and regex are more different than alike. Parse is not 
designed to be concise. :-)
Maxim
1-May-2009
[1966]
no its designed to be understandable beyond the second rule   ;-)
Gregg
1-May-2009
[1967]
:-)
Maxim
1-May-2009
[1968]
mike: the best tip I can give you is to picture a cursor in your 
head when you type your rules.  parse really is about iterating over 
a series on byte at a time and matching the next expected characetr.
Gregg
1-May-2009
[1969]
My example above may not be exactly what you want. e.g. you might 
want to clear mark-1: in the skip rule.
Maxim
1-May-2009
[1970x6]
whenever it doesn't find what it expects, it "rolls back" to the 
last complete finished rule and tries the next one, if an alternative 
was given.  this is hiercharchical.  so if youre inside the 15th 
depth of parse ans suddenly an unexpected character is encountered, 
you might roll back up to the very first rule!
if that is the first alternative given within the parse rules.
since it only moves forward, its very fast.  in order to do look 
ahead assertion and things like that (which are slow in regexp anyways) 
you must learn a few tricks in order to manually set and retrieve 
the "current" character index.
also note that when there is a "roll back", the cursor and rules 
rolls back together.  (unless you are doing manual cursor manipulation 
tricks)
so if your first rule only matched 2 characters, the second one fails, 
and other alternative is given... the alternative effectively starts 
checking at character 3
even if the second rule failed 15 rules deep at character 3000
Graham
1-May-2009
[1976x5]
I presume that .txt is not going to appear in the 'random' text?? 
 And XXX is really a fixed set of characters?
this is a cheat ...

>> s: {randomXXXrandom.log XXXrandom.txtrandom}
== "randomXXXrandom.log XXXrandom.txtrandom"

>> parse/all reverse s [ to "txt." copy txt to "XXX" ( reverse txt 
) to end ]
== true
>> txt
== "random.txt"
that's for those of us who don't like to backtrack :)
or if .log neve appears in the random text you can just skip past 
it
>> parse/all s [ thru ".log" thru "XXX" copy txt thru ".txt" to end 
]
== true
>> txt
== "random.txt"
PeterWood
2-May-2009
[1981]
I usually adopt a different approach which is to write a rule to 
match my target and use any and skip to apply that rule progressively 
through the input. It may not be the fastest way but it seems easier 
to grasp than backtracking.

>> haystack: {randomXXXrandom.log XXXrandom.txtrandom} 
>> alpha: charset [#"a" - #"z" #"A" - #"Z"]  

== make bitset! #{
0000000000000000FEFFFF07FEFFFF0700000000000000000000000000000000
}
>>   digit: charset [#"0" - #"9"

]
== make bitset! #{
000000000000FF03000000000000000000000000000000000000000000000000
}

>>   alphanumeric: union alpha digi

t
== make bitset! #{
000000000000FF03FEFFFF07FEFFFF0700000000000000000000000000000000
}
 
                             
>> needle: ["XXX" some alphanumeric 
".txt"]    

>> parse/all haystack [any [copy result needle (print skip result 
3) | skip]]

random.txt

== true


As you can see with this approach, you have to manually extract the 
"XXX" once you've grasped the needle.
mhinson
2-May-2009
[1982]
You may be surprised to hear that I understand what you are all saying. 
 I was sort of already begining to draw my own conclusion that the 
answer to my problem might not be as trivial as I wanted it to be. 
 I think this mini tutorial on parse for people with an understanding 
of regular expressions would be very handy for others, could the 
essence of your replies be put somewhere that they will be found 
by other newbies? What fun this is, thanks for the continued help.
Sunanda
2-May-2009
[1983x3]
Mike, this group has [web-public] in its title, meaning it is being 
published to the web.
So the replies are available online for anyone.
http://www.rebol.org/aga-display-posts.r?post=r3wp174x1957
A tutorial to put it all in content would be even better.
If you have not found it already, this is a detailed tutorial on 
'parse, building up slowly from the basics:

http://en.wikibooks.org/wiki/REBOL_Programming/Language_Features/Parse
And this gives you easy access to many useful mailing list threads 
-- often containing "worked examples" in answer to specific problems:
http://www.rebol.org/ml-topic-index.r?i=parse
mhinson
2-May-2009
[1986]
I am becoming dispondent today because although I now feel I understand 
some very usefull concepts & have all these great links to documentation, 
I still stumble over the syntax of very basic things. e.g this is 
wrong & one of dozens of different ways I have tried to arange the 
brackets & quote marks.  It is frustrating to spend an hour or so 
making no progress at all on something I know must be obvious.

result: []  

parse/all {zabc} [ to ["b" | "y"] copy result thru "c"  (print result) 
]

parse/all {zybc} [ to ["b" | "y"] copy result thru "c"  (print result) 
]
Izkata
2-May-2009
[1987]
Put the 'to inside the block, like this:

parse/all {zabc} [ [to "b" | to "y"] copy result thru "c"  (print 
result) ]


IIRC, your syntax has been a long-standing request to improve 'parse
mhinson
2-May-2009
[1988]
Thanks Izkata, the is exactly the help I needed.  Since I failed 
to find the information about this in the documentation I thought 
I would try & find it now I know the answer, but I still can't.  
Should it be infered from some basic principle I have missed?  Or 
am I just bad at searching the documents?
Pekr
2-May-2009
[1989x2]
to "b" | to "y" might not work as you would expect though. Better 
check what you are expecting, because you should really read it as 
- try to locate "b", and in the case you will not find it, try to 
locate "y". It simply does not mean find first occurance of "b" or 
"y", return the first match ...
Such functionality is long time request to parse enhancement, and 
is planned to be implemented ...
mhinson
2-May-2009
[1991]
Pekr, I see now this is the same newbie trap you pointed out to me 
over 2 weeks ago. Difference is that this time I understand what 
you mean. (i hope).

I think I need to study backtracking now.  I just discovered this 
discussion that seems very helpfull on the subject.

http://www.mail-archive.com/[list-:-rebol-:-com]/msg03371.html  I wonder 
if I should start using Rebol 3 ?  does it have this enhancement 
yet? is it stable enough for educational use would you say? or is 
is really only the domain of testers as yet?  Thanks.
Pekr
3-May-2009
[1992x2]
no R3 parse enhancement is implemented yet, but they are planned 
for R3.0 beta release, so hopefully they come. I am not sure Carl 
will implement all of them, but maybe he will. You can look at it 
here - http://www.rebol.net/wiki/Parse_Project
Here's my version:


parse/all {zybc} [ some ["b" break | "y"  break | skip] copy result 
thru "c"  (print result) ]


Simple explanation - we try to match at least one occurance of "b" 
or "y. There is currently no other chance than skip by one char (don't 
worry, it is not slow). Once you reach the char, you have to "break", 
or the rule will be still applied, because "skip" will always occur, 
even if "b" or "y" are not matched.
mhinson
3-May-2009
[1994]
Hi, I have been studying the example from Pekr and developed the 
following addaptation.

b: [to "bb" break]
y: [to "yy" break]

parse/all {zyybbc} [ some [b | y  break | skip] copy result thru 
"c"  (print result) ]


however this seems to loop for ever, but I don't understand why. 
Any wise words would be appreciated.  Sorry to be so needy, I am 
begining to wonder that as I am having so much trouble with this 
basic stuff, perhaps this is a programing language that I am just 
not suited to?  Let me know if I am causing a problem by posting 
here so often & I will admit defeat with the parsing & go back to 
something more familiar.s
[unknown: 5]
3-May-2009
[1995]
what are you trying to accomplish?
mhinson
3-May-2009
[1996]
I am really trying to learn the parse grammer rules, but they trip 
me up at every turn.
[unknown: 5]
3-May-2009
[1997]
There is some gotchas but practice is key to them.
mhinson
3-May-2009
[1998]
the example from Pekr was to show me how to backtrack in order to 
make the ["b" | "y"] construct work in way that is non-greedy, that 
is to say so it finds the first occurance of either.