Skip to content

Instantly share code, notes, and snippets.

@qtxie
Forked from dockimbel/JSON.red
Last active October 6, 2016 22:39
Show Gist options
  • Select an option

  • Save qtxie/445dff8fba8a9eb8b82df7f3a055841d to your computer and use it in GitHub Desktop.

Select an option

Save qtxie/445dff8fba8a9eb8b82df7f3a055841d to your computer and use it in GitHub Desktop.

Revisions

  1. qtxie revised this gist Oct 6, 2016. No changes.
  2. qtxie revised this gist Oct 6, 2016. No changes.
  3. qtxie revised this gist Oct 6, 2016. 1 changed file with 72 additions and 5 deletions.
    77 changes: 72 additions & 5 deletions JSON.red
    Original file line number Diff line number Diff line change
    @@ -1,22 +1,22 @@
    Red [
    Title: "JSON parser"
    File: %json.red
    Author: "Nenad Rakocevic"
    Author: "Nenad Rakocevic, Qingtian Xie"
    License: "BSD-3 - https://github.com/red/red/blob/master/BSD-3-License.txt"
    ]

    json: context [
    quoted-char: charset {"\/bfnrt}
    quoted-char: charset {"\/bfnrt}
    exponent: charset "eE"
    sign: charset "+-"
    digit-nz: charset "123456789"
    digit: append copy digit-nz #"0"
    hexa: union digit charset "ABCDEabcde"
    blank: charset " ^(09)^(0A)^(0D)"
    ws: [any blank]
    ws: [any blank]
    dbl-quote: #"^""
    s: e: none
    s: e: none

    decode-str: func [start end /local new rule s][
    new: copy/part start back end ;-- exclude ending quote
    rule: [
    @@ -26,6 +26,7 @@ json: context [
    | #"f" (s/1: #"^(0C)")
    | #"n" (s/1: #"^/")
    | #"r" (s/1: #"^M")
    | #"t" (s/1: #"^-")
    | #"u" 4 hexa
    ]
    | skip
    @@ -34,6 +35,26 @@ json: context [
    parse new rule
    new
    ]

    encode-str: func [str [string!] buffer [string!] /local start rule s][
    append buffer #"^""
    start: tail buffer
    append buffer str
    rule: [
    any [
    change #"^H" "\b"
    | change #"^(0C)" "\f"
    | change #"^/" "\n"
    | change #"^M" "\r"
    | change #"\" "\\"
    | change #"^-" "\t"
    | change #"^"" {\"}
    | skip
    ]
    ]
    parse start rule
    append buffer #"^""
    ]

    value: [
    string keep (decode-str s e)
    @@ -61,4 +82,50 @@ json: context [
    decode: function [data [string!] return: [block! object!]][
    parse data [collect any [blank | object-rule | array]]
    ]

    encode-into: function [data [any-type!] buffer [string!]][
    case [
    map? data [
    append buffer #"{"
    either zero? length? data [
    append buffer #"}"
    ][
    foreach [k v] data [
    encode-into k buffer
    append buffer #":"
    encode-into v buffer
    append buffer #","
    ]
    change back tail buffer #"}"
    ]
    ]
    block? data [
    append buffer #"["
    either empty? data [
    append buffer #"]"
    ][
    foreach v data [
    encode-into v buffer
    append buffer #","
    ]
    change back tail buffer #"]"
    ]
    ]
    string? data [
    encode-str data buffer
    ]
    any [logic? data number? data][
    append buffer mold data
    ]
    true [
    encode-into mold data buffer
    ]
    ]
    ]

    encode: function [data return: [string!]][
    buffer: make string! 1000
    encode-into data buffer
    buffer
    ]
    ]
  4. @dockimbel dockimbel revised this gist Oct 19, 2015. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions JSON.red
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,6 @@ json: context [
    blank: charset " ^(09)^(0A)^(0D)"
    ws: [any blank]
    dbl-quote: #"^""
    neg?: no
    s: e: none

    decode-str: func [start end /local new rule s][
    @@ -46,7 +45,7 @@ json: context [
    | array
    ]

    number: [opt #"-" s: some digit opt [dot some digit opt [exponent sign 1 3 digit]] e:]
    number: [s: opt #"-" some digit opt [dot some digit opt [exponent sign 1 3 digit]] e:]

    string: [dbl-quote s: any [#"\" [quoted-char | #"u" 4 hexa] | dbl-quote break | skip] e:]

  5. @dockimbel dockimbel revised this gist Oct 19, 2015. 1 changed file with 18 additions and 25 deletions.
    43 changes: 18 additions & 25 deletions JSON.red
    Original file line number Diff line number Diff line change
    @@ -6,16 +6,16 @@ Red [
    ]

    json: context [
    quoted-char: charset {"\/bfnrt}
    quoted-char: charset {"\/bfnrt}
    exponent: charset "eE"
    sign: charset "+-"
    digit-nz: charset "123456789"
    digit: append copy digit-nz #"0"
    hexa: union digit charset "ABCDEabcde"
    ws: charset " ^(09)^(0A)^(0D)"
    blank: charset " ^(09)^(0A)^(0D)"
    ws: [any blank]
    dbl-quote: #"^""
    neg?: no
    key?: no
    s: e: none

    decode-str: func [start end /local new rule s][
    @@ -33,40 +33,33 @@ json: context [
    ]
    ]
    parse new rule
    if key? [new: load new key?: no]
    new
    ]

    number: [
    (neg?: no) opt [#"-" (neg?: yes)]
    s: some digit opt [dot some digit opt [exponent sign 1 3 digit]] e:
    keep (load copy/part s e)
    ]

    string: [
    dbl-quote s: any [#"\" [quoted-char | #"u" 4 hexa] | dbl-quote break | skip] e:
    keep (decode-str s e)
    ]


    value: [
    string
    | object-rule
    | array
    | number
    string keep (decode-str s e)
    | number keep (load copy/part s e)
    | "true" keep (true)
    | "false" keep (false)
    | "null" keep (none)
    | object-rule
    | array
    ]

    number: [opt #"-" s: some digit opt [dot some digit opt [exponent sign 1 3 digit]] e:]

    string: [dbl-quote s: any [#"\" [quoted-char | #"u" 4 hexa] | dbl-quote break | skip] e:]

    couple: [ws string keep (load decode-str s e) ws #":" ws value]

    object-rule: [
    #"{" collect set list any [
    any ws (key?: yes) string any ws #":" any ws value [#"," | any ws #"}" break]
    ] keep (make map! list)
    #"{" collect set list opt [any [couple #","] couple] ws #"}"
    keep (make map! list)
    ]

    array: [#"[" collect any [any ws [value [#"," | any ws #"]" break] | any ws #"]" break]]]
    array: [#"[" collect opt [any [ws value #","] ws value] ws #"]"]

    decode: function [data [string!] return: [block! object!]][
    parse data [collect any [ws | object-rule | array]]
    parse data [collect any [blank | object-rule | array]]
    ]
    ]
  6. @dockimbel dockimbel revised this gist Oct 17, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion JSON.red
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@ json: context [
    digit-nz: charset "123456789"
    digit: append copy digit-nz #"0"
    hexa: union digit charset "ABCDEabcde"
    ws: charset " ^(09)^(0A)^(0D)"
    ws: charset " ^(09)^(0A)^(0D)"
    dbl-quote: #"^""
    neg?: no
    key?: no
  7. @dockimbel dockimbel revised this gist Oct 17, 2015. No changes.
  8. @dockimbel dockimbel revised this gist Oct 17, 2015. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions JSON.red
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@ json: context [
    digit-nz: charset "123456789"
    digit: append copy digit-nz #"0"
    hexa: union digit charset "ABCDEabcde"
    ws: charset " ^(09)^(0A)^(0D)"
    ws: charset " ^(09)^(0A)^(0D)"
    dbl-quote: #"^""
    neg?: no
    key?: no
    @@ -38,8 +38,8 @@ json: context [
    ]

    number: [
    (neg?: no) opt [#"-" neg?: yes]
    s: [#"0" | some digit-nz] opt [dot some digit opt [exponent sign 1 3 digit]] e:
    (neg?: no) opt [#"-" (neg?: yes)]
    s: some digit opt [dot some digit opt [exponent sign 1 3 digit]] e:
    keep (load copy/part s e)
    ]

    @@ -60,11 +60,11 @@ json: context [

    object-rule: [
    #"{" collect set list any [
    any ws (key?: yes) string #":" any ws value [#"," | any ws #"}" break]
    any ws (key?: yes) string any ws #":" any ws value [#"," | any ws #"}" break]
    ] keep (make map! list)
    ]

    array: [#"[" collect any [any ws value [#"," | any ws #"]" break]]]
    array: [#"[" collect any [any ws [value [#"," | any ws #"]" break] | any ws #"]" break]]]

    decode: function [data [string!] return: [block! object!]][
    parse data [collect any [ws | object-rule | array]]
  9. @dockimbel dockimbel revised this gist Jun 7, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion JSON.red
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@ Red [
    Title: "JSON parser"
    File: %json.red
    Author: "Nenad Rakocevic"
    License: "BSD-3 - https://github.com/dockimbel/Red/blob/master/BSD-3-License.txt"
    License: "BSD-3 - https://github.com/red/red/blob/master/BSD-3-License.txt"
    ]

    json: context [
  10. @dockimbel dockimbel revised this gist Jun 1, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion JSON.red
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@ json: context [
    digit-nz: charset "123456789"
    digit: append copy digit-nz #"0"
    hexa: union digit charset "ABCDEabcde"
    ws: charset " ^(09)^(0A)^(0D)"
    ws: charset " ^(09)^(0A)^(0D)"
    dbl-quote: #"^""
    neg?: no
    key?: no
  11. @dockimbel dockimbel created this gist Jun 1, 2015.
    72 changes: 72 additions & 0 deletions JSON.red
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,72 @@
    Red [
    Title: "JSON parser"
    File: %json.red
    Author: "Nenad Rakocevic"
    License: "BSD-3 - https://github.com/dockimbel/Red/blob/master/BSD-3-License.txt"
    ]

    json: context [
    quoted-char: charset {"\/bfnrt}
    exponent: charset "eE"
    sign: charset "+-"
    digit-nz: charset "123456789"
    digit: append copy digit-nz #"0"
    hexa: union digit charset "ABCDEabcde"
    ws: charset " ^(09)^(0A)^(0D)"
    dbl-quote: #"^""
    neg?: no
    key?: no
    s: e: none

    decode-str: func [start end /local new rule s][
    new: copy/part start back end ;-- exclude ending quote
    rule: [
    any [
    s: remove #"\" [
    #"b" (s/1: #"^H")
    | #"f" (s/1: #"^(0C)")
    | #"n" (s/1: #"^/")
    | #"r" (s/1: #"^M")
    | #"u" 4 hexa
    ]
    | skip
    ]
    ]
    parse new rule
    if key? [new: load new key?: no]
    new
    ]

    number: [
    (neg?: no) opt [#"-" neg?: yes]
    s: [#"0" | some digit-nz] opt [dot some digit opt [exponent sign 1 3 digit]] e:
    keep (load copy/part s e)
    ]

    string: [
    dbl-quote s: any [#"\" [quoted-char | #"u" 4 hexa] | dbl-quote break | skip] e:
    keep (decode-str s e)
    ]

    value: [
    string
    | object-rule
    | array
    | number
    | "true" keep (true)
    | "false" keep (false)
    | "null" keep (none)
    ]

    object-rule: [
    #"{" collect set list any [
    any ws (key?: yes) string #":" any ws value [#"," | any ws #"}" break]
    ] keep (make map! list)
    ]

    array: [#"[" collect any [any ws value [#"," | any ws #"]" break]]]

    decode: function [data [string!] return: [block! object!]][
    parse data [collect any [ws | object-rule | array]]
    ]
    ]