Last active
December 18, 2024 17:34
-
-
Save kddnewton/cdd86ffab5235ea6abcb005978ded7e4 to your computer and use it in GitHub Desktop.
Revisions
-
kddnewton revised this gist
Jun 10, 2022 . 1 changed file with 5 additions and 11 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ require "json" struct = { "a" => 1, "b" => 2, "c" => [1, 2, 3], "d" => [{ "e" => 3 }, nil, false, true, [], {}] } source = JSON.dump(struct) tokens = [] @@ -22,9 +22,6 @@ def parse_array(tokens) result = [] loop do item, tokens = parse_item(tokens) @@ -39,9 +36,6 @@ def parse_array(tokens) def parse_object(tokens) result = {} loop do tokens => [String => key, :":", *tokens] @@ -57,10 +51,10 @@ def parse_object(tokens) def parse_item(tokens) case tokens in [:"[", :"]", *rest] then [[], rest] in [:"[", *rest] then parse_array(rest) in [:"{", :"}", *rest] then [{}, rest] in [:"{", *rest] then parse_object(rest) in [FalseClass | Integer | NilClass | String | TrueClass => value, *rest] [value, rest] end -
kddnewton revised this gist
Jun 10, 2022 . 1 changed file with 42 additions and 35 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,59 +10,66 @@ tokens << case source.strip when /\A[\{\}\[\],:]/ then $&.to_sym when /\A(\d+)/ then $1.to_i when /\A"([^"]*?)"/ then $1 when /\A(true|false)/ then $1 == "true" when /\Anull/ then nil else raise end source = $' end def parse_array(tokens) result = [] if tokens in [:"]", *rest] return result, rest end loop do item, tokens = parse_item(tokens) result << item case tokens in [:"]", *rest] then return result, rest in [:",", *rest] then tokens = rest end end end def parse_object(tokens) result = {} if tokens in [:"}", *rest] return result, rest end loop do tokens => [String => key, :":", *tokens] value, tokens = parse_item(tokens) result[key] = value case tokens in [:"}", *rest] then return result, rest in [:",", *rest] then tokens = rest end end end def parse_item(tokens) case tokens in [:"[", *rest] parse_array(rest) in [:"{", *rest] parse_object(rest) in [FalseClass | Integer | NilClass | String | TrueClass => value, *rest] [value, rest] end end def parse(tokens) parse_item(tokens) => [value, []] value end p struct p parse(tokens) -
kddnewton created this gist
Jun 10, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,68 @@ require "json" struct = { a: 1, b: 2, c: [1, 2, 3], d: [{ e: 3 }, nil, false, true, [], {}] } source = JSON.dump(struct) tokens = [] index = 0 until source.empty? tokens << case source.strip when /\A[\{\}\[\],:]/ then $&.to_sym when /\A(\d+)/ then $1.to_i when /\A"([^"]*?)"/ then $1 when /\Anull/ then nil when /\Atrue/ then true when /\Afalse/ then false else raise end source = $' end def parse_item(tokens) case tokens in [:"{", *rest] count = 1 index = rest.index { (count += { "{": 1, "}": -1 }.fetch(_1, 0)) == 0 } [parse_object(rest[0...index]), rest[(index + 1)..]] in [:"[", *rest] count = 1 index = rest.index { (count += { "[": 1, "]": -1 }.fetch(_1, 0)) == 0 } [parse_array(rest[0...index]), rest[(index + 1)..]] in [value, *rest] [value, rest] end end def parse_object(tokens) return {} if tokens in [] tokens => [String => key, :":", *rest] case parse_item(rest) in item, [:",", *rest] then { key => item }.merge(parse_object(rest)) in item, [] then { key => item } end end def parse_array(tokens) return [] if tokens in [] case parse_item(tokens) in item, [:",", *rest] then [item] + parse_array(rest) in left, [] then [item] end end def parse(tokens) case tokens in [:"{", *rest, :"}"] then parse_object(rest) in [:"[", *rest, :"]"] then parse_array(rest) in [value] then value end end p struct p parse(tokens)