AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 5907 |
r3wp | 58701 |
total: | 64608 |
results window for this page: [start: 32901 end: 33000]
world-name: r3wp
Group: I'm new ... Ask any question, and a helpful person will try to answer. [web-public] | ||
Henrik: 24-May-2009 | Something more basic, that you may have skipped or forgotten: Contexts are just objects. They are just a clumped together set of words with values. The big secret is revealed here: >> source context context: func [ "Defines a unique (underived) object." blk [block!] "Object variables and values." ][ make object! blk ] So when you make a new object, you make a new context. The definition block (shown as blk in the source for context) is then bound to this new context. You can run ordinary REBOL code inside the object definition block. You are not restricted to the obvious syntax of set-word! and value pairs: d: make object! [ b: "hello" reverse b ] d/b == "olleh" Of course after the definition block has been parsed to become an object, only the key/value pairs remain. Remember that and you can get very far with contexts. | |
mhinson: 24-May-2009 | I think I have understood what it is that has been preventing me from understanding BIND. I was expecting BIND to make a persistant difference to the contexts, but now I have realised that is not the case, it only acts as a function to return information when it is called. That was a tough one to fight through. However, now I understand Henrik's example, but the example in the manual still confuses me. words: [a b c] fun: func [a b c][print bind words 'a] ;; why is this not ... print bind words 'a 'b 'c] Does this mean that bind causes fun to be joined to the context of words, for all the variables used in the words context? I think I am also still confused about which direction the context moves. Sorry to be asking again, but I do want to understand this completely. In Henrik's example it seems to be "do b in the context of c" but in the manual example it seems more like "print words (which in the global context ) as if the context variables of words had been assigned the values of the current context.... I am off to bed now to sleep on it. Thanks. | |
mhinson: 25-May-2009 | I see the bind function can do both the things I noticed above. I have stalled with reading Ladislav's Bindology paper at section 9.1 I dont understand what a-word has become, and why. I dont understand how 'a might be referenced in bind 'a a-word as it has no mention in the example, so I dont understand what is being demonstrated. | |
Steeve: 25-May-2009 | words: [a b c] ;** words, a, b, and c belong to the global context. fun: func [a b c][print bind words 'a] ;** 'it is asked to change the context of the words comprise in the block "words". ;** After that, they are not belonging to the global context anymore, but to the context of the function. | |
mhinson: 25-May-2009 | Thanks Steeve, I think bind is becoming a bit clearer to me. Your comments seem to make sense to me now. | |
BrianH: 25-May-2009 | Words are immediate values, so BIND returns a new value when passed a word. BIND changes blocks passed to it, but BIND/copy changes a deep copy. The words in blocks are replaced with new words that have the same symbol but a different binding. | |
Steeve: 27-May-2009 | missing a reduce, pal | |
Henrik: 28-May-2009 | the alternative is compose which offers a /deep refinement: creature: compose/deep [(to-word animal) [(named) [(breed)]]] and all parts you wish to compose in the block must be wrapped in ()'s. | |
mhinson: 28-May-2009 | That is very cool... And I feel happy that I predicted there might be a thing that did that too... it is much more elegant than lots of reduce statements everywhere. Thanks. | |
Graham: 28-May-2009 | Compose wasn't there in the beginning ... it was a later add on because of these issues | |
mhinson: 29-May-2009 | Hi, I have been trying for the last hour or two to get this code to behave in the way I want. data: { thing toy owner child thing house owner adult } thing: copy [] owner: copy [] StructuredData: copy [] parse/all data [ any [ ["thing " copy thing to newline (append StructuredData reduce[to-word thing[]])] |[" owner " copy owner to newline (append StructuredData/(to-word thing) compose/deep [owner[(owner)]])] | skip ] ] probe StructuredData [toy [owner ["child"] owner ["adult"]] house [owner ["child"] owner ["adult"]]] My problem is that the toy & the house are owned by the child & the adult. It seems the things are linked to each other in a way I dont follow. If I assign the values directly, rather than using the parse, then the StructuredData contains what I expect. [toy [owner ["child"]] house [ owner ["adult"]]] | |
Chris: 29-May-2009 | Your problem is this line: ["thing " copy thing to newline (append StructuredData reduce [to-word thing []])] Specifically this part: reduce [to-word thing []] The last block here is never copied. When you append your data with the reduced block, the owners block is always the same (as in 'same?) block. You need to create a new block each time: reduce [to-word thing copy []] or reduce [to-word thing make block! 5] ; 5 is arbitrary | |
mhinson: 30-May-2009 | Thanks Chris. There are several things I have learnt from this: COPY has more varied use than I was aware of. In this case I think COPY is making sure I am adding a unique empty block, rather than a link to this one. I still cant quite get my head round an empty block being something that can be referenced again later, although I know I have read about it previously & know it is important. Why do I not seem to need COPY in my following example? StructuredData: copy [] thing: copy "toy" append StructuredData reduce[to-word thing[]] owner: copy "child" append StructuredData/(to-word thing) compose/deep [owner[(owner)]] thing: copy "house" append StructuredData reduce[to-word thing[]] owner: copy "adult" append StructuredData/(to-word thing) compose/deep [owner[(owner)]] probe StructuredData [toy [owner ["child"]] house [owner ["adult"]]] | |
Chris: 30-May-2009 | mh: In the case above, when you were using 'reduce, you were evaluating the first block, in which the second block is just a value. When you evaluate a block value, it is not in turn evaluated: >> [i'm not code] == [i'm not code] It's important to remember when you do some deeper evaluation: >> code: [[]] ; block containing a block value == [[]] >> append code/1 'a ; modify block value == [a] >> result: do code ; evaluate block, block value returned - now referenced by 'result == [a] >> append code/1 'b ; modify block value == [a b] >> result ; result is referencing the same value == [a b] >> append result 'c == [a b c] >> code == [[a b c]] Every value in REBOL is merely referenced to by the language. Sometimes explicitly: result: [] probe result Or not: code: [[]] probe code/1 Or both: code: [[]] result: code/1 probe same? code/1 result | |
mhinson: 30-May-2009 | Thanks Chris, Graham, Izkata I feel like I half get this, but not well enough to be confident yet. I have been trying to create a really simple example where two parts of the same block are really the same items, so changing either, changes both because I think it will help me understand better & that was the behaviour in my original example. Perhaps if I study this for another couple of hours I will get a breakthrough with it. Thanks. | |
Chris: 30-May-2009 | Such as?: >> attr: [] == [] >> cont: reduce [attr attr] == [[] []] >> insert attr 'c == [] >> insert first cont 'b == [c] >> insert second cont 'a == [b c] >> cont == [[a b c] [a b c]] | |
Izkata: 30-May-2009 | Try this: Predict the output of these function calls: foo: func [/local A B][ A: [] B: copy [] print mold append A {a} print mold append B {b} ] foo foo foo | |
mhinson: 31-May-2009 | ;Thanks Izkata, I predicted the outcome correctly. I went on to try this: D: [{bar}] ;; global D foo1: func [D][D: [] print mold append D {d}] ;; foo2: func [D][D: [] print mold append D {d}] ;; foo1 D ;; value of global D passed to function (but not used) foo1 D ;; function references its own local value of [] to which it keep appending {d} foo2 D ;; same as foo1 but references its own [] ?pointer? thing D ;; still references un changed global D foo1: func [D][D: [] print mold append D {d}] ;; rewriting foo1 foo1 D ;; new foo1 function has new [] pointer foo3: func [][D: [] print mold append D {d}] ;; D is not passed to the function Foo3 ;; now we are changing global D and making it reference foo3 [] pointer D ;; proof global D has changed ;; I think the bit that was making it hard for me to understand was that ;; referencing the same empty block in a function means the actual exact function, ;; a second copy of it even with the same name, sets up a new local pointer. And also the unexpected localness confused me. ;; Question, do my comments show that my understanding is now correct please? | |
mhinson: 31-May-2009 | What is the length limit for a comment line please? some of my comment lines are being intrepreted. I think it is the length of them. | |
mhinson: 31-May-2009 | no, just ;; in front of a few very long lines. | |
mhinson: 31-May-2009 | it is like that because I have a bunch of lines that will become a function & I am comparing them in some cases, and excludeing them in other cases to debug my code. | |
Graham: 31-May-2009 | and you only need a single ; | |
mhinson: 31-May-2009 | Those lines I posted still do strange stuff with a single ; at the beginning. Could it be a bug with the console? I do 2 ;; to make them stand out more, although syntax highliting does that already. Thanks. | |
Sunanda: 1-Jun-2009 | A tip I picked up off of the Mailing List years ago (thanks to whoever it was) doc: does [do clipboard] then you need to just type doc to DO Clipboard:// | |
mhinson: 3-Jun-2009 | Hi, is thre a neater way to do this please an avoid so many reduce statements please? QQ: [] func1: func [o1] [append QQ copy/deep reduce [reduce o1 reduce reduce [reduce o1]]] owner: "Luke" func1 'owner [owner ["Luke"]] | |
Sunanda: 4-Jun-2009 | Multiple copies of REBOL is a pain that several of us have. | |
Graham: 4-Jun-2009 | It's a result of programming with Rebol which tells us to use 'copy to be safe | |
mhinson: 4-Jun-2009 | With the shortcut to do clipboard:// it complains if there is no rebol[] header. Do folk only use it for bigger blocks of code, rather than a few lines that need testing? As I suppose pasting it straight into the console for small chunks works pretty well? Thanks. | |
mhinson: 5-Jun-2009 | Hi, I have associated .r files with Rebol/view, but when I open my .r files I get an error ** Access Error: Cabbot open /c/documents ** Near: do/args script system/script/args I tried associating .rs with Rebol/View & that works ok... I suspect this is a windowsy problem, any suggestions please? | |
Maxim: 5-Jun-2009 | XP was designed for dumb users... vista went a step further and added that pre-requisite to its analysts. | |
BrianH: 5-Jun-2009 | Software at its best is a distillation of your smarter moments, for later use during your dumber ones :) | |
mhinson: 8-Jun-2009 | Hi, I seem to be answering more of my own questions for the last few days which is encouraging, but I am wondering if I am getting into bad habits as I have no solid programming background & apart from the tips I have got here I am just self-taught. Is there anywhere I can put a few hundred lines of code to be torn to shredds please? I don't paticularly relish the idea, but I suspect it will be a good learning experience. | |
Sunanda: 8-Jun-2009 | Few hundred lines of code!? Congratulations on writing them.....But can you extract a subset (say a function of two that you are especially proud of) for analysis. 100s of lines of code is going to be hard for anyone to wrap their mind around for comment. Having said that, possible locations: Here or the mailing list. You tend to get more thought out replies on the ML. You get more instant interaction here. | |
Sunanda: 8-Jun-2009 | You could also try reboltalk -- though that seems overrun with spam a lot these days: http://www.reboltalk.com/ | |
mhinson: 8-Jun-2009 | It is mostly a parse with about 8 small functions that are called within the parse to identify special cases, expand ranges & mess about with IP address info. | |
mhinson: 8-Jun-2009 | I think the fact that I can readily extract a decent function to post means that I have been using too many globals & getting my code a bit muddled. Thanks for the feedback, I will post something once I get it a bit more untangled.... It just went like that, honest I didnt write it like that to start with.. :-( | |
mhinson: 8-Jun-2009 | I am intrested in Cisco networking & writing tools related to that area of technology, not sure that is a very prominent interest in the AltME world?? | |
mhinson: 8-Jun-2009 | This is a unique place. It is a priveledge to be invited here. | |
Sunanda: 9-Jun-2009 | The Library does sometimes have trouble with scripts. It needs to load the script to get header information. But the Library is running on an older version of R2. Some newer scripts cannot be loaded as they contain syntax elements that crash the version the Library is running. We have some creative work-arounds. Mike can you email me your script (right click my name for email address). I'll see what the options are. Thanks.....You are a natural at finding bugs! | |
mhinson: 9-Jun-2009 | Hi, I have sent the whole thing to Sunanda as the script is ok in the browser, but has a few (other) problems being loaded into the Library. Probably down to me doing strange noobie things. In the case above the library prefers ... intIpaddrS/:count1 ... Which seems better in any case so I have changed it. | |
Sunanda: 9-Jun-2009 | Thanks Mike. It's [old REBOL version + REBOL not being backward compatible]. There is a theory that REBOL does not need to be backward compatible, as old applications can continue to run on older versions of the interpreter. That theory is fine in many cases..... .....But it fails in the case of REBOL.org -- we're an old (verging on legacy) application that consumes REBOL code as data ..... We fail in some cases because the code we try to consume as data crashes the version of the interpreter we use. I have an idea for (yet another) creative work around for the issue Mike has.....But I also have to spend a few days away from REBOL coding, so no immediate solution forthcoming. Sorry! | |
mhinson: 10-Jun-2009 | Hi, is there any clever Rebol way to access the Tuples in this block by the associated numbers 80 & 4 please? b: [80["8.8.8.8" "random"] 4["4.4.4.4"]] if they were words it would be easy, but with numbers I am wondering if I just have to search for them & find the index & add one? Or perhaps convert the numbers into words by prepending them with a letter perhaps? Thanks. | |
mhinson: 10-Jun-2009 | This solution seems a bit messy, so I wondered if there was a neater way. >> b: [_80["8.8.8.8" "random"] _4["4.4.4.4"]] == [_80 ["8.8.8.8" "random"] _4 ["4.4.4.4"]] >> b/_80 == ["8.8.8.8" "random"] | |
mhinson: 10-Jun-2009 | That is perfect.... Again I learn a new word for my Rebol conversations. Thanks Sunanda | |
mhinson: 13-Jun-2009 | Hi, I have written this function and would be glad of any comments please. I know it is only simple stuff but I want to try any learn to write code well, not just hack stuff together that just about works. Thanks. ;; Generate all IPv4 dotted decimal masks AllMasks: has [a b c d allMasks][ allMasks: [] if (allMasks = []) [ for count 0 7 1 [ i: to-integer power 2 (count) a: 255.255.255.255 - to-tuple rejoin ["0.0.0." (i - 1) ""] b: 255.255.255.255 - to-tuple rejoin ["0.0." (i - 1) ".255"] c: 255.255.255.255 - to-tuple rejoin ["0." (i - 1) ".255.255"] d: 255.255.255.255 - to-tuple rejoin ["" (i - 1) ".255.255.255"] insert allMasks reduce [a b c d] ] sort/all/reverse allMasks insert tail allMasks 0.0.0.0 print "Created all IPv4 masks" ;; debug ] return allMasks ] | |
Sunanda: 13-Jun-2009 | Any code that works is fine by me.....! You could make your to-tuples a little tidier by utilising the fact the to-tuple will take a block of integers, eg: to-tuple [255 255 255 248] == 255.255.255.248 | |
Paul: 13-Jun-2009 | Hi mhinson, a couple things at first glance. Beware setting a word to series data. One of the big pitfalls newcomers have is that if they intend to reuse a function that contains a series being set that it can result in the series getting recursively populated. To avoid that we often use the 'copy word when setting series. Although, by design sometimes we want the previous behavior. The other thing is to get rid of the return at the end. Just end your statement with allmasks. You should really only need the 'return if you intend to pre-empt the full execution of the body block of the function. | |
Sunanda: 13-Jun-2009 | Use of 'return is partially a personal style issue. It is, literally, not needed if the last value your function handles is the one you want returned; in that case omiting the 'return can speed up a function considerably. On the other hand, consider "literate programming" conventions: it can be polite to spell out the details so future code readers do not need to recapitulate your clevernesses just to work out what is returned......The code snippet below can return three separate things: spelling it out would help future generations! f: func [a b][ either a > b [ print a ][ if a = b [b + 5] ] ] | |
mhinson: 13-Jun-2009 | Hi guys, thanks for the tips, it is looking neater allready. About setting the words to series data, is this us in my gode a bad example would you say? I intended that the function would only ever need to calculate the values once, but perhaps my method is not secure? Thanks for the tip about series pickers, that way looks a bit reversed so I would have probably got it wrong. | |
Sunanda: 13-Jun-2009 | Another thought -- you may be able to avoid the block and to-tuple stuff by modifying a tuple: t: 255.255.255.255 == 255.255.255.255 t: poke t 4 t/4 - 1 == 255.255.255.254 | |
Izkata: 13-Jun-2009 | I wouldn't call it a bad example of storing series data, exactly, just unusual. Look at this: >> foo: func [/local bar][ [ bar: [] [ if empty? bar [ [ print {Generating..} [ insert bar 1 [ ] [ return bar [ ] >> foo Generating.. == [1] >> foo == [1] If the function needs to be called multiple times, the data is stored and doesn't need to be re-created each call, getting a pretty good speedup. This is what foo now looks like: >> source foo foo: func [/local bar][ bar: [1] if empty? bar [ print "Generating.." insert bar 1 ] return bar ] | |
mhinson: 14-Jun-2009 | I am wondering if there is a better or simpler way to get the index when using FIND? and the value is not found, my attempt seems more complex that I would have expected from Rebol, so I suspect there is a method or function I have not yet discovered. :-) Thanks. a: find {abd} "e" either none? a [i: 0][i: index? a] | |
Henrik: 14-Jun-2009 | The second line can be: any [all [a index? a] 0] | |
Henrik: 14-Jun-2009 | if you want to keep the 'either, it internally tests for none, so you could shorten it to: i: either a [index? a][0] You can see what kind of tests it makes by using TO-LOGIC on a value you want to test. | |
Paul: 14-Jun-2009 | Because the argument to index? is supposed to be a series and 'none is not a series. | |
mhinson: 14-Jun-2009 | Then should FIND return an empty series if the target is not found? rather than none? I thought none was a special case & might be handled differently by some functions that expect specific types. | |
Paul: 14-Jun-2009 | But see Find returns none BASED on a series argument. You were suppling 'none as the argument. | |
Henrik: 14-Jun-2009 | One can say that FIND limits its input to series! to eliminate errors as early as possible. Imagine if FIND accepted NONE and we had some intricate series of FINDs on a single block 'a: find find find/reverse find a 'e string! 'f integer! == none If 'a is a dynamic block (not known when you write the code) where is the error? It's not a great example, but it raises the question of how forgiving you want your functions to be, when you write them. I consider that you generally want to catch errors as early as possible, to avoid having to write "forgiving" code that can take up space and complicate things and worst of all, make the code much harder to debug. But it's only one school of thought. | |
mhinson: 14-Jun-2009 | ANY & ALL are quite hard, but I think I am getting it.. This confused me for a while, but now I understand. a: b: c: d: [] any [ do[a: 1 false] do[ all[ do[b: 2 false] do[c: 3 true]] true] do[ d: 4 true]] print rejoin["a,b,c,d=" a "," b "," c "," d] This is what I think is happening. a is set but as the block returns false the ANY block evaluation continues b is set within the nested ALL block & as it returns false the ALL block evaluation stops the do which contains the ALL block returns true so the ANY block evaluation stops | |
Izkata: 14-Jun-2009 | Yes; ANY is a shortcut for OR'ing vaues together, and ALL is a shortcut for AND. | |
Henrik: 14-Jun-2009 | I use ANY and ALL a lot because they can be handy in situations where an EITHER can be too cumbersome, such as inline result output for printing: print any [select names name "No Name Found"] In other cases they take up more space than an EITHER. | |
Tomc: 14-Jun-2009 | unlike a series of and/or any/all will stop evaulating conditions at the first condition that deternims the result | |
Gregg: 14-Jun-2009 | I take that back, I've messed up a couple times and created uncontrolled growth in the memoized data. You do have to watch out for that. :-) | |
Oldes: 15-Jun-2009 | instead of: any [ do[a: 1 false] ] why not to use just: any [ (a: 1 false) ] | |
mhinson: 15-Jun-2009 | That is interesting Oldes. I thought I tried something like that, but now I see I must have been confused about what the () do. so does the ANY cause the () to evaluate its contents? If I just put [(true)] it is not evaluated, but all[(true)] is. Then again to-logic [(false)] is not evaluated. There must be a trick I am missing here I think. Thanks, | |
Gregg: 15-Jun-2009 | Using blocks and *not* evaluating their contents--perhaps "deferring evalutation" is a better way to say it--is also a powerful aspect of REBOL. Being able to prevent parens from being evaluated is a good example. | |
mhinson: 15-Jun-2009 | I think I would love to know when evaluation occurs.. So far I mostly just have to test every fragment of code I write & if I am lucky I guess right first time. I am slowly getting better at it, but I would say it is often a bit of a mystery. | |
mhinson: 15-Jun-2009 | I have submitted a script to the Library. http://www.rebol.org/view-script.r?script=cisco-extract.r Its purpose (apart from learning Rebol) is to read Cisco config files & present the interface information in a tab separated text file. | |
mhinson: 17-Jun-2009 | Hi, I have done a bit with fairly basic parse expressions, but I am now trying to understand more. Am I right to think that ALL SOME & ANY are the only controls of this type? Or am I missing another in the set? Do ALL & ANY work in the parse dialect the same way that they do described above? Thanks. | |
mhinson: 17-Jun-2009 | ok. I really like the ? help functions. While learning they help a great deal. Thanks. | |
BrianH: 17-Jun-2009 | Unfortunately, parsing is considered a hard subject. Learning PARSE might take some time if you haven't had experience or taken a class in parsing before, even when you read the online docs. | |
mhinson: 17-Jun-2009 | I had a really usefull walk-through of Parse with Maxim a few weeks ago here. I wouldn't say Parse has been any harder for me to learn about than any other aspect I have delved into so far, in fact I found the GUI stuff the most confusing to get ahead with. | |
mhinson: 17-Jun-2009 | I started looking at the R3 Gui too. I am mostly intrested in drawing my own graphics on screen, controled by a bit of maths & trig, but with real-time interaction from sliders etc. I suspect this is not the sort of thing that newbies are expected to do, but writing text in different fonts on coloured buttons dosn't do anything for me.. I am finding that using any part of Rebol makes it easier to understand the discussion here & get more in tune with what behaviour to expect. | |
mhinson: 17-Jun-2009 | I have been working on my Parse understanding and came up with this: parse/all {aX--baX~~a--aX~~} [some [ "a" h: some[ [ ["--" :h copy result to "--" (print result) thru "a" h:] |["~~" :h copy result to "~~" (print result) thru "a" h:] ] |[skip] ] ] ] I am extracting the text between "a" and either "--" or "~~" Is my method a reasonable aproach or is there a simpler or more readable way to do this sort of thing please? | |
Ladislav: 17-Jun-2009 | here is my way: parse/all {aX--baX~~a--aX~~} [ "a" some [ s: any [ t: ["--" | "~~"] (result: copy/part s t print result) break | skip ] thru "a" ] to end ] | |
Izkata: 17-Jun-2009 | If the empty one doesn't need to be recorded as empty: parse/all {aX--baX~~a--aX~~} [ some [ ["a" some ["--" break | "~~" break | X: (print X/1) skip] | skip] ] ] | |
Izkata: 17-Jun-2009 | Mine'll also only grab one character at a time, so {abbb--} would need something extra | |
Graham: 18-Jun-2009 | If it's a fixed length format .. why bother use parse and just use copy/part ? | |
mhinson: 18-Jun-2009 | Thanks for the examples, I will be digesting them for a while I think. I started looking at a real life problem where the ending sequence of what I wanted to extract was two different things (". " OR "." newline), that led me to look at this sort of structure & try to understand how parse rules can be adapted. My example is educational only, not from real life. It was intended to be a short example of non-fixed length format with multiple cases to extract and 2 different end-of-data-to-extract markers. I think a better example of what I intended should have XX as the data to extract in one case. {aX--baX~~a--aX~~aXX~~} perhaps. Thanks. | |
Izkata: 18-Jun-2009 | Righto, here's my updated one - good practice for me, too, I rarely use parse like this: parse/all {aX--baX~~a--aX~~aXX~~} [ some [ ["a" S: some [E: ["--" | "~~"] (print copy/part S E) break | skip] | skip] ] ] | |
Steeve: 18-Jun-2009 | Lot of ways with parse... content: complement charset "-~" parse/all {aX--baX~~a--aX~~aXX~~} [ some [ thru #"a" opt [copy result some content ["--" | "~~"] (print result)] ] ] | |
mhinson: 19-Jun-2009 | It is strange this parse learning.. I look at these rules & understand what is happening. BUT I try to write my own without looking at these & I always get confused again. It dosn't seem very complex, but it does seem very easy to get wrong. Does any one have any tricks for formatting the code in a way that helps keep track of what the logic is doing? | |
mhinson: 20-Jun-2009 | I remeber looking at this before, but I couldn't work out how to use it... With a bit of luck I will understand it now, although it does look quite complex. Thanks. | |
mhinson: 20-Jun-2009 | Looks like the instructions are written for someone who already knows how to use it... - run the script ## this dosn't seem to do anything - Run the parse-analysis.r script and use the tokenise-parse function to get the base data. ## dont understand what this means, tried a few things but they all give errors. The example works, but I cant even see the parse expressions in it so I dont understand why it works or how to adapt it for my own example. When I first looked at this in April I got quite frustrated because it looked as if it was there to help newbies learn about parse, but it was too hard for newbies to understand how to use... now I can at least understand how to run the example. Thanks | |
Sunanda: 20-Jun-2009 | I sympathise....the documented examples for parse-analysis are certainly less than clear on what steps you need to take to prep a parse for analysis. If you have worked it out for some simple examples, then adding a discussion thread to the script may help other's in future. | |
Gregg: 21-Jun-2009 | I often have trouble visualizing how things work, and I don't feel that I really understand something until I can do that. With PARSE, even though it can be tedious and create volumes of output, it may help to write some simple grammars and have it print output for every rule. Have a probe at the start of the rule, and a probe if it's successful, nesting the output helps a lot too. Don't get discouraged, it's not an easy thing to grok for a lot of people. | |
Gregg: 21-Jun-2009 | In my largest grammar, where incoming data may be malformed, I've found it invaluable to have the rule tracing built in, enabled by a flag. e.g. TSAFE-CHAR: [ (rule-trace "TSAFE-CHAR IN") copy =TSAFE-CHAR charset-21 | charset-22 | charset-23 | charset-24 | charset-25 | NON-US-ASCII (rule-trace "TSAFE-CHAR OUT") ] rule-trace: func [value /local rule-name action] [ rule-name: first parse value none ;print [tab rule-name tab found? find don't-trace rule-name] action: second parse value none if all [ any [ trace-rules? = true action = form trace-rules? ] not found? find don't-trace rule-name ][ val: attempt [mold get to word! join "=" rule-name] print ["===" value any [val ""]] ] ] Don't-trace allows you to turn off selected rules that may get called a lot. You could also set tracing levels if you wanted. | |
Gregg: 21-Jun-2009 | This makes it easy to test input that doesn't parse and, if I can't find the problem or location quickly, turn on the trace and see exactly where it fails. I've also thought about, and asked Carl for, a way to get the position where the parse failed, including a line number. | |
Izkata: 21-Jun-2009 | The main thing I do is, at some point that happens a lot in the code, display the data. Makes it easier to step through the code and do - in your head - what the code is doing. If it suddenly doesn't match up, the loic somewhere was wrong. For example, when working on the last one, I had to debug part of it and did this: parse/all {aX--baX~~a--aX~~aXX~~} [ some [ ["a" S: (? S) some [E: ["--" | "~~"] (print copy/part S E) break | skip] | skip] ] ] | |
mhinson: 23-Jun-2009 | I seem to be going backwards with learning this. Perhaps I think I know the grammer, but don't. I am trying to write out long hand what I want to do, then convert it to a parse, but I dont have any words to describe how parse skips back to a previous point, so I cant write what I want to do long hand either.. e.g. gather the x in pairs from {fd doixx s x x x oie x } test for "x" or skip then when x is found do the same thing but escape to the outside loop. If I could write the above in a format that made more sense I think I would have a better chance of then converting it to a parse. test for "x" or skip seems to be ["x" | skip] doing it twice to get the x in pairs would seem like ["x" | skip] ["x" | skip] but that dosnt work because it lacks the loop control so I add that by a bit of guess work because I dont understand it properly. parse/all data [some[["x" | skip] ["x" | skip]]] but this is just completly wrong & I think the reason it is wrong is because I have completely misunderstood some or skip or | or where the point in the string the parse pointer gets to after each step.... I have tried using OPT & break in the second section but just get more muddled. | |
mhinson: 23-Jun-2009 | Gregg's suggestion sounds as if it might be helpfull, but I cant understand it yet. Izkata's suggestion is very helpfull, but in my case tends to just show that I am miles away from anything like a solution. Thanks. | |
PeterWood: 23-Jun-2009 | MIke, my first advice would be to avoid trying to "go back" during a parse operation at this stage. I think that is something to leave until you feel more comfortable with parse. | |
PeterWood: 23-Jun-2009 | Perhaps a good starting point is to think that when you "parse" something, you are asking does it conform to the rules I have supplied. If it does parse returns true, if it doesn't parse returns false. >> parse "abcdefghi" ["abcdefghi"] == true >> parse "abcdefghi" ["abcde"] == false | |
PeterWood: 23-Jun-2009 | You're already familiar with to,thru, end and to end: >> parse "abcdefghi" ["a" to "i"] == false >> parse "abcdefghi" ["a" thru "i"] == true >> parse "abcdefghi" ["abcde" to end] == true | |
PeterWood: 23-Jun-2009 | Perhaps the second thing to realise is a rule can be split into "sub-rules': >> parse "abcdefghi" ["abcde" "fghi"] == true | |
PeterWood: 23-Jun-2009 | (What Gregg referred to was a much more sophisticated way of getting the parse to show you what happened). | |
PeterWood: 23-Jun-2009 | Sub-rules can be optional by using the | (or) and enclosing the options in a block: >> parse "abcdefghi" ["abcde" (print "abcde found") ["fghi" (print "fghi found") | "xyz"(print "xyz found")]] abcde found fghi found == true | |
PeterWood: 23-Jun-2009 | We can specify that a sub-rule should be repeated: >> parse "abcdefghi" ["abcde" 4 skip] == true | |
PeterWood: 23-Jun-2009 | A better example of repetition: >> parse "aaa" [4 "a"] == false | |
PeterWood: 23-Jun-2009 | Some and Any are forms of repetition, this shows the difference: >> parse "aaa1000" [some "a" to end] == true >> parse "aaa1000" [any "a" to end] == true >> parse "bbb1000" [any "a" to end] == true >> parse "bbb1000" [some "a" to end] == false |
32901 / 64608 | 1 | 2 | 3 | 4 | 5 | ... | 328 | 329 | [330] | 331 | 332 | ... | 643 | 644 | 645 | 646 | 647 |