Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: Parse versus Regular Expressions

From: brett:codeconscious at: 5-Apr-2003 13:50

Hi Joel,
> I'm quite willing to be educated, so here's another example. I'll > state the problem, then wait for suggestions on how to use PARSE > before I show the solution (using Python's RE engine). Lest I be > accused of theory, I'll point out that this is a disguised and > simplified version of a program I've recently written for Real Work.
Well I had a go. I decided to just attack it using the first approach that came to mind. My prelinary thinking was that there is two themes here, control (sequencing, errors) and character stream (accumulating sentences). So the plan was (1) break into lines (2) break into fields (3) filter (4) process the character stream. That is basically what I've carried into PARSE rules. To accomplish this I've had to make Parse jump around a bit by changing the input pointer a few times and by rewriting the rules as things proceed. If this was for real work, then: EITHER one-off? [ use it after more testing ][ rewrite it with a more robust solution] Regards, Brett. REBOL [ Title: "Joel's PARSE problem." Author: "Brett Handley" Comments: { 1. First "blunt parse attack" approach. 2. I don't like the way I am stepping through character data. 3. More of a concern, in this approach it is difficult to see any "value add" from PARSE over just writing a non-parse parser. 4. I posted it because despite being ugly, I've expended the effort, so may as well offer it as a target of critique! :) 5. Way to sensitive to a change in character positions! 6. Not tested thoroughly - only on the data in the code. } ] data: decompress #{ 789CA5D25D0AC3200C00E0ABE46DD087E24FF7738FED02B6CD9820DA55A5D75F EA2C8C958DD9459F8C7C2644C628385C6EDA036D051E6D40DB610D45211893B4 F8CC31910FCFAE0C597B2279F2254145FEED356FC940DD6FEBF7E9EDAB44C0A4 8D815E7B350CA8C62D9E4CDEA18236866C3ABB0BD062A7A24770571AD03DCE03 0237F6F8F191E4F13C8F23CD17C1281FCA9A5CD7D724EFF4FDEE2F5F68F11EAA 35717B80020000 } ; ------------------------------------------------- ; PARSE RULES ; ------------------------------------------------- r_digit: charset {0123456789} r_char: complement charset { ^-} r_seq1: [ copy v_lineseq1 6 r_digit (v_lineseq1: to integer! v_lineseq1) ] r_seq2: [ copy v_lineseq2 8 r_digit (v_lineseq2: to integer! v_lineseq2) ] r_body: [ :v_linebody 66 [ #"." (end-of-sentence) | copy v_char r_char (character v_char) | skip (whitespace) ] 8 skip ] r_ignore: [none] r_error: [ (emit join "ERROR: " copy/part v_linestart v_lineend) none ] ; Splits each line into fields, checks sequencing. r_line: [ v_linestart: r_seq1 v_linebody: 66 skip r_seq2 v_lineend: (r_filterdynamic: dynamic-filter-rule?) r_filterdynamic ] ; ------------------------------------------------- ; Functions call during parse process ; ------------------------------------------------- dynamic-filter-rule?: does [ either all [ any [none? seq1 v_lineseq1 >= seq1] any [none? seq2 v_lineseq2 >= seq2] ] [ seq1: v_lineseq1 seq2: v_lineseq2 either v_linebody/1 = #"*" [[none]] [r_body] ] [r_error] ] character: func [ch] [insert tail out ch] whitespace: does [ if all [not empty? out #" " <> last out] [ insert tail out #" " ] ] end-of-sentence: does [ character #"." emit out out: copy {} ] emit: :print ; ------------------------------------------------- ; HERE WE GO ; ------------------------------------------------- ; ; Initialise ; v_lineseq1: v_lineseq2: v_linebody: v_linestart: v_lineend: seq1: seq2: r_filterdynamic: none out: copy {} either parse/all data [any r_line] [ if not empty? out [print "ERROR last sentence incomplete."] ] [print "ERROR The file does not conform to the expected format."] HALT