• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

AltME groups: search

Help · search scripts · search articles · search mailing list

results summary

worldhits
r4wp18
r3wp193
total:211

results window for this page: [start: 19 end: 118]

world-name: r3wp

Group: All ... except covered in other channels [web-public]
Anton:
27-Feb-2005
digit: charset "0123456789"
number: [1 3 digit]
s: "testse193.194.70.123 1080iiyyyuiyiy  234.221.23.5:3380"

parse s [some [start: digit 3 [number "."] number opt [#":" 1 5 digit] 
end: (print copy/part start end) | skip]]
;193.194.70.123
;234.221.23.5:3380
;== true
Anton:
27-Feb-2005
ips: copy []

parse/all s [some [(port: none) start: digit 3 [number "."] number 
opt [#":" port: 1 5 digit] end: (append ips reduce [load copy/part 
start any [all [port back port] end] if port [load copy/part port 
end]]) | skip]]
Micha:
27-Feb-2005
parse s [some [start:   3 [number "."]   number opt #":" 1 5 digit 
 end: (append ips parse copy/part start end ":") | skip]
]
Micha:
27-Feb-2005
parse s [some [start:   3 [number "."]   number opt #":" 1 5 digit 
 end: (append ips load  replace  copy/part start end ":"
 " " ) | skip]]
Micha:
28-Feb-2005
parse/all s [some [start: digit 3 [number "."] number x: 1 10 char 
y: 1 5 digit   end: ( probe reduce [ copy/part start x  copy/part 
y end]) | skip ]]
BrianH:
4-May-2006
Here are some minimum additonal parse operations, and some workarounds 
that could be used to replace them until they are implemented.

fail ==> [end skip]
check (code) ==> (tmp1: unless (code) [fail]) tmp1
remove rule ==> tmp1: rule tmp2: :tmp1 (remove/part :tmp1 :tmp2)

replace rule (code) ==> tmp1: rule tmp2: :tmp1 (tmp1: change/part 
:tmp1 (code) :tmp2) :tmp1

replace-only rule (code) ==> tmp1: rule tmp2: :tmp1 (tmp1: change/part/only 
:tmp1 (code) :tmp2) :tmp1

into-string rule ==> set tmp1 string! (tmp1: unless parse tmp1 rule 
[fail]) tmp1


Note that if parse operations are changed to take refinements or 
if these are being done as rewrite rules, replace-only and into-string 
could be expressed as remove/only and into/string. This would be 
slower in a native implementation, but about the same in rewrite 
rules. It would look more REBOL-like if that matters to you.


A rewrite engine for these workarounds will need temporaries for 
their implementation. The caller would need to provide a block of 
their own temporaries, and would not be able to reuse them in their 
code. The rewriter will need to count temporaries and complain if 
the caller doesn't provide enough. As with all parse rules, these 
temporaries will not be recursion-safe. Directly nested rules should 
be fine as long as there are enough temporaries provided.
Group: RAMBO ... The REBOL bug and enhancement database [web-public]
Pekr:
1-Dec-2005
Chris - maybe it should, if you look at how skip "" 5 works. 'skip 
operation here is simply kind of doing "nothing" - trying to jump, 
but already at the end, so it jumps nowhere :-)
Brett:
2-Dec-2005
>> parse {ab} [to {a} to {a} to {a} to {a} {b}]
== false
>> parse {ab} [to #"a" skip #"b"]
== true
>> parse {ab} [to #"a" to #"a" to #"a" skip #"b"]
== true
>> parse {ab} [to #"a" to #"a" to #"a" to #"a" skip #"b"]
== true
>> parse {12345} [to end to end to end to end]
== true
>> parse {12345} [to end to 6 to 10 to 100 to end]
== true
>> parse {123} [thru 4 (print 1)]
== false
>> parse {123} [to 5 skip]
== false
Ladislav:
19-Apr-2006
this is the way: parse [/] [set w word! (nx: unless w = first [/] 
[[end skip]]) nx]
Anton:
23-Nov-2006
switch: func [

    "Selects a choice and evaluates the first block that follows it."

    [throw] ; <-- allows RETURN to be used by the user to jump out of 
    an enclosing function (not just this one)
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case [block!] "Default case if no others are found."
    /all "Evaluate all matches (not just first one)"
    /local rule new
][
	rule: [
		1 1 () ; <-- value
		to block! set new block! ; <- re-use the 'case variable
		(

      if any [default none? case][default: none case: clear []] ; only 
      clear case the first time
			append case new
		)
		to end ; <--
		| skip to () ; <-- type? value
	]
	rule/3: value
	change back tail rule type? value
	rule/11: either all [type? value]['end]
	parse cases [some rule]
	do case
]
Group: Core ... Discuss core issues [web-public]
JaimeVargas:
7-Apr-2005
I hope this is useful for someone

REBOL []

rest: func [s [series!]][skip s 1]

define-object: func [
	spec [block!] 
	/local 

  arg-spec ctx-spec object-name constructor-name predicate-name attributes
		spec-rule type-spec continue? w
][
	arg-names: copy []

	continue?: [none] ;used to stop parsing
	name-rule: [set w word! (insert tail arg-names w)]

 type-rule: [set w word! (unless datatype? attempt [get w] [continue?: 
 [end skip]])]

 spec-rule: [name-rule some [name-rule opt [into [some [type-rule 
 continue?]]]]]

	if any [
		not parse spec spec-rule
		arg-names <> unique arg-names
	][
		make error! "invalid spec"
	]

    object-name: to-string first arg-names
	constructor-name: to-word join 'make- object-name
	predicate-name: to-word join first arg-names '?
	attributes: rest arg-names

	arg-spec: copy []
	foreach itm attributes [
		insert tail arg-spec reduce [
			to-word join itm '-value
			either block? w: select spec itm [w][[any-type!]]
		]
	]

	ctx-spec: copy []
	arg-names: extract arg-spec 2 1
	repeat i length? attributes [

  insert tail ctx-spec reduce [to-set-word attributes/:i to-get-word 
  arg-names/:i]
	]

	;create constructor function
	set constructor-name make function! 

  compose [(reform ["Makes a new" uppercase object-name "object with 
  attributes" mold attributes]) (arg-spec)]
		compose/only [make object! (ctx-spec)] ;body

	;create predicate function
	set predicate-name make function! 

  compose [(reform ["Determines if value is a" uppercase object-name 
  "object"]) value [object!] /local types]
		compose/deep/only [
			either (attributes) = rest first value [
				foreach itm (attributes) [
					unless any [

      [any-type!] = types: select (arg-spec) to-word join itm '-value
						find types type?/word value/:itm
					][return false]
				]
				true
			][
				false
			]
		] 
]
JaimeVargas:
7-Apr-2005
If anyone ever wanted multi-methods or function overload in rebol 
here is the answer. Enjoy ;-)

REBOL []

define-method: func [
	'name [word!] spec [block!] locals [block!] code [block!]

 /local w type-rule spec-rule continue? register-name methods-name
][
	;; first validate the spec
	continue?: [none] ;used to stop parsing

 type-rule: [set w word! (unless datatype? attempt [get w] [continue?: 
 [end skip]])]
	spec-rule: [some [word! into [type-rule continue?]]]
    unless parse spec spec-rule [make error! "invalid spec"]

	register-name: to-word join :name '-register
	methods-name: to-word join :name '-methods?
	unless value? name [
		
		context [
			dispatch-table: copy []
			
			spec-fingerprint: func [spec [block!] /local types][
				types: copy []
				foreach itm extract/index spec 2 2 [insert tail types itm/1 ]
				types
			]
			
			values-fingerprint: func [values [block!] /local types][
				types: copy []
				foreach v values [insert tail types type?/word v]
				types
			]
			

   retrieve-func: func [values [block!]][select/only dispatch-table 
   values-fingerprint values]
			
			set :name func [values [block!]][
				do compose [(retrieve-func values) (values)]
			]
			
			set :register-name func [spec code /local fingerprint pos][
				fingerprint: spec-fingerprint spec
				either found? pos: find/only dispatch-table fingerprint [
					poke dispatch-table 1 + index? pos function spec locals code
				][

     insert tail dispatch-table reduce [fingerprint function spec locals 
     code]
				]
			]
			
			set :methods-name does [probe dispatch-table]
		]
	]

	do reduce [register-name spec code]
]

define-method f [x [integer!]] [] [x + 1]
define-method f [s [block!]] [] [attempt [pick s 2]]
define-method f [x [decimal!]] [] [sine x] 

f[5] == 6
f[[one two three]] == two
f[90.0] == 1.0
Pekr:
15-Oct-2005
form-decimal: function [num][tmp main rest sign base][

     either found? find tmp: to-string num "E" [

              parse tmp [
                 copy main to "."
                 skip
                 copy rest to "E"
                 skip
                 mark: (sign: copy/part mark 1)
                 skip
                 copy base to end
               ]


        either sign = "-" [

                tmp: "0."

                loop ((to-integer base) - 1) [insert tail tmp "0"]
                insert tail tmp rest
        ][
                tmp: copy ""

                insert tail tmp join main rest

                loop ((to-integer base) - (length? rest)) [insert tail tmp "0"]  
                    
                           
        ] 
     
      tmp                 

     ][num] 

]
Pekr:
15-Oct-2005
form-decimal: func [num /local tmp main rest sign base][

     either found? find tmp: to-string num "E" [

              parse tmp [
                 [copy main to "." 
                  skip
                  copy rest to "E"
                  |
                  copy rest to "E"
                  (main: copy "")  
                  ]
             
                 skip
                 mark: (sign: copy/part mark 1)
                 skip
                 copy base to end
               ]


        either sign = "-" [

                tmp: copy "0."

                loop ((to-integer base) - 1) [insert tail tmp "0"]
                insert tail tmp rest
        ][
                tmp: copy ""

                insert tail tmp join main rest

                loop ((to-integer base) - (length? rest)) [insert tail tmp "0"]  
                    
                           
        ] 
     
      tmp                 

     ][num] 

]
BrianH:
5-Nov-2005
(Back to slicing briefly) REBOL already has functionality equivalent 
to slicing as copy-of-subsection, so this would be better represented 
as a very simple mezzanine function that does the work. If you mean 
slicing as reference-to-subsection-in-place, that would be worth 
adding new support for. Something like:

slice!: make object! [start: end: none]

slice: func [[catch] s [series!] /from b [integer!] /to e [integer!] 
/len l [integer!]] [
    b: either from [at :s b] [:s]
    e: case [
        to at :s e
        len skip :b l
        true tail :s
    ]
    if greater? index? :b index? :e [to: :e e: :b b: :to]
    make slice! [start: b end: e]
]
Robert:
16-Jun-2006
This is IMO inconsistent and should be changed:

>> ? for
USAGE:
    FOR 'word start end bump body

DESCRIPTION:
     Repeats a block over a range of values.
     FOR is a function value.

ARGUMENTS:
     word -- Variable to hold current value (Type: word)

     start -- Starting value (Type: number series money time date char)

     end -- Ending value (Type: number series money time date char)

     bump -- Amount to skip each time (Type: number money time char)
     body -- Block to evaluate (Type: block)

(SPECIAL ATTRIBUTES)
     catch
     throw
>> a: 2.0
== 2.0
>> for test 1 a 1 [print test]
** Script Error: for expected end argument of type: integer
** Near: for test 1 a 1
>> number? a
== true


It should be possible to use decimal! as well. The interpreter should 
implicitly convert it to an integer!
Group: I'm new ... Ask any question, and a helpful person will try to answer. [web-public]
DideC:
22-Jun-2005
>> help new-line
USAGE:
    NEW-LINE block value /all /skip size

DESCRIPTION:
     Sets or clears the new-line marker within a block.
     NEW-LINE is a native value.

ARGUMENTS:
     block -- Position in block to change marker (Type: block)
     value -- Set TRUE for newline. (Type: any)

REFINEMENTS:
     /all -- Set/clear marker to end of block

     /skip -- Set/clear marker periodically to the end of the block
         size -- (Type: integer)
>> a: [1 2 3 4 5 6 7 8 9 10]
== [1 2 3 4 5 6 7 8 9 10]
>> new-line a true
== [
    1 2 3 4 5 6 7 8 9 10
]
>> new-line a false
== [1 2 3 4 5 6 7 8 9 10]
>> new-line/skip a true 2
== [
    1 2
    3 4
    5 6
    7 8
    9 10
]
Anton:
14-Apr-2006
page: read http://www.rebol.com

images: copy []

use [whsp ws non-end-tag strd p1 p2 delim non-delim][

	whsp: charset " ^-^/" ; whitespace
	ws: [any whsp] ; a rule for any number of whitespace characters
	non-end-tag: complement charset ">" ; all characters except ">"
	strd: charset {"'} ; string delimiters, double and single quote
	parse/all page [
		any [
			thru "<img" [
				ws "src" ws "=" ws 

    p1: [strd (delim: form p1/1) | (delim: ">")] (non-delim: complement 
    union whsp charset delim)

    p1: any non-delim p2: (append images copy/part p1 p2) ; keep the 
    url
				| non-end-tag
			] | skip
		]
	]

]


new-line/all images on ; add hidden newlines to the images block 
so it molds nicely
print mold images
Anton:
14-Apr-2006
page: read http://www.rebol.com
images: copy []

use [whsp ws non-end-tag strd p1 p2 delim non-delim][

	whsp: charset " ^-^/" ; whitespace
	ws: [any whsp] ; a rule for any number of whitespace characters
	non-end-tag: complement charset ">" ; all characters except ">"
	strd: charset {"'} ; string delimiters, double and single quote
	parse/all page [
		any [
			thru "<img" whsp [
				any [
					ws "src" ws "=" ws 

     p1: [strd (delim: form p1/1) | (delim: ">")] (non-delim: complement 
     union whsp charset delim)

     p1: any non-delim p2: (append images copy/part p1 p2) ; keep the 
     url
					| non-end-tag 
				]
			] | skip
		]
	]

]


new-line/all images on ; add hidden newlines to the images block 
so it molds nicely
print mold images
Anton:
14-Apr-2006
page: read http://www.rebol.com
; special test cases from Alek_K
;page: {<img src="one two.jpg">} ; OK
;page: {<img alt="picture" src=one.jpg />} ; OK
images: copy []


use [whsp ws non-end-tag strd wh- non-str-delim p1 p2 delim non-delim][

	whsp: charset " ^-^/" ; whitespace
	ws: [any whsp] ; a rule for any number of whitespace characters
	non-end-tag: complement charset ">" ; all characters except ">"
	strd: charset {"'} ; string delimiters, double and single quote


 wh-: charset "^-^/" ; whitespace minus the space character (space 
 is allowed inside a quoted string)
	non-str-delim: complement union whsp charset ">"	

	parse/all page [
		any [
			thru "<img" whsp [
				any [
					ws "src" ws "=" ws 

     ;p1: [strd (delim: form p1/1) | (delim: ">")] (non-delim: complement 
     union whsp charset delim)

     p1: [strd (non-delim: complement union wh- charset form p1/1) | (non-delim: 
     non-str-delim)]

     p1: any non-delim p2: (append images copy/part p1 p2) ; keep the 
     url
					| non-end-tag 
				]
			] | skip
		]
	]

]


new-line/all images on ; add hidden newlines to the images block 
so it molds nicely
print mold images
BrianH:
17-Jan-2008
If you want to do keyword-based records, put the keywords and values 
in the same block and use
    select/skip data key 2

Put each record in its own block: with variable length records you 
will need to track the end of the record otherwise. This method will 
be slower, but take less space when at least half of the fields are 
usually missing.
sqlab:
14-Apr-2009
better

rule: [(wanted: copy [] ) any [to "wanted" copy line to "rubbish" 
(append wanted line) skip ] to end]
PeterWood:
15-Apr-2009
In case this isn't clear. I'll try to explain the parse rule.


First any effectively says to match any of the rules in the following 
block until the end of the string is reached.

The first rule in the block is 

 [interface copy int-text some name-char (print ["interface: " int-text)]

says match with the word interface (newline + "interface ")

then if there is a match,  copy some name-char which says copy one 
or more characters which match the criteria of a name-char

then if there are some name-char characters evaluate the rebol code 
in parentheses.


If there wasn't a match with that first rule, then the second rule 
that follows the | will be applied.

skip will pass over one character and always provides a match.
PeterWood:
16-Apr-2009
Mike - The method that I showed you does not use up the "newline" 
at the end of the line. If you check again, the parse rule simply 
says copy in-text some name-char. This "stops" before the newline 
at the end of the line.


In fact guessing at your requirements a little and assuming the name-char 
is available. Some thing along these lines should be close to what 
you want:


keywords: ["^/interface " | "^/another keyword " | "^/yet another 
kerword"]

parse/all lines [any
  [ 
     copy int-keyword [keywords copy int-text some name-char (
       print  int-keyword ": " int-text]
    )
    |
    skip
 ] 
]

{I obviously haven't tested this code.)
mhinson:
16-Apr-2009
The mist maybe slowly clearing (sorry to be so slow to catch on).

The 2 stage process may be the answer, perhaps I can add a key char 
at the first line position when I read the file, then use this as 
the line start reference, but continue to use the end of line as 
normal.


I think I understand Peter's example & have tweaked it a bit to make 
it work for me.


lines: {~junk Interface fa0
~!
~interface fa1
~interface fa2 point-to-point
~!
~interface Fa3
~ description test three
~ ip address 1.1.3.3 255.255.255.0
~!
~interface Fa4
~ ip address 1.1.4.4 255.255.255.0
~!
~interface Fa3
~ description test four etc
~}

spacer: charset "^/"
name-char: complement spacer
stopwords: "point-to-point"

keywords: ["~interface " | "~ description " | "~ ip address"]

parse/all lines [any
  [ 

     copy int-keyword keywords copy int-text [to stopwords | some name-char] 
     (
       print  [int-keyword ": " int-text]
    )
    |
    skip
 ] 
]
mhinson:
17-Apr-2009
I have been studying the code from sqlab but I cant understand it 
enough to modify it. This is a deconstruction of part of it with 
my comments added. I would love a hand to understand this a bit more. 
 I cant find any documentation for this sort of thing that I can 
understand. 

I have also been trying to retrieve an index number when reading 
lines so it can be used as suggested by Sunanda. drawn a blank so 
far.



parse/all lines [                ;; parse the whole block called 
lines /all makes parsing only use values given below 

                                            ;; I am not sure if this is itteratied or the whole block parsed 
                                            as one. 
	(wanted: copy [])  ;; initalise wanted 

 | some [                 ;; one or more matches needed to return 
 true

  ifa: "interface"  some [   ;; ifa is given a string value right in 
  the middle of the parsing code

                                            ;; I see why, but not how this is able to slip into the middle here

                                            ;; then some starts another block so perhaps the "interface" is used 
                                            by parse too??

   ife: "point-to-point"  break  ;; no idea how the syntax works here
			| ife: newline    break           ;; or here

   | skip                                      ;; this skips I think 
   till one of the OR conditions are met from below?
		]

  (append/only  append wanted copy/part ifa ife   interf:  copy []) 
    ;;  I dont understand what block append/only is working on here

                                                                                                                                           ;;  append to block wanted using a part copy between ifa & ife but 
                                                                                                                                           I 

                                                                                                                                           ;;  dont understand the source for the copy 

  | some [                                                     ;; I 
  think perhaps all the below rules are end or search paterns?   
			s: " interface" (interf: copy [])
	        | drule
	        | iprule
	        | norule
	        | pvcrul
	        | pprule
	        | !rule
	        | break 
		] thru newline           ;; final catchall end search pattern. 
	]
]


Sorry to ask so many questions, feel free to throw me out if this 
is just too much, but I have spent several hours on this fragment 
allready. Thanks.
Oldes:
17-Apr-2009
parse/all {ab hello cd} [3 skip copy result 5 skip to end]     ;; 
returns "hello"

parse/all {ab hello cd} [thru #" " copy result to #" " to end]  ;; 
returns "hello"
Pekr:
4-May-2009
'break is needed in Ladislav's code imo because after first match 
of "B" you want to escape (break from) repetitive 'any block, and 
continue your processing with furhter rules (which is not the case 
with Ladislav's example, but is the case with your example, where 
'copy followed. If there would be no break, after matching "B", the 
rule would still succeed, because if there is no "B", then there 
is always "skip option, which is always valid until the end of the 
script. So actually without the 'break, this 'any block would 'skip 
till the end of input string is reached ...
mhinson:
13-May-2009
Hi, I have been puzzeling over this all evening & would love a few 
tips please.

I am trying to write a single parse rule that will extract the first 
number before the "/" in each case, but my logic must be faulty I 
think.

digit: charset [#"0" - #"9"]
data1: {random 10/2}
data2: {2/33-35,2/48}

parse/all data1 [ some [[h: 1 2 digit :h copy result to "/" thru 
end] | skip]]
result

parse/all data2 [ some [[h: 1 2 digit :h copy result to "/" thru 
end] | skip]]
result
Group: Parse ... Discussion of PARSE dialect [web-public]
BrianH:
22-Aug-2005
parse/all data [any [to "*" a: skip b: to "*" c: skip d: :a (change/part 
a rejoin ["<strong>" copy/part b c "</strong>"] d)] to end]
BrianH:
22-Aug-2005
markup-chars: charset "*~"
non-markup: complement markup-chars
tag1: ["*" "<strong>" "~" "<i>"]
tag2: ["*" "</strong>" "~" "</i>"]
parse/all data [
    any non-markup
    any [

        ["*" a: skip b: to "*" c: skip d: | "~" a: skip b: to "~" c: skip 
        d: ] :a (
            change/part a rejoin [
                select tag1 copy/part a b
                copy/part b c
                select tag2 copy/part c d
            ] d
        ) any non-markup
    ]
    to end
]
BrianW:
22-Aug-2005
Here's what I have right now:

		markup-chars: charset "*_@"
		non-markup: complement markup-chars
		inline-tags: [
			"*" "strong"
			"_" "em"
			"@" "code"
		]

		markup-rule: [
			any non-markup
			any [
				[ a: "*" b: to "*" c: skip d: |
				  a: "_" b: to "_" c: skip d: | 
				  a: "@" b: to "@" c: skip d: ] :a (
					change/part a rejoin [ 
						"<" select inline-tags copy/part a b ">"
						copy/part b c 
						"</" select inline-tags copy/part a b ">"
					] d
				) any non-markup
			]
			to end
		]
		parse text markup-rule
BrianW:
22-Aug-2005
okay, here's a slightly tweaked version that uses a multichar markup 
tag:

        markup-chars: charset "[*_-:---]"
        non-markup: complement markup-chars
        inline-tags: [
            "*" "strong"
            "_" "em"
            "@" "code"
            "--" "small"
        ]

        markup-rule: [
            any non-markup
            any [
                [ a: "*" b: to "*" c: skip d: |
                  a: "_" b: to "_" c: skip d: | 
                  a: "@" b: to "@" c: skip d: |
                  a: "--" b: to "--" c: skip skip d: ] :a (
                    change/part a rejoin [ 
                        "<" select inline-tags copy/part a b ">"
                        copy/part b c 
                        "</" select inline-tags copy/part a b ">"
                    ] d
                ) any non-markup | skip
            ]
            to end
        ]
        parse/all text markup-rule
Graham:
11-Oct-2005
[ copy frag n skip | copy frag to end ]
Ladislav:
11-Oct-2005
or copy frag [n skip | to end]
Ladislav:
11-Oct-2005
how about this one?: copy frag [n skip | to end] (frag: any [frag 
""])
Tomc:
11-Oct-2005
split-text: func [txt [string!] n [integer!]
    /local frag fraglet bl frag-rule bs ws
][  ws: charset [#" " #"^-" #"^/"]
    bs: complement ws
    bl: copy []
    frag-rule: [
        any ws
        [copy frag [n skip]
         [opt[copy fraglet some bs  (insert tail frag fraglet)]
        ]
       |[copy frag to end]
       (insert tail bl frag)
    ]
    parse/all txt [some frag-rule]
    bl
]
Ladislav:
11-Oct-2005
>> n: 5 parse "" [copy frag [n skip | to end] (frag: any [frag ""])]
== true
>> frag
== ""
Ladislav:
11-Oct-2005
split-text: func [
	txt n 
	/local frag result bl stop-rule
][
    bl: copy []
    result: copy ""
    stop-rule: none
    end-rule: [to end (stop-rule: [end skip])]
    frag-rule: [

  copy frag [n skip | end-rule] (frag: any [frag ""] print frag append 
  result frag)

  copy frag [to #" " | end-rule] (frag: any [frag ""] print frag append 
  result frag append bl copy result clear result)]
    parse/all txt [some [frag-rule stop-rule]]
    bl
]
Tomc:
11-Oct-2005
split-text: func [txt [string!] n [integer!]
    /local frag fraglet bl frag-rule bs ws
][  ws: charset [#" " #"^-" #"^/"]
    bs: complement ws
    bl: copy []
    frag-rule: [
        any ws
        copy frag [
            [1 n skip 
                opt[copy fraglet some bs]
            ]
            | to end skip
        ]
        (all [fraglet join frag fraglet]
         insert tail bl frag 
         print frag
        )
    ]
    parse/all txt [some frag-rule]
    bl
]
Ladislav:
16-Oct-2005
Gabriele: the [copy frag [n skip | to end] (insert tail result any 
[frag""])] looks too complicated for the PARSE setting words to NONE 
justification, I would at least prefer to add it to the ticket as 
an example.
Volker:
23-Oct-2005
i use 
 "a" any[ "b" | "c" | skip ] to end
Even slower and less elegantly, but works.
Volker:
23-Oct-2005
Maybe i used this?
 parse s ["a" some[ "be" break | "ce" break | skip] p: to end]

if nothing is found, it skips to the end. returns true, but if you 
require something after it,
that fails (because already at end).
Volker:
31-Oct-2005
or "end skip". with break the parsed part counts as success. with 
end skip it counts as failure and backtracks.
Volker:
31-Oct-2005
the general way:

 rule: [  ( dummy-rule: [] if not ok? [ dummy-rule: [end skip] ) dummy-rule 
 ]
BrianH:
1-Nov-2005
I didn't do a really useful example, just one to demonstrate the 
current way of faking the behavior.
Example:  [if (test) | ...]
Fix:  [(unless test [dummy: [end skip]]) dummy | ...]
BrianH:
1-Nov-2005
See, this is why I wanted that if clause. It's so easy to mess up 
the workaround.
Fix:  [(dummy: unless test [[end skip]]) dummy | ...]
Volker:
4-Nov-2005
should work like thru.  "any non-caret" is like "to caret", then 
skipping it is like "thru caret". without caret it would go to end, 
and then the final skip fail.
BrianH:
27-Jun-2006
You can drop one charset by changing [non-alpha | end] to [alpha 
end skip | end | none] .
BrianH:
27-Jun-2006
No, that would break out of the enclosing all loop. The end skip 
will always fail and proceed to the next alternate.
Tomc:
28-Jun-2006
capital: charset {ABCDEFGHIJKLMNOPQRSTUVWXYZ}
ws: charset { ^/^-}
latipac: difference complement capital ws


sub-rule: [
	some capital there:
	[ws | end]
	(all[ 4 < length? copy/part :here :there
		insert :there "</strong>"
		insert :here  "<strong>"
		there: skip :there 17]
	)
]
rule: [
	any latipac 
	[	some ws here:
		sub-rule
	]|[skip there:]
	:there
]
parse/all/case txt [here: opt sub-rule some rule]
Graham:
1-Jul-2006
Trying to do some macro expansion in text ...

This is not working :(

expand-macros: func [tmp [string!] macros [block!]
	/local white-rule rule len lexp
] [
	white-rule: charset [#" " #"^/"]
	foreach [macro expansion] macros [
        len: length? macro
		lexp: length? expansion
		rule:  compose/deep copy [

            [ to here: white-rule (macro) white-rule ( change/part here expansion 
            len  ?? macro) lexp skip ]
            to end
        ]
		parse/all tmp [some [rule]]
	]
	tmp
]
BrianH:
1-Jul-2006
expand-macros: func [data [string!] macros [block!]
	/local whitespace macro-rule macro here there
] compose [
	whitespace: (charset " ^/")
    macro-rule: make block! length? macros
	foreach [macro expansion] macros [
        macro-rule: insert insert macro-rule macro '|
    ]
    macro-rule: head remove back macro-rule
    parse/all data [some [
        here: copy macro macro-rule there: [whitespace | end] (

            there: change/part here select/skip macros macro 2 there
        ) :there |
        skip
    ]]
    macro-rule: none
    data
]
BrianH:
1-Jul-2006
expand-macros: func [data [string!] macros [block!]
    /local whitespace macro-rule macro here there
] compose [
    whitespace: (charset " ^/")
    macro-rule: make block! length? macros
    foreach [macro expansion] macros [
        macro-rule: insert insert macro-rule macro '|
    ]
    macro-rule: head remove back macro-rule
    parse/all data [some [
        here: copy macro macro-rule there: [whitespace | end] (

            there: change/part here select/skip macros macro 2 there
        ) :there |
        skip
    ]]
    macro-rule: none
    data
]
BrianH:
1-Jul-2006
expand-macros: func [data [string!] macros [block!]
    /local whitespace macro-rule macro expansion here there
] compose [
    whitespace: (charset " ^/")
    macro-rule: make block! 2.5 * length? macros
    foreach [macro expansion] macros [
        macro-rule: insert macro-rule
            compose [here: (macro) there: [whitespace | end] '|]
    ]
    macro-rule: head remove back macro-rule
    parse/all data [some [
        macro-rule (
            macro: copy/part here there

            there: change/part here select/skip macros macro 2 there
        ) :there |
        skip
    ]]
    macro-rule: none
    data
]
BrianH:
1-Jul-2006
expand-macros: func [data [string!] macros [block!]
    /local whitespace macro-rule macro expansion here there
] compose [
    whitespace: (charset " ^/")
    macro-rule: make block! 2.5 * length? macros
    foreach [macro expansion] macros [
        macro-rule: insert macro-rule
            compose [here: (macro) there: [whitespace | end] |]
    ]
    macro-rule: head remove back macro-rule
    parse/all data [some [
        macro-rule (
            macro: copy/part here there

            there: change/part here select/skip macros macro 2 there
        ) :there |
        skip
    ]]
    macro-rule: none
    data
]
BrianH:
1-Jul-2006
expand-macros: func [data [string!] macros [block!]
    /local whitespace macro-rule macro expansion here there
] compose [
    whitespace: (charset " ^/")
    macro-rule: make block! 2.5 * length? macros
    foreach [macro expansion] macros [
        macro-rule: insert macro-rule
            compose [here: (macro) there: [whitespace | end] |]
    ]
    macro-rule: head remove back macro-rule
    parse/all data [some [
        macro-rule (
            macro: copy/part here there

            there: change/part here select/skip macros macro 2 there
        ) :there |
        thru whitespace
    ] to end]
    macro-rule: none
    data
]
BrianH:
1-Jul-2006
; Now whitespace is dealt with
expand-macros: func [data [string!] macros [block!]
    /local whitespace macro-rule macro expansion here there
] compose [
    whitespace: (charset " ^/")
    macro-rule: make block! 2.5 * length? macros
    foreach [macro expansion] macros [
        macro-rule: insert macro-rule
            compose [here: (macro) there: [whitespace | end] |]
    ]
    macro-rule: head remove back macro-rule
    parse/all data [some [any whitespace [
        macro-rule (
            macro: copy/part here there

            there: change/part here select/skip macros macro 2 there
        ) :there |
        to whitespace
    ]] to end]
    macro-rule: none
    data
]
BrianH:
1-Jul-2006
expand-macros: func [data [string!] macros [block!]
    /local ws non-ws macro-rule macro expansion here there
] compose [
    ws: (charset " ^/") non-ws: (complement charset " ^/")
    macro-rule: make block! 2.5 * length? macros
    foreach [macro expansion] macros [
        macro-rule: insert macro-rule
            compose [here: (macro) there: [ws | end] |]
    ]
    macro-rule: head remove back macro-rule
    parse/all data [some [any ws [
        macro-rule (
            macro: copy/part here there

            there: change/part here select/skip macros macro 2 there
        ) :there |
        some non-ws
    ]] to end]
    macro-rule: none
    data
]
Pekr:
19-Jul-2006
REBOL []

template: {

<b><!--[mark-x]-->Hello x!<!--/[mark-y]--></b>
<b><!--[mark-y]-->Hello y!<!--/[mark-y]--></b>
<b><!--[mark-z]-->Hello z!<!--/[mark-z]--></b>
<b><!--[mark-w]-->Hello w!<!--/[mark-w]--></b>

}

parse/all template [
   some [
         thru "<!--["
         copy mark to "]-->"
         "]-->" 
         start:
         copy text to "<!--/["
         end:
         "<!--/[" mark "]-->"
         (print text)
         |
         skip
    ]
]           
         
halt
Pekr:
19-Jul-2006
this one works better for me:

parse/all template [
   some [
         thru "<!--["
         copy mark to "]-->"
         "]-->" 
         start:
         copy text to "<!--/["
         end:
         "<!--/[" 

         [mark "]-->" (print text) | (print ["not found end of: " mark]) :start]
         |
         skip
    ]
]
Anton:
4-Oct-2006
string: "<good tag><bad tag><other tag><good tag>"
entity: "<ENTITY>"
parse/all string [
	any [
		to "<" start: skip
		to ">" end: skip 
		(if not find copy/part start end "good tag" [
			change/part start entity 1

   ; fix up END (for when your entity is other than a 1-character long 
   string)
			end: skip end (length? entity) - 1
			change/part end entity 1
			; fix up END again
			end: skip end (length? entity) - 1
		])
		:end skip
	]
	to end
]
string

;== {<good tag><ENTITY>bad tag<ENTITY><ENTITY>other tag<ENTITY><good 
tag>}
Anton:
4-Oct-2006
string: "<good tag><bad tag> 3 > 5 <other tag><good tag with something 
inside>"

string: " > >> < <<good tag><bad tag> 3 > 5 <other tag><good tag 
etc> >> > "

; (1) search for end tags >, they are erroneous so replace them

; (2) search for start tags <, if there is more than one, replace 
all except the last one

; (3) search for end tag >, check tag body and replace if necessary

entity: "&entity;"
ntag: complement charset "<>" ; non tag
parse/all result: copy string [
	any [
		; (1)
		any [
			any ntag start: ">" end: (

    change/part start entity 1 end: skip start length? entity  ;print 
    [1 index? start]
			) 
			:end
		]
	
		; (2)
		(start: none stop?: none)
		any [
			any ntag start: "<" end:   ;(print [2 mold start])
			any ntag "<" (  ;print "found a second start tag"

    change/part start entity 1 end: skip start length? entity  ;(print 
    [2.1 mold copy/part start end]) 
				start: none
			) :end
		]
		(if none? start [stop?: 'break]) stop?
		
		; ok, we found at least one start tag
		;(print ["OK we found at least one start tag" mold start])
		:start skip
		
		; (3)
		any ntag end: ">"   ;(print [3 mold copy/part start end])
		(if not find copy/part start end "good tag" [
			;print ["found a bad tag" mold copy/part start end]
			change/part start entity 1

   ; fix up END (for when your entity is other than a 1-character long 
   string)
			end: skip end (length? entity) - 1
			change/part end entity 1
			; fix up END again
			end: skip end (length? entity) - 1
		])
		:end skip
	]
	to end
]
result
Gabriele:
25-Dec-2006
>> rules: [
[    any [
[        end break
[        |
[        copy value [to newline | to end] (print value) opt skip
[        ]
[    ]
== [
    any [
        end break
        |
        copy value [to newline | to end] (print value) opt skip
    ]
]
>> parse s2 rules
str 1
str 2
str 3
== true
Gabriele:
26-Dec-2006
joe, if you don't care about parse returning true you can just use 
skip (without opt, which is there for the end case)
Ladislav:
27-Dec-2006
Joe: another option is to use:

rules: [
    any [
        copy value [to newline | to end] (print value) skip
    ]
    to end
]
Ladislav:
27-Dec-2006
but, as Gabriele said, that is equivalent to:

rules: [
    any [
        copy value [to newline | to end] (print value) skip
    ]
]

if you ignore the parse result
BrianH:
27-Dec-2006
to end skip will always fail. move the skip after the to newline.
Oldes:
19-Jan-2007
Isn't this a bug?

>> b: "1234^@567" parse/all b [copy i to {^@} 1 skip b: to end] probe 
i probe b
1234
567

BUT:

>> b: "1234^@567" parse/all b [copy i to #{00} 1 skip b: to end] 
probe i probe b
1234
1234^@567
Volker:
19-Jan-2007
>> b: "1234^@567" parse/all b [copy i to "^(0)" 1 skip b: to end]
== true
>> i
== "1234"
Maxim:
13-Apr-2007
symbol: charset [#"a" - #"z" #"A" - #"Z" #"0" #"9" "_-?!*+~"]
nstr: "...aa.....a.....a.....h." 

parse/all nstr [
	some [
		symbol | end skip | 
		[

   here: ( probe here either none? here/1 [print nstr print "!!"  ][print 
   here/1 print nstr remove here here: back here]) ; :here skip
		]
		;:here
	]
] probe nstr
Ladislav:
13-Apr-2007
Max: ...symbol | end skip | ... does not have much sense, since it 
is equivalent to just ...symbol | ...
Ladislav:
13-Apr-2007
rule: [(next-rule: unless result-of-expression [[end skip]]) next-rule]
Ladislav:
13-Apr-2007
see this:

>> rule: [(next-rule: unless result-of-expression [[end skip]]) next-rule]

== [(next-rule: unless result-of-expression [[end skip]]) next-rule]
>> result-of-expression: false
== false
>> parse "" rule
== false
>> result-of-expression: true
== true
>> parse "" rule
== true
Ladislav:
28-Jun-2007
this is possible, but my guess, that Steeve would call it ugly too:


>> once-only: func [rule] [use [rule'] copy/deep [rule': :rule [rule' 
(rule': [end skip])]]
]

>> rule: [(a': once-only a b': once-only b c': once-only c) 3 [a' 
| b' | c']]

== [(a': once-only a b': once-only b c': once-only c) 3 [a' | b' 
| c']]
Geomol:
28-Jun-2007
Ladislav, that's not ugly, it's beautiful! :-)

I have a question though. Do you need the skip at the end of once-only? 
Wouldn't it work just with
rule': [end]
Ladislav:
28-Jun-2007
John: [end skip] is a rule that surely fails, while [end] may succeed 
(at end)
Geomol:
28-Jun-2007
I see. That's also why my block parsing give false result with less 
input. So for block-parsing, it should be:

>> once-only: func [:rule] [use [rule'] copy/deep [rule': :rule [rule' 
(rule': [end skip])]]]
Geomol:
28-Jun-2007
>> once-only: func [rule] [use [rule'] copy/deep [rule': :rule [rule' 
(rule': [end skip])]]]

>> rule: [(a': once-only 'a b': once-only 'b c': once-only 'c) 3 
[a' | b' | c']]
>> parse [a b c] rule
** Script Error: Invalid argument: a
Steeve:
28-Jun-2007
Once (again)

Rebol is amazing, i think i found a simple and elegant dialect

Currently, it's not allowing recursive once usage, but it's obvious 
to do with a stack.


take: func [r] [n: 0 once/1: (length? r) + 1 / 3 once/2/2: r replace/all 
r '.. '.]
.: [(n: n + 1)]
..: [(n: n + 1) end skip]
once: [0 [(if n > 0 [poke once/2/2 n - 1 * 3 + 1  '..] n: 0) []]]


rule: [. "a" | . "b" | . "c"]
parse "CBA" [ (take rule) once]
== true
parse  "BAC" [ (take rule) once]
== true
parse  "CBA" [ (take rule) once]
== true
parse  "BBC" [ (take rule) once]
== true
parse  "CA" [ (take rule) once]
== false
parse  "CABA"[ (take rule) once]
== false
rule2: [. "a" | . "a" | . "b" | . "c"]
parse "CABA"[ (take rule2) once]
== true
Tomc:
29-Jun-2007
do rules: [
	set 'a "first rule "
	set 'b "second rule "
	set 'c "third rule "
]

rule: [ 
	[end (if empty? erode[here: back tail :here]) :here skip]| 
	[here: erode there: 
	(	all[
			token: copy/part :here :there
			word: find rules token
			word: first back word
			remove/part find erode word 2 
		]

  all[empty? erode not tail? there insert/only erode [] there: tail 
  there]
	)] :there
    rule
]

data: "first rule second rule third rule "
erode: [ a | b | c | a]  parse/all data rule
Tomc:
4-Sep-2007
data: {my string^-"<span style="font: 12px arial;>some text</span>"}

rule: [copy token [to tab | to end](insert/only tail result token) 
skip rule]
parse/all data [(result: copy []) rule]
result


 ["my string" {"<span style="font: 12px arial;>some text</span>"}]
BrianH:
6-Nov-2008
Here's an example of what you could do with the PARSE proposals:

use [r d f] [ ; External words from standard USE statement
    parse f: read d: %./ r: [
        use [d1 f p] [ ; These words override the outer words
            any [
            ; Check for directory filename

                (d1: d) ; This maintains a recursive directory stack
                p: ; Save the position

                change [ ; This rule must be matched before the change happens

                    ; Set f to the filename if it is a directory else fail
                    set f into file! [to end reverse "/" to end]
                    ; f is a directory filename, so process it
                    (

                        d: join d f ; Add the directory name to the current path

                        f: read d   ; Read the directory into a block
                    )
                    ; f is now a block of filenames.
                ] f ; The file is now the block read above
                :p  ; Go back to the saved position
                into block! r ; Now recurse into the new block
                (d: d1) ; Pop the directory stack
            ; Otherwise backtrack and skip
                | skip
            ] ; end any
        ] ; end use
    ] ; end parse
    f ; This is the expanded directory block
]
BrianH:
6-Nov-2008
Here's an revised version with more of the PARSE proposals:

use [r d res] [ ; External words from standard USE statement
    parse res: read d: %./ r: [
        use [ds f] [ ; These words override the outer words
            any [
            ; Check for directory filename

                (ds: d) ; This maintains a recursive directory stack
                [ ; Save the position through alternation

                    change [ ; This rule must be matched before the change happens

                        ; Set f to the filename if it is a directory else fail

                        set f into file! [to end reverse "/" to end]

                        ; f is a directory filename, so process it
                        (

                            d: join d f ; Add the directory name to the current path

                            f: read d   ; Read the directory into a block
                        )
                        ; f is now a block of filenames.
                    ] f ; The file is now the block read above
					fail ; Backtrack to the saved position
					|
					into block! r ; Now recurse into the new block
				]
                (d: ds) ; Pop the directory stack
            ; Otherwise backtrack and skip
                | skip
            ] ; end any
        ] ; end use
    ] ; end parse
    res ; This is the expanded directory block
]
Steeve:
24-Dec-2008
parse/all s [some ["12345" (print "*") end skip]
is that not enough ?
BrianH:
24-Dec-2008
The skip will produce false because it is attempting to skip past 
the end.
BrianH:
24-Dec-2008
The phrase [end skip] will always fail and return false.
BrianH:
24-Dec-2008
For now, you want a continuation variable. Like this:

result: parse [this that bleh blah][some [set w word! (cont: unless 
find words w [[end skip]]) cont]]
Group: Linux ... [web-public] group for linux REBOL users
Ladislav:
9-Apr-2007
Max, why don't you use LOAD in PARSE, if you want to? Example:

rule: [
	(result: make block! 0)
	any [
		[
			; trying to load
			pos: skip (
				next-rule: either error? try [
					set [value pos] load/next pos
				] [[end skip]] [[:pos]]
			) next-rule |
			; load didn't succeed, using something else
			copy value skip
		]
		(insert/only tail result get/any 'value)
	]
]

>> parse "1 2 a, 3" rule
== true
>> result
== [1 2 "a" "," 3]
Ladislav:
9-Apr-2007
twist of redefining a rule...

 - that is just to "tell PARSE" whether the paren operation succeeded 
 or not - [end skip] is failure
Group: !Readmail ... a Rebol mail client [web-public]
Graham:
17-May-2005
From Didier

	; decode ISO-8859-1 / ASCII-US encoded text

 decode-iso8859: func [str /local ascii non-ascii char text emit quoted-printable 
 encoded-word res b e] [
		emit: func [v][append res v]
		ascii: charset [#" " - #"^(7f)"]
		non-ascii: complement ascii
		text: exclude union ascii non-ascii charset ["="]
		char: exclude ascii charset ["?_=^-"]
		encoded-word: [
			"=?" ["ISO-8859-1" | "us-ascii"] [
				"?q?" some quoted-printable |
				"?b?" b: to "?" e: (emit to-string debase copy/part b e)
			] "?="
		]
		quoted-printable: [
			"_" (emit #" ") |
			b: some char e: (emit copy/part b e) |

   b: "=" (emit do rejoin [ {#"^^(} second b third b {)"} ]) 2 skip
		]

		res: make string! length? str

  parse/all str [any [encoded-word | "=" (emit #"=") | "^/ " | b: some 
  text e: (emit copy/part b e)] to end]
		res
	]
Group: Announce ... Announcements only - use Ann-reply to chat [web-public]
eFishAnt:
2-May-2006
Visit  http://www.TGD-Consulting.de/Download.htmland take a look 
at

the final release of Hex-It!. (I posted on behalf of Dirk Weyand, 
since he cannot reach AltME)


Hex-It! is a small but powerful hex-editor. You can use this tool 
to analyse
or alter the "fingerprints" for any kind of files.

Known first as a contribution to the REBOL Demo 2006 contest, the 
final
release with enhanced features is available now.
Features of Hex-It! v1.2.0:
---------------------------
* cross platform hex-editor

* free "save-feature" for small files sized lesser 15 KB, to edit 
larger
  files purchase a license-key that unlocks this limitation
* enhanced spot navigation with mouse scroll-wheel support
* non blocking file access 

* support of large files (a maximum chunk of 1MB file-data is only 
held in
  memory at once)
Some notes and useful tips & tricks on the usage of Hex-It!:
------------------------------------------------------------

- Modifications of files were automatically saved on exit, if you 
load

another file or if a different chunk of the same file is selected.
- Byte selection:

  + Select a byte with a left mouse button (LMB) click on the hexadecimal
    values to the left. The byte is highlighted then.

  + If a byte is selected, either use the cursor keys or the scroll-wheel 
  of
    the mouse to scroll through the bytes of the file.

  + Change a selected byte with plus (+) & minus (-) or just enter 
  its

    new value. Single characters, three digit numbers or single hexadecimal
    values are valid.

  + Use the right mouse button (RMB) to deselect a highlighted byte.
- Spot-navigation:

  + The spot specifies the index/position of a byte in the file. If 
  no byte

    is selected it shows the position of the top left byte displayed. 
  + Enter a number to set directly the spot to a byte-position.

  + Skip a certain amount of bytes relative to the current spot by 
  using

    plus (+) & minus (-), e.g. "+10000" skips 10000 bytes forward and
    "-1000" skips 1000 bytes backwards. 

  + Skip to end of file: Click with the RMB on the arrow-down Spot-button
    or use the "End"-Key.

  + Skip to first byte of file: Click with the RMB on the arrow-up
    Spot-button or use the "Home"-Key. 
- Seek:
  + ASCII- or Hex-Strings are valid queries.

  + LMB click on the "Seek"-button seeks from the current position.

  + RMB click on the "Seek"-button seeks from the beginning of the 
  file.

Please note, that the license of this release is not BSD like anymore.
Group: Rebol School ... Rebol School [web-public]
Geomol:
6-Feb-2009
The second argument to parse can be a string, and then parse split 
up the first argument, or the second argument can be a block of parsing 
rules. out is just my output block.

So the parsing rules go:
1) first any of a sub-block of sub-rules

2) sub-block copy the input string to a point, where two newlines 
are found, the result in the variable: arg

3) the paranthesis is evaluated (as normal REBOL code), and it append 
arg (the part of the string, we just copied) to the variable out
4) the parser then skip any number of newlines (2, 3 or more)

5) when the sub-rules are not valid any longer, the input string 
is copied till the end (and appended to out as before)
Group: rebcode ... Rebcode discussion [web-public]
BrianH:
14-Oct-2005
(Thinking out loud) It occurs to me that computed branches would 
be a lot easier if you could reference the target values in your 
code, so that you have something to compute with. If the offsets 
were absolute you could just assign them to the label words (something 
that could be done in the first pass of the assembler rewrite of 
the branch statements). Relative offsets could be calculated pretty 
easily if you had something like a HERE opcode that would assign 
the current position to a variable that could be used soon afterwards 
to calculate the relative offset. For that matter, the HERE opcode 
could perform the assignment of the original label as well, and even 
be accomplished by a rewrite rule in the branch fixup pass of the 
assembler.


Here's my proposal for a HERE assembler directive. No native opcodes 
would need to be added - this would be another directive like label. 
This directive could be used to set the target values to words for 
later computation. Assuming BRAW stays relative and no absolute computed 
branch is added, it could also be used in computations to convert 
from absolute to relative offsets. This would be sufficient to make 
computed branches practical.


- A new directive HERE, taking two arguments, a word and a literal 
integer.

It would set the word to the position of the HERE directive, plus 
an offset specified in the second parameter. The offset would need 
to be a literal because the calculation would be performed ahead 
of time by the assembler - 0 would mean no offset. If you don't want 
to reset the position every time you branch to the word use an offset 
of 3. Resetting the word after every branch would allow its use as 
a temporary in absolute-to-relative calculations, but that would 
only be an advantage until the JIT or optimizer is implemented - 
the choice would be up to the developer. Having a mandatory second 
argument is necessary for reasons that will become clear later.


- The HERE directive would be rewritten away in the fix-bl function 
of the assembler like this:

REBOL []  ; So I could use SciTE to write this message

fix-bl: func [block /local labels here label] [
    labels: make block! 16
    block-action: :fix-bl
    if debug? [print "=== Fixing binding and labels... ==="]
    parse block [
        some [
            here:
            subblock-rule (here/1: bind here/1 words)
            |

            'label word! (here/1: bind here/1 words insert insert tail labels 
            here/2 index? here)
            |  ; Beginning of the added code
            'here word! integer! (

                here/1: bind 'set words  ; This is why HERE needs two arguments

                here/3: here/3 + index? here  ; Offset from position of this directive
                if (here/3 < 1) or (here/3 > 1 + length? block) [
                    error/with here "Offset out of bounds:"
                ]
            )  ; End of the added code
            |
            opcode-rule (here/1: bind here/1 words)
            |
            skip (error here)
        ]
    ]
    parse block [
        some [
            here:
            ['bra word! | 'brat word! | 'braf word!] (

                if not label: select labels here/2 [error/with here "Missing label:"]
                here/2: label - index? here
            )
            |
            opcode-rule
            |
            skip (error here)
        ]
    ]
]
Group: Tech News ... Interesting technology [web-public]
Volker:
11-May-2007
text: {
10-Mar-2007 $12,002.34 "Home Hardware" "Tile Saw"
1--Mar-2007 $12002.34 "Home Hardware" "Tile Saw"
}
parse text blk-rule: [
    some [
        str:
        newline |

        #";" [thru newline | to end] new: (probe copy/part str new) |
        [#"[" | #"("] blk-rule |
        [#"]" | #")"] break |
        skip (
            either attempt [
                set [value new] load/next str
            ] [
                probe :value
            ] [
                new: find str " "
                print ["GIBBERISH" copy/part str new]
            ]
        ) :new
    ]
]
Group: !REBOL3-OLD1 ... [web-public]
BrianH:
4-May-2006
As for the hash (or assoc) index and list data combo, it has some 
advantages. When you are inserting and removing data a lot lists 
have a known speed benefit but the real advantage as far as indexes 
are concerned is in how lists handle series offsets (I'm using the 
word offset here because I'm using the word index to refer to the 
external hash/assoc index).


Blocks encode their offsets as a number offset from the beginning 
of the series:

>> a: [a b c]
== [a b c]
>> b: skip a 2
== [c]
>> index? b
== 3
>> insert next a 'd
== [b c]
>> b
== [b c]
>> index? b
== 3

List offsets are pointers to the associated list element.

>> a: make list! [a b c]
== make list! [a b c]
>> b: skip a 2
== make list! [c]
>> index? b
== 3
>> insert next a 'd
== make list! [b c]
>> b
== make list! [c]
>> index? b
== 4


If you are indexing your data and your data in in a block, you need 
to update your index with almost every insertion and removal because 
the references to latter positions of the block in the index will 
be invalid. With list insertion and removal, external references 
are likely to still be valid unless the referenced elements themselves 
are deleted. If you are sure to delete the reference from the index 
(or replace it with nones) the rest of the index should be OK. New 
index references can just be tacked on the end, or put into the first 
empty entry. This makes live indexes a lot more practical.


On the down side, if you are using lists and they are long enough 
to make linear searches impractical, you really do need an external 
index for them to be useful. Also you need to balance the overhead 
and complexity of keeping the indexes updated against their benefit. 
This technique is not for the faint of heart unless you can get some 
guru to do algorithms for you.
Group: !Cheyenne ... Discussions about the Cheyenne Web Server [web-public]
Graham:
14-Jul-2007
and from Cheyenne


## Error in [uniserve] : On-received call failed with error: make 
object! [
    code: 305
    type: 'script
    id: 'invalid-arg
    arg1: none
    arg2: none
    arg3: none
    near: [parse/all data [
            some [
                s: to bound e: (
                    if e <> s [
                        either wrt? [
                            insert/part tmp/port s skip e -2
                        ] [
                            insert/part tail req/in/content s e
                        ]
                    ]
                )
                s: bound [
                    "--" to end s: break
                    | thru crlfcrlf e: (
                        insert/part tail req/in/content s e

                        if wrt?: to logic! find/part s "Content-Type" e [

                            append tmp/files name: make-tmp-filename

                            repend req/in/content [mold name crlf]
                            if tmp/port [close tmp/port]
                            tmp/port: open/mode name [
                                binary direct no-wait write new
                            ]
                        ]
                    )
                ]
            ]
        ]
        tmp/buffer: either
    ]
    where: 'process-content
] !
Dockimbel:
20-Dec-2007
HOW-TO make Cheyenne work with PHP for non-Windows OS


The purpose of the following patch is to make FastCGI in PHP work 
the same on all OSes.


1) If you have PHP v5.2.1 or higher with sources, you can skip 2) 
& 3) else :

2) Download latest PHP sources from http://www.php.net/downloads.php
3) Untar the archive anywhere yo want
4) Go to PHP install folder
5) Patching PHP source :

	Open a REBOL console, then :

;---- cut'n paste the following code in REBOL's console ----

patch-php: has [buffer pos][
	target: %sapi/cgi/fastcgi.c
	if none? attempt [buffer: read target][
		print "unable to find the file to patch!!"
		exit
	]
	either parse buffer [
		thru "int fcgi_accept_request("
		to "if (req->fd >= 0) {"
		pos: to end
	][
		insert pos "^/^-^-^-^-break;^/^-^-^-^-"
		write target buffer
		print "patch applied."
	][
		print "failed to locate the line to patch!!"
	]
]

patch-php
;---- end of code ----
		
6) Once the patch is applied :

	> ./configure --enable-fastcgi
	> make
	> sudo make install
	
7) Check if everything is ok :

	> php-cgi -h
	...
	you should see a -b option listed meaning you got proper
	FastCGI support.
	
	If it fails (occured on OSX), try with a full path instead :
	
	> /usr/local/bin/php-cgi -h
	

8) Edit Cheyenne's config file (httpd.cfg) to set the correct option 
in the PHP section. Non-Windows users have to also set the new 'delay 
option.
Will:
21-May-2008
impressed! 8) I finally gave another try at php support in cheyenne 
and after patching fastcgi.c as suggested it now works like a charm.

If you are on os x and use macports, here is a way to patch and compile:

sudo port install php5 +mysql5 +fastcgi
sudo port uninstall php5
cd /opt/local/var/macports/distfiles/php5/
sudo tar -xjf php-5.2.6.tar.bz2
>> run patch below
tar -cjf php-5.2.6.tar.bz2 php-5.2.6
sudo port install php5 +mysql5 +fastcgi checksum.skip=yes

copy of Dockimbel's patch with path fixed for this example

;---- cut'n paste the following code in REBOL's console ----

patch-php: has [buffer pos][ target: %php-5.2.6/sapi/cgi/fastcgi.c 
if none? attempt [buffer: read target][ print "unable to find the 
file to patch!!" exit ] either parse buffer [ thru "int fcgi_accept_request(" 
to "if (req->fd >= 0) {" pos: to end ][ insert pos "^/^-^-^-^-break;^/^-^-^-^-" 
write target buffer print "patch applied." ][ print "failed to locate 
the line to patch!!" ] ]
patch-php ;---- end of code ----
Robert:
12-Jun-2009
I have a problem, that after some running time Cheyenne seems to 
get into an unstable state and my REST shopping-cart isn't working 
any longer. I got this error in the trace.log, which seems to be 
Cheyenne internal:


5/6-10:09:48.142823-## Error in [task-handler-40014] : Make object! 
[                                                                
                 
    code: 501                                  
                                                                 
                                      
    type: 'access         
                                                                 
                                                           
    id: 
'not-open                                                        
                                                                 
            
    arg1: "Port"                                    
                                                                 
                                 
    arg2: none                 
                                                                 
                                                      
    arg3: 
none                                                             
                                                                 
          
    near: [parse/all current: fourth entry [          
                                                                 
                               
            any [                
                                                                 
                                                    
            
    end break                                                    
                                                                 
        
                | "#[" copy value to #"]" skip (        
                                                                 
                             
                    append out reform 
[                                                                
                                               
                 
       " prin any [pick cat"                                     
                                                                 
   
                        locale/id? value                     
                                                                 
                        
                        mold value #"]" 
                                                                 
                                             
                   
 ]                                                               
                                                                 
 
                )                                              
                                                                 
                      
                | "<%" [#"=" (append out " 
prin ") | none]                                                  
                                          
                copy value 
[to "%>" | none] 2 skip (                                        
                                                          
      
              if value [repend out [value #" "]]                 
                                                                 
              
                )                                 
                                                                 
                                   
                | s: copy value 
[any [e: "<%" :e break | e: "#[" :e break | skip]] e: (          
                                                     
           
         append out reform [" txt" index? s offset? s e #" "]    
                                                                 
         
                )                                      
                                                                 
                              
            ]                     
                                                                 
                                                   
        ]]   
                                                                 
                                                                 
       
    where: 'confirm                                      
                                                                 
                            
] !                                 
                                                                 
                                                 
5/6-23:01:46.501455-## 
Error in [task-handler-40014] : Make object! [                   
                                                              
  
  code: 501                                                      
                                                                 
                  
    type: 'access                             
                                                                 
                                       
    id: 'not-open        
                                                                 
                                                            
    
arg1: "Port"                                                     
                                                                 
                
    arg2: none                                  
                                                                 
                                     
    arg3: none             
                                                                 
                                                          
    near: 
[unless no-lang [                                                
                                                                 
          
            id: locale/lang                           
                                                                 
                               
            locale/set-default-lang 
                                                                 
                                                 
        ]      
                                                                 
                                                                 
     
        out: make                                          
                                                                 
                          
    ]                                 
                                                                 
                                               
    where: 'confirm 
                                                                 
                                                                 

] !
1 / 211[1] 23