-
-
Save Eric-Guo/b001a7083839bf5fb7f7b56d90ba3196 to your computer and use it in GitHub Desktop.
JSON parser with pattern matching
This file contains 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 characters
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 /\A(true|false)/ then $1 == "true" | |
when /\Anull/ then nil | |
else raise | |
end | |
source = $' | |
end | |
def parse_array(tokens) | |
result = [] | |
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 = {} | |
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] 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 | |
end | |
def parse(tokens) | |
parse_item(tokens) => [value, []] | |
value | |
end | |
p struct | |
p parse(tokens) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment