<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: parse-int-values code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Thu, 07 Aug 2008 14:24:32 GMT</pubDate>
    <description>DZone Snippets: parse-int-values code</description>
    <item>
      <title>Parse multiple, independently fixed length, integer values from a string</title>
      <link>http://snippets.dzone.com/posts/show/1494</link>
      <description>&lt;code&gt;&lt;br /&gt;parse-int-values: func [&lt;br /&gt;    "Parses and returns integer values, each &lt;n&gt; chars long in a string."&lt;br /&gt;    input [any-string!]&lt;br /&gt;    spec [block!] "Dialected block of commands: &lt;n&gt;, skip &lt;n&gt;, done, char, or string"&lt;br /&gt;    /local&lt;br /&gt;        gen'd-rules ; generated rules&lt;br /&gt;        result      ; what we return to the caller&lt;br /&gt;        emit emit-data-rule emit-skip-rule emit-literal-rule emit-data&lt;br /&gt;        digit= n= literal=&lt;br /&gt;        int-rule= skip-rule= literal-rule= done= build-rule=&lt;br /&gt;        data-rule skip-rule&lt;br /&gt;][&lt;br /&gt;    ; This is where we put the rules we build; our gernated parse rules.&lt;br /&gt;    gen'd-rules: copy []&lt;br /&gt;    ; This is where we put the integer results&lt;br /&gt;    result: copy []&lt;br /&gt;&lt;br /&gt;    ; helper functions&lt;br /&gt;    emit: func [rule n] [append gen'd-rules replace copy rule 'n n]&lt;br /&gt;    emit-data-rule: func [n] [emit data-rule n]&lt;br /&gt;    emit-skip-rule: func [n] [emit skip-rule n]&lt;br /&gt;    emit-literal-rule: func [value] [append gen'd-rules value]&lt;br /&gt;    emit-data: does [append result to integer! =chars]&lt;br /&gt;&lt;br /&gt;    ; Rule templates; used to generate rules&lt;br /&gt;    ;data-rule: [copy =chars n digit= (append result to integer! =chars)]&lt;br /&gt;    data-rule: [copy =chars n digit= (emit-data)]&lt;br /&gt;    skip-rule: [n skip]&lt;br /&gt;&lt;br /&gt;    ; helper parse rules&lt;br /&gt;	digit=: charset [#"0" - #"9"]&lt;br /&gt;    n=: [set n integer!]&lt;br /&gt;    literal=: [set lit-val [char! | any-string!]]&lt;br /&gt;&lt;br /&gt;    ; Rule generation helper parse rules&lt;br /&gt;    int-rule=: [n= (emit-data-rule n)]&lt;br /&gt;    skip-rule=: ['skip n= (emit-skip-rule n)]&lt;br /&gt;    literal-rule=: [literal= (emit-literal-rule lit-val)]&lt;br /&gt;    done=: ['done (append gen'd-rules [to end])]&lt;br /&gt;&lt;br /&gt;    ; This generates the parse rules used against the input&lt;br /&gt;    build-rule=: [some [skip-rule= | int-rule= | literal-rule=] opt done=]&lt;br /&gt;&lt;br /&gt;    ; We parse the spec they give us, and use that to generate the&lt;br /&gt;    ; parse rules used against the actual input. If the spec parse&lt;br /&gt;    ; fails, we return none (maybe we should throw an error though);&lt;br /&gt;    ; if the data parse fails, we return false; otherwise they get&lt;br /&gt;    ; back a block of integers. Have to decide what to do if they&lt;br /&gt;    ; give us negative numbers as well.&lt;br /&gt;    either parse spec build-rule= [&lt;br /&gt;        either parse input gen'd-rules [result] [false]&lt;br /&gt;    ] [none]&lt;br /&gt;]&lt;br /&gt;comment {&lt;br /&gt;    test: func [val spec] [print mold parse-int-values val spec]&lt;br /&gt;    test "20060228T190000" [4 2 2 skip 1 2 2 2]&lt;br /&gt;    test "20060228T190000" [4 2 2 #"T" 2 2 2]&lt;br /&gt;    test "20060228T190000Z" [4 2 2 #"T" 2 2 2 #"Z"]&lt;br /&gt;    test "20060228T190000Z" [4 2 2 #"T" 2 2 2 done]&lt;br /&gt;    test %2006021509450004.jpg [4 2 2 2 2 4 skip 4]&lt;br /&gt;    test %2006021509450004.jpg [4 2 2 2 2 4 done]&lt;br /&gt;    ; tests that *should* fail&lt;br /&gt;    ; Bad spec&lt;br /&gt;    test "20060228T190000Z" [4 2 x #"T" 2 2 2]&lt;br /&gt;    test "20060228T190000Z" [4 2 2 #"T" 2.5 2 2]&lt;br /&gt;    ; Bad input&lt;br /&gt;    test "20060228T190000Z" [4 2 2 #"T" 2 2 2]&lt;br /&gt;    test "2000228T190000Z" [4 2 2 #"T" 2 2 2 done]&lt;br /&gt;    test "20060228x190000Z" [4 2 2 #"T" 2 2 2 done]&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 16 Feb 2006 00:28:44 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1494</guid>
      <author>gregg.irwin (Gregg Irwin)</author>
    </item>
  </channel>
</rss>
