AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 190 |
r3wp | 3717 |
total: | 3907 |
results window for this page: [start: 1 end: 100]
world-name: r4wp
Group: #Red ... Red language group [web-public] | ||
Pekr: 14-Mar-2012 | that's what Doc replied on his blog: @Thomas: for the very first Red alpha, only memory management, basic datatypes and a few natives/actions. Ports and I/O will probably be added in following alpha versions, as PARSE. If we don't hit any walls, we should have it a few weeks, probably a month. | |
BrianH: 15-Jun-2012 | You can make a port work a lot like a series, and you mostly did with the virtual block scheme. FOREACH and PARSE not working on ports can be a bit annoying, but they would only work on a subset of the port types that either work like series or (theoretically) like files (like open/direct file ports in R2). | |
BrianH: 15-Jun-2012 | If Red adopts R3's port model, I would definitely like to try to implement that port PARSE idea I was thinking of for R3. | |
Pekr: 27-Jun-2012 | Well, as for dialects, I still can see PARSE as a secret weapon. Hopefully Red gets to R3 or Topaz level, as far as parsing goes. We could create some dialects for niches, I think ppl would see the advantage ... | |
Kaj: 18-Aug-2012 | Yes, except that Red/System is designed to fit Red, and Red will pass code to Red/System efficiently in loaded block form, instead of text form that the C compilers had to parse again | |
Pekr: 25-Aug-2012 | What I still think is, that we need strong parse. It is very cool technology. Yes, I dare to call it a technology. We need r3 level parse. Then we can create dialects, and show other guys, that dialecting is a cool concept. Pity we were not able to capitalise on it more, mainly due to closed nature of R2 possibilities to bind to other environments .... you imo :-) | |
Kaj: 25-Aug-2012 | Petr, I think we need Topaz level PARSE :-) | |
Pekr: 25-Aug-2012 | Topaz has even better parse than R3? | |
BrianH: 4-Oct-2012 | R2 and R3 use their own stacks, though recursive PARSE may use the C stack. The stack frames of R2 and R3 are different, but I wouldn't be able to tell you how. | |
DocKimbel: 18-Oct-2012 | Think PARSE usable from any other language as example. ;-) | |
Arnold: 30-Nov-2012 | Great explanations Nenad! My apologies if sometimes I seem to ask for the known things.. For the documentation we need a Red marker pen and mark the REBOL documentation where appropriate for Red. I took a little time (just 5 minutes LoL) to see if I could find a starting point for the documentation extraction script from the suggested makedoc2.r script but 'parse is not my best REBOL skill. Besides graphics and a killer application as Pekr described, having CGI support for Red can bring a lot of attention to Red too imho. (And this could bring financing Red up too when Red programmers are making money making websites using Red.) | |
DocKimbel: 9-Dec-2012 | The source code should be easily parse-able, so the list of functions, native, actions, ops could be extracted and pretty-printed as a web page. IIRC, someone tried to make such script but I didn't see any result yet. | |
Arnold: 9-Dec-2012 | Yes I wanted to give it a try for the doc scripts. But parse is not my expertise, and at the moment I am short in time as I can make extra hours at work. So everybody step in please and publish your baby-doc-scripts so we can all contribute little bits. | |
Pekr: 11-Dec-2012 | Jerry: yes, it is. I just hope, that some I/O and later parse comes in next 2 months, to be really usefull in real life :-) | |
Kaj: 8-Jan-2013 | With my proposal, you can parse numbers in issue notation, detect it's an integer and convert it to integer storage, without polluting the symbol table | |
Group: Ann-Reply ... Reply to Announce group [web-public] | ||
MaxV: 18-Jul-2012 | There a a lot of function undocumented. For example about VID a lot of documentation is missing, but VID is one the most important feature of Rebol. Similar for parse... and so on. Do you know that you can use "of" for radio buttons? | |
BrianH: 18-Jul-2012 | Others can chime in about the VID, but there are some pretty good tutorials about the parse dialect. Plus, you might look into the parse enhancement project page, which ended up with a lot of discussion of the semantic model, and in many cases the behavior of existing operations. | |
BrianH: 18-Jul-2012 | Someone else will have to provide the tutorial links. The parse project is here: http://www.rebol.net/wiki/Parse_Projec | |
BrianH: 18-Jul-2012 | Sorry, http://www.rebol.net/wiki/Parse_Project | |
Kaj: 25-Sep-2012 | PARSE level should be compatible, except for bug fixes | |
BrianH: 25-Sep-2012 | MaxV, REBOL isn't really an interpreter. DO is an interpreter, as is PARSE. The rest are library functions. If your code calls any of these functions, you need to provide the source to your code, even if it's encapped. | |
BrianH: 25-Sep-2012 | Oh, weirdly enough, DELECT and DO-COMMANDS are also interpreters. There is an additional gotcha though. Though DO, PARSE, DELECT and DO-COMMANDS are interpreters, they are implemented as library functions. This means that the code that you pass to these functions can be closed-source, but the code that *calls* these functions needs to be GPL-compatible. If you make a REBOL-in-REBOL interpreter or compiler that treats the code it runs as data, and the code it runs doesn't call any REBOL functions at all, even indirectly, then the code it runs can be closed source. This is basically what Red is, so Red would be legal. | |
Ladislav: 26-Sep-2012 | Re: 'Maybe you interpret "these functions" as DO, etc' - I have to because the citation actually is: Though DO, PARSE, DELECT and DO-COMMANDS are interpreters, they are implemented as library functions. This means that the code that you pass to these functions can be closed-source, but the code that *calls* these functions needs to be GPL-compatible | |
BrianH: 26-Sep-2012 | Here is the FSF FAQ entry relating to interpreters and their libraries: http://www.gnu.org/licenses/gpl-faq.html#IfInterpreterIsGPL Pretty much the whole entry is applicable. The first paragraph would apply to data passed to DO, PARSE, DELECT, DO-COMMANDS, or other dialect processors. The second paragraph would definitely apply to extensions, and could apply to built-in functions unless we get an exception like GCC's; or we could get a FAQ entry declaring that the functions built into R3 are "part of the interpreter" rather than "library code", despite R3's actual system model. Note that PARSE's built-in operations are more unambiguously "part of the interpreter", and the same could be said for other similar dialects. The last two paragraphs apply to mezzanine code and embedded modules. If they are GPL'd and your code uses them, it would be affected. | |
Ladislav: 27-Sep-2012 | The first paragraph would apply to data passed to DO, PARSE, DELECT, DO-COMMANDS, or other dialect processors. - actually, there is absolutely no need to not apply it also to the r3.exe+r3lib.dll | |
Ladislav: 27-Sep-2012 | So, readers may see different opinions. From "there are libraries different than r3lib.dll in the r3.exe+r3lib.dll interpreter" to even more extreme: every one of DO, PARSE, etc. is a separate program (obviously false) to which the GPL has to be applied on a separate basis". | |
Ladislav: 27-Sep-2012 | Also a wrong interpretation. There are no "libraries coming with the interpreter" and your interpretation is overly extensive, like the interpretation that DO, PARSE, etc. are "separate programs". | |
Andreas: 27-Sep-2012 | I don't follow the DO, PARSE, etc interpretation. | |
Ladislav: 27-Sep-2012 | 'or we could get a FAQ entry declaring that the functions built into R3 are "part of the interpreter" rather than "library code"' - that is where I do agree with you, except for the fact that we do have such an indication: 1) the functions *are physically/* part of the interpreter, they are "linked into it" (I would say "statically", since the interpreter does not need to look for them "elsewhere in the system", they are "inside") 2) the functions are a part of the interpreter, the interpreter documentation specifically mentions the functionality of the interpreter (the documentation mentions that the "ordinary version" of the interpreter "understands" FUNC, DO, PARSE, whatnot...) | |
Group: Rebol School ... REBOL School [web-public] | ||
Gregg: 24-Apr-2012 | He's one of us now Endo. Next thing, he'll b3 wondering why every other programming language has only 6 or 8 datatypes and why they don't have a PARSE function. :-) | |
GrahamC: 24-Apr-2012 | has anyone written parse rules for phone numbers? I need to setup a set of rules for international numbers, local numbers, cell numbers, 1800 etc for use in asterisk and prevent users from making toll calls unless authorise | |
Gregg: 24-Apr-2012 | set 'parse-phone-num func [ num [string!] /local digit digits sep _ext_ ch nums pin ext ] [ digit: charset "0123456798" digits: [some digit] sep: charset "()-._" _ext_: ["ext" opt "." | "x"] nums: copy "" rules: [ any [ some [sep | copy ch digit (append nums ch)] | _ext_ copy ext digits | "pin" copy pin digits ] end ] either parse trim num rules [reduce ['num nums 'ext ext 'pin pin]] [none] ] set 'well-formed-phone-number? func [num /local data] [ either none? data: parse-phone-num num [false] [ any [ found? find [7 10] length? data/num all [11 = length? data/num data/num/1 = #"1"] ] ] ] | |
Gregg: 24-Apr-2012 | set 'format-phone-number func [ num [string! object!] "String or object with /text value" /def-area-code area-code [string! integer!] /local left right mid obj res ] [ left: func [s len][copy/part s len] right: func [s len] [copy skip tail s negate len] mid: func [s start len][copy/part at s start len] if object? num [obj: num num: obj/text] res: either data: parse-phone-num num [ ; discard leader if it's there. if all [11 = length? data/num data/num/1 = #"1"] [ data/num: right data/num 10 ] rejoin [ rejoin switch/default length? data/num [ 7 [ compose [ (either area-code [rejoin ["(" area-code ") "]][]) left data/num 3 "-" right data/num 4 ]] 10 [[ "(" left data/num 3 ") " mid data/num 4 3 "-" right data/num 4 ]] ][[data/num]] reduce either data/ext [[" ext" trim data/ext]] [""] reduce either data/pin [[" pin" trim data/pin]] [""] ] ][num] if obj [ obj/text: res attempt [if 'face = obj/type [show obj]] ] res ] | |
GrahamC: 24-Apr-2012 | I guess users are going to have to make their own parse rules then | |
Gregg: 24-Apr-2012 | parse-int-values: func [ "Parses and returns integer values, each <n> chars long in a string." input [any-string!] spec [block!] "Dialected block of commands: <n>, skip <n>, done, char, or string" /local gen'd-rules ; generated rules result ; what we return to the caller emit emit-data-rule emit-skip-rule emit-literal-rule emit-data digit= n= literal= int-rule= skip-rule= literal-rule= done= build-rule= data-rule skip-rule ][ ; This is where we put the rules we build; our gernated parse rules. gen'd-rules: copy [] ; This is where we put the integer results result: copy [] ; helper functions emit: func [rule n] [append gen'd-rules replace copy rule 'n n] emit-data-rule: func [n] [emit data-rule n] emit-skip-rule: func [n] [emit skip-rule n] emit-literal-rule: func [value] [append gen'd-rules value] emit-data: does [append result to integer! =chars] ; Rule templates; used to generate rules ;data-rule: [copy =chars n digit= (append result to integer! =chars)] data-rule: [copy =chars n digit= (emit-data)] skip-rule: [n skip] ; helper parse rules digit=: charset [#"0" - #"9"] n=: [set n integer!] literal=: [set lit-val [char! | any-string!]] ; Rule generation helper parse rules int-rule=: [n= (emit-data-rule n)] skip-rule=: ['skip n= (emit-skip-rule n)] literal-rule=: [literal= (emit-literal-rule lit-val)] done=: ['done (append gen'd-rules [to end])] ; This generates the parse rules used against the input build-rule=: [some [skip-rule= | int-rule= | literal-rule=] opt done=] ; We parse the spec they give us, and use that to generate the ; parse rules used against the actual input. If the spec parse ; fails, we return none (maybe we should throw an error though); ; if the data parse fails, we return false; otherwise they get ; back a block of integers. Have to decide what to do if they ; give us negative numbers as well. either parse spec build-rule= [ either parse input gen'd-rules [result] [false] ] [none] ] | |
Gregg: 24-Apr-2012 | Example: parse-int-values "1234567890" [2 4 skip 2 2] | |
Gregg: 24-Apr-2012 | parse-int-values "(123) 456-7890" [#"(" 3 ") " 3 #"-" 4] | |
Sunanda: 28-Apr-2012 | REBOL is structured more like LISP or Haskell (but without being a pure functional language). So, yes, it does not have direct access to the machine instructions or low-level op sys APIs in the way that assembler or assembler-wrapper languages (like C) does. What REBOL does have is easy integrated access to very high level APIs: parse. bind, map, etc. | |
ChristianE: 14-May-2012 | indent: funct [string [string!]] [ whitespace: charset "^- " indention: line-start: content: none parse/all string [ copy indention any whitespace any [thru "^/" line-start: any whitespace content: (insert remove/part line-start content indention) :content] ] string ] | |
Endo: 14-May-2012 | hah! I wrote something similar: indent: func [s /local x] [parse/all s [x: (insert x "^-") any [thru newline x: (insert x "^-")]] s] | |
GiuseppeC: 18-Jun-2012 | I have a problem with Parse The following string does not work parse line [any [to mystring copy link to {<br />}]] mystring is a variable This works parse line [any [to "http://mysite.com"copy link to {<br />}]] Can't variables be used after TO ? | |
sqlab: 19-Jun-2012 | it works with global variables. maybe your variable is not visible to parse >> mys: "ac" == "ac" >> parse " abacbac ba" [any [to mys copy s to "b" (probe s)]] ac ac == false | |
GiuseppeC: 19-Jun-2012 | How do I parse the same data with different ending ? I could have http://myfile.txt</BR> http://myfile.txt</DIV> I need something like PARSE mystring [copy link to [</ BR>|</ DIV>] | |
Endo: 19-Jun-2012 | to doesn't accept block, so put "to" inside the block: s1: {http://myfile.txt</br>} s2: {http://myfile.txt</div>} parse s1 [copy link [to </br> | to </div>] (print link)] ;works parse s2 [copy link [to </br> | to </div>] (print link)] ;works too | |
GiuseppeC: 19-Jun-2012 | I need something like the following parse s1 [any [to "http://"copy link [to </br>|to </div>]] Is it possible ? | |
Ladislav: 19-Jun-2012 | Of course it is possible, if I understand if well what you want, is: s1: "a http://xxx</div>b http://yyy</br>" parse/all s1 [any [to "http://"copy link any [</br> break | </div> break | skip] (print link)]] | |
Ladislav: 19-Jun-2012 | If you do want to leave out the </br> and </div> substrings, the simplest way probably is: s1: "a http://xxx</div>b http://yyy</br>" parse/all s1 [any [to "http://"start: any [end: </br> break | </div> break | skip] (print copy/part start end)]] | |
Endo: 20-Jun-2012 | There is no documentaion about BREAK in PARSE (for R2), so it is always difficult to remember for me. Thanks Ladislav. | |
Endo: 20-Jun-2012 | Guiseppe: if you didn't read this before, here is a very good article: http://www.codeconscious.com/rebol/parse-tutorial.html other articles are also great, take a look at them all. | |
GiuseppeC: 20-Jun-2012 | Also: parse/all s1 [any [to "http://"copy link any [</br> break | </div> break | skip] (print link)]] Could it be written as: parse/all s1 [any [to "http://"copy link TO any [</br> break | </div> break | skip] (print link)]] Or parse/all s1 [any [to "http://"copy link any [TO </br> break |TO </div> break | skip] (print link)]] Finally, which is the purpose of the SKIP keywork in this context ? | |
Endo: 20-Jun-2012 | Guiseppe: "I am not ablie to understand the use of Break. Why it is useful ?" I'll try to explain: >> parse/all "http://a.txthttp://b.dat"[any [to "http://"copy x any [".txt" | ".dat" | skip] (print x)]] http://a.txthttp://b.dat;it prints just one line, from the first http:// to the last .dat >> parse/all "http://a.txthttp://b.dat"[any [to "http://"copy x any [".txt" break | ".dat" break | skip] (print x)]] http://a.txt;now it works as expected, from http:// to .txt and breaks http://b.dat;and from the next http:// to .dat | |
Endo: 20-Jun-2012 | But still there is a problem in your example. Here I'll try to explain: >> parse/all "http://a.txthttp://b.dat"[any [to "http://"copy x any [thru ".txt" (print 1) break | thru ".dat" (print 2) break | skip (print 3)] (print x)]] 1 http://a.txt 2 http://b.dat it looks correct. but actually it depends on which one is first (.txt or .dat) here is the problem: >> parse/all "http://a.txthttp://b.dat"[any [to "http://"copy x [thru ".dat" (print 1) | thru ".txt" (print 2) | skip (print 3)] (print x)]] 1 http://a.txthttp://b.dat | |
BrianH: 20-Jun-2012 | Petr, R3 can't decode any 8bit encodings with its built-in code, just ASCII (which is 7bit) and UTF-8. However, its binary handling is better so it should be easy to write your own converters. For R2, I would suggest looking at Gabriele's PowerMezz package; it has some great text converters. Of course you lose out on R3's PARSE if you use R2. | |
Ladislav: 21-Jun-2012 | 'Could it be written as: parse/all s1 [any [to "http://"copy link TO any [</br> break | </div> break | skip] (print link)]]' - no, since: - TO ANY is not supported - if it were supported it would not do what you want (you want to find the first terminator whatever it is, while TO ANY would find the </div> if it were in the input text even when a "closer" </br> would be "closer" | |
Ladislav: 21-Jun-2012 | Or parse/all s1 [any [to http://"copy link any [TO </br> break |TO </div> break | skip] (print link)]]" - this *is* supported, but it does not do what you want; it finds the </br> even if </div> occurs "sooner" | |
Sunanda: 30-Jul-2012 | Anyone want to have a try at this little puzzle? I have a working solution, but I am sure there is way more REBOLish way. I have two objects that each contain simple REBOL values (ie imagine they've just been created from some serialised data, so no recursive blocks or anything tricky): obj1: make object! [aaa: 1 bbb: "xx"] obj2: make object! [bbb: "XX" aaa: 1] All I want to do is confirm that they contain identical words and values under normal REBOL comparison rules -- so obj1 and obj2 should be treated as identical, while the next few are not identical to obj1 or obj2: obj3: make object! [bbb: "xx"] ;; no 'aaa word obj4: make object! [bbb: "XX" aaa: 1 ccc: 3] ;; extra word obj5: make object! [bbb: "XX" aaa: -1] ;; different 'aaa word value I am sure there is a simple one-line 'parse solution .... Isn't there always!? Thanks! | |
DocKimbel: 8-Aug-2012 | Endo: I think a much faster version could be coded using PARSE. | |
Endo: 8-Aug-2012 | And I'm not that good using PARSE, my PARSE expriments usually stuck with infinite loops :( | |
BrianH: 8-Aug-2012 | Here's a version for R3 parse, with some optimizations: rle2: funct ["Run length encode" b [series!]] [ output: copy [] x: none r: either any-block? :b [qr: copy [quote 1] [(qr/2: :x) any qr]] [[any x]] parse :b [any [pos1: set x skip r pos2: ( reduce/into [subtract index? :pos2 index? :pos1 :x] tail output )]] output ] | |
BrianH: 8-Aug-2012 | rle2: funct ["Run length encode" b [series!]] [ output: copy [] x: none r: either any-block? :b [qr: copy [quote 1] [(qr/2: :x) any qr]] [[any x]] parse/case :b [any [pos1: set x skip r pos2: ( reduce/into [subtract index? :pos2 index? :pos1 :x] tail output )]] output ] >> rle2 [a a A b b c d D d d d] == [2 a 1 A 2 b 1 c 1 d 1 D 3 d] | |
BrianH: 8-Aug-2012 | I tried to come up with a more optimal R3 version without using parse, but I got blocked by case-sensitivity, without considering binding. I suppose I could just consider binding too, or unbind the results. It also doesn't do structural comparison of functions, either in the parse or procedural version. | |
BrianH: 8-Aug-2012 | Can someone come up with an equivalent R2 parse version? Of course words aren't case-preserving in R2, nor can they be compared case-sensitively. | |
DocKimbel: 8-Aug-2012 | Here's a R2 solution with same rules for string! and block! series: rle: func [s [series!] /local out c i][ out: make block! 1 parse/case/all s [ any [ [end | c: ( c: either word? c/1 [to-lit-word c/1][c/1] i: 1 )] skip some [ c (i: i + 1) | (repend out [i c]) break ] ] ] out ] >> rle "aaabbcx" == [3 #"a" 2 #"b" 1 #"c" 1 #"x"] >> rle [a a a a a] == [5 a] >> rle [a a a a a b b] == [5 a 2 b] >> rle [a a A b b c d D d d d] == [3 a 2 b 1 c 5 d] | |
DocKimbel: 8-Aug-2012 | Another version of 'rle for R2 that uses two pointers (like your R3 version) instead of a counter: rle: func [s [series!] /local out c pos1 pos2][ out: make block! 1 parse/case/all s [ any [ [end | c: ( c: either word? c/1 [to-lit-word c/1][c/1] )] pos1: skip some [c | pos2: (repend out [offset? pos1 pos2 c]) break] ] ] out ] | |
BrianH: 8-Aug-2012 | Ah, yeah, I overspecced the R3 version by using QUOTE. Although there's a standatd workaround for integers (precede it with 1 1), for any-blocks and functions it might be best to do the comparison using REBOL code. The R2 equivalent of the IF operation in R3 parse would help here: http://www.rebol.net/wiki/Parse_Project#IF_.28condition.29 | |
BrianH: 8-Aug-2012 | Here's a version of Doc's with all datatypes handled, even unset. It even avoids accidentally converting lit-words to words and lit-paths to paths: rle: func [s [series!] /local out pos1 pos2 cont][ out: make block! 1 parse/all s [ any [ pos1: skip some [ pos2: skip (cont: if any [ not-equal? unset? :pos1/1 unset? :pos2/1 strict-not-equal? :pos1/1 :pos2/1 ] [[end skip]]) cont | pos2: (repend out [offset? :pos1 :pos2 :pos1/1]) break ] ] ] out ] | |
BrianH: 8-Aug-2012 | There was no point in using parse/case since the comparisons were being done by strict-not-equal?, not parse. | |
BrianH: 8-Aug-2012 | This version handles unsets too: rle: func [s [series!] /local out emit pos1 pos2 cont][ out: make block! 1 emit: [(repend out [offset? :pos1 :pos2 :pos1/1])] parse/all s [ any [ pos1: unset! some [pos2: unset! | pos2: emit break] | pos1: skip some [ pos2: unset! :pos2 emit break | pos2: skip ( cont: if strict-not-equal? :pos1/1 :pos2/1 [[end skip]] ) cont | pos2: emit break ] ] ] out ] | |
BrianH: 8-Aug-2012 | Slight improvement: rle: func [s [series!] /local out emit pos1 pos2 cont][ out: make block! 1 emit: [(repend out [offset? :pos1 :pos2 :pos1/1])] parse/all s [any [ pos1: unset! any unset! pos2: emit | pos1: skip some [ pos2: unset! :pos2 emit break | pos2: skip ( cont: if strict-not-equal? :pos1/1 :pos2/1 [[end skip]] ) cont | pos2: emit break ] ]] out ] | |
DocKimbel: 9-Aug-2012 | Endo: you should rather bench on one long series rather than 1M times on a small one in order to avoid function calls overhead and get a more fair comparison. When I try with a 1M size string with random a,b,c chars, my parse solution is twice faster than the mezz one (Brian's one is crashing so can't test it). I was expecting a greater difference though. | |
BrianH: 9-Aug-2012 | Weird, I found the bug in R2 parse that causes the crash: >> parse "" [integer!] == false >> parse "" [unset!] == true ; should be false | |
BrianH: 9-Aug-2012 | Two rules it is then. This doesn't crash, and is optimized for strings while we're at it. It's probably slower when doing blocks than Doc's, but it handles all datatypes: rle: func [s [series!] /local out emit pos1 pos2 cont][ out: make block! 1 emit: [(repend out [offset? :pos1 :pos2 first :pos1])] parse/case/all :s pick [[ any [pos1: skip (cont: first :pos1) any cont pos2: emit] ] [ any [ pos1: unset! any unset! pos2: emit | pos1: skip some [ end pos2: emit break | pos2: unset! :pos2 emit break | pos2: skip ( cont: unless strict-equal? first :pos1 first :pos2 [[end skip]] ) cont | pos2: emit break ] ] ]] any-string? :s out ] It also works around the strict-not-equal? bug in pre-2.7.7 R2, and using FIRST instead of path access is another speedup in R2 (path access is faster in R3). | |
BrianH: 9-Aug-2012 | Change the repend to chained inserts and it gets noticably faster, due to less mezzanine overhead: rle: func [s [series!] /local out emit pos1 pos2 cont][ out: make block! 2 emit: [(out: insert/only insert out offset? :pos1 :pos2 first :pos1)] parse/case/all :s pick [[ any [pos1: skip (cont: first :pos1) any cont pos2: emit] ] [ any [ pos1: unset! any unset! pos2: emit | pos1: skip some [ end pos2: emit break | pos2: unset! :pos2 emit break | pos2: skip ( cont: unless strict-equal? first :pos1 first :pos2 [[end skip]] ) cont | pos2: emit break ] ] ]] any-string? :s head out ] | |
BrianH: 9-Aug-2012 | You can get rid of this line too for a slight speedup: end pos2: emit break | It's a leftover when I was trying to work around the bug in PARSE. | |
BrianH: 9-Aug-2012 | If you follow the /into option standard you can do chained calls to RLE too: rle: func [s [series!] /into out [any-block!] /local emit pos1 pos2 cont][ unless into [out: make block! 2] emit: [(out: insert/only insert :out offset? :pos1 :pos2 first :pos1)] parse/case/all :s pick [[ any [pos1: skip (cont: first :pos1) any cont pos2: emit] ] [ any [ pos1: unset! any unset! pos2: emit | pos1: skip some [ pos2: unset! :pos2 emit break | pos2: skip ( cont: unless strict-equal? first :pos1 first :pos2 [[end skip]] ) cont | pos2: emit break ] ] ]] any-string? :s either into [:out] [head :out] ] | |
BrianH: 9-Aug-2012 | R3 version, same /into option: rle: funct ["Run length encode" s [series!] /into output [any-block!]] [ unless into [output: make block! 2] x: none r: either any-block? :s [qr: copy [quote 1] [(qr/2: :x) any qr]] [[any x]] parse/case :s [any [pos1: set x skip r pos2: ( output: reduce/into [subtract index? :pos2 index? :pos1 :x] :output )]] either into [:output] [head :output] ] | |
BrianH: 9-Aug-2012 | Sorry, same unset problems, have to use POKE: rle: funct ["Run length encode" s [series!] /into output [any-block!]] [ unless into [output: make block! 2] x: none r: either any-block? :s [qr: copy [quote 1] [(poke qr 2 :x) any qr]] [[any x]] parse/case :s [any [pos1: set x skip r pos2: ( output: reduce/into [subtract index? :pos2 index? :pos1 :x] :output )]] either into [:output] [head :output] ] | |
Steeve: 10-Aug-2012 | An alternative for R3 (strings and blocks) rle: func [s /local p e o][ o: copy [] parse/case s [ any [ p: skip any [e: if (p/1 == e/1) skip] (repend o [offset? p e p/1]) ] ] o ] | |
BrianH: 11-Aug-2012 | Steeve, that's basically the same as my R2 RLE's block rule, but with the IF workaround replaced with IF. It has a few gotchas: - Executes function values in block data - Doesn't handle unset! or error! values - Converts lit-paths to paths and lit-words to words before comparison and again before putting in the output. - Lots of intermediate block creation overhead - Considers bindings of words when comparing them, not just case-sensitive spelling The first 3 can be handled by using :p/1 and :e/1 instead of p/1 and e/1, and the fourth by using REDUCE/into instead of REPEND. The last one can't be handled by any built-in function or operator in R3 (see http://issue.cc/r3/1834for details) but you could do a combination of functions and operators to get case-sensitive comparison without considering bindings. PARSE/case's QUOTE operation is the fastest method for doing that at the moment. Nice job on neatly bypassing the relaxed bounds checking of R3 blocks. Though the if (p/1 == e/1) would succeed if p/1 is none and e is at the end of the block, the skip would still fail. That trick saves one e: operation. | |
BrianH: 11-Aug-2012 | The advantages of == or =? comparison over PARSE QUOTE would be lost if you serialize the data and save it to a file or send it over a network. REBOL syntax doesn't keep track of those distinctions. | |
BrianH: 11-Aug-2012 | The PARSE IF method does let you add a /compare function option though, so you can be as specific as you want. Instead of if (:p/1 == :e/1) you would do if (apply :f [:p/1 :e/1]) then pass :== or :strict-equal? as a parameter.. | |
BrianH: 11-Aug-2012 | Here's a version of my last one above, but with Steeve's trick adapted to make a /compare option. It defaults to its old case-sensitive behavior. rle: func [ "Run length encode to series of [length value]" s [series!] "The series to encode" /into {Insert into a buffer instead (returns position after insert)} output [any-block!] "The output buffer (modified)" /compare "Comparator function for equvilance" comparator [any-function!] /local x r qr b e ] [ unless into [output: make block! 2] x: none r: case [ compare [[any [e: if (apply :comparator [:x :e/1]) skip]]] any-string? :s [[any x]] 'else [qr: copy [quote 1] [(poke qr 2 :x) any qr] ] parse/case :s [any [b: set x skip r e: ( output: reduce/into [offset? :b :e :x] :output )]] either into [:output] [head :output] ] | |
BrianH: 11-Aug-2012 | Whoops, forgot a bracket: rle: func [ "Run length encode to series of [length value]" s [series!] "The series to encode" /into {Insert into a buffer instead (returns position after insert)} output [any-block!] "The output buffer (modified)" /compare "Comparator function for equvilance" comparator [any-function!] /local x r qr b e ] [ unless into [output: make block! 2] x: none r: case [ compare [[any [e: if (apply :comparator [:x :e/1]) skip]]] any-string? :s [[any x]] 'else [qr: copy [quote 1] [(poke qr 2 :x) any qr]] ] parse/case :s [any [b: set x skip r e: ( output: reduce/into [offset? :b :e :x] :output )]] either into [:output] [head :output] ] | |
Steeve: 11-Aug-2012 | I don't think it would be hard to code with parse | |
Steeve: 11-Aug-2012 | But I didn't use parse at that time | |
BrianH: 14-Aug-2012 | Yes. It uses the IF and QUOTE operations, SET working on string parsing, PARSE default /all, :x meaning GET/any 'x, REDUCE/into, and equality finctions handling unset! values. | |
BrianH: 14-Aug-2012 | If you are doing anything in PARSE, or generating blocks, or a wide variety of other things, it almost always pays off to do it in R3 if you can, rather than R2 or any of the other REBOL-alikes except maybe Topaz. Topaz has a few PARSE enhancements that R3 could use, but the rest don't even come close; there are so many bugs in R2 that need to be worked around that code for it can be quite different. Unfortunately, other factors can prevent people from using R3. Hopefully when Red itself is developed, not just Red/System, it will adopt the changes that we made for R3. | |
BrianH: 14-Aug-2012 | I'd love to see the Topaz PARSE enhancements in Red too :) | |
BrianH: 14-Aug-2012 | Gabriele has done a great job of reimplementing many of R3's PARSE enhancements in R2 using rule generators. If you're stuck on R2 or REBOL-alikes with R2-like behavior, that's a good place to start. It also helps to look at the parse project page, since there are a lot of code equivalent examples in the proposals there. That way you can translate your rules manually, and in some cases get faster rules as a result. Be careful with unset! vlaues though since there are a lot of bugs and limitations to R2's unset value handling, as demonstrated in the R2 RLE code above. | |
james_nak: 14-Aug-2012 | Brian, it's so nice to have a Parse expert here. Thanks for your advice. | |
james_nak: 14-Aug-2012 | Really though, you are probably one of the few who really know Parse. | |
Marco: 14-Aug-2012 | Speaking of Parse. I think it could be useful to compile some kind of FAQ or even better a tips&tricks doc. | |
MagnussonC: 18-Sep-2012 | I read a file, line by line and want parts of each line in certain variables. First is an integer then a space and then a 3-4 character word then a space and then the rest of the line in a string. I guess there is no way like in Perl to match those variabels at once and put the value in numbered variables. I suppose I need to parse that line with something like (thru "a" copy b to "c") once for each variable (or perhaps first char with line/1)!? | |
MaxV: 18-Sep-2012 | Read this http://rebol2.blogspot.it/2012/05/text-extraction-with-parse.html ;-) | |
Maxim: 18-Sep-2012 | does this help? -------------------------- a: {123 abcd bla blca bla 534 hged bla blca bla 947 ahg psogie rpgioseg seo[rgieh rpgiu} digits: charset "0123456789" letters: charset [#"A" - #"Z" #"a" - #"z"] space: charset " " data: complement charset "^/" ctx: copy [ ] parse/all a [ some [ copy id some digits space copy var 3 4 letters space copy line-data some data ; we have a match for all data, add it in our container ( append ctx copy reduce [ to-set-word rejoin [var "-" id] line-data] ) "^/" ] ] ctx: context ctx probe ctx | |
Maxim: 18-Sep-2012 | I added a bit of processing to show how to use parse in order to actually do things beyond just match patterns. note that the paren is at the end, once we have all data we want to match. An error people often do is to start processing too soon. | |
MagnussonC: 18-Sep-2012 | Thank you both! Now I have something to work with. Didn't realize you could do parse complex like that. | |
Gregg: 19-Sep-2012 | Magnusson, have you looked at the REBOL manual that explains the parse grammar? | |
Ladislav: 19-Sep-2012 | See also http://en.wikibooks.org/wiki/REBOL_Programming/Language_Features/Parse/Parse_expressions | |
Group: Databases ... group to discuss various database issues and drivers [web-public] | ||
BrianH: 17-Mar-2012 | ChristianE implements an R2-like API in an R3 port model, and it just feels alien, though it does allow me to have more portable code between R2 and R3. This helps when i have to have a script extract data in R2 because it needs to get text or numeric type data, but then close and call itself in R3 to parse that data. My %rebol.r is R2 and R3 compatible. |
1 / 3907 | [1] | 2 | 3 | 4 | 5 | ... | 36 | 37 | 38 | 39 | 40 |