Skip to content

Instantly share code, notes, and snippets.

@technoweenie
Created January 12, 2011 12:11
Show Gist options
  • Save technoweenie/776081 to your computer and use it in GitHub Desktop.
Save technoweenie/776081 to your computer and use it in GitHub Desktop.
quick JSON example parser using parslet
require 'rubygems'
require 'parslet'
require 'pp'
def parse(klass, str)
parser = klass.new
puts "parsing #{str}"
pp parser.parse(str)
puts
rescue Parslet::ParseFailed => err
puts err, parser.root.error_tree
end
#parse Mini, "puts(123 + 456 + 3, 1)"
class Str < Parslet::Parser
rule(:space) { match('\s').repeat(1) }
rule(:space?) { space.maybe }
rule(:quote) { str('"') }
rule(:nonquote) { str('"').absnt? >> any }
rule(:escape) { str('\\') >> any }
rule(:string) { quote >> (escape | nonquote).repeat(1).as(:str) >> quote }
root :string
end
parse Str, %("test")
parse Str, %("\\"test\\"")
class JSON < Parslet::Parser
rule(:space) { match('\s').repeat(1) }
rule(:space?) { space.maybe }
rule(:quote) { str('"') }
rule(:nonquote) { str('"').absnt? >> any }
rule(:comma) { str(',') >> space? }
rule(:colon) { str(':') >> space? }
rule(:escape) { str('\\') >> any }
rule(:integer) { match['0-9'].repeat(1).as(:int) >> space? }
rule(:string) { quote >> (escape | nonquote).repeat(1).as(:str) >> quote }
rule(:value) { string | integer }
rule(:array_list) { value >> (comma >> value).repeat }
rule(:array) { match['\['] >> array_list.as(:array) >> match['\]'] }
rule(:hash_pair) { string.as(:key) >> colon >> object.as(:value) }
rule(:hash_list) { hash_pair >> (comma >> hash_pair).repeat }
rule(:hash) { match['{'] >> hash_list.as(:hash) >> match['}'] }
rule(:object) { hash | array | string | integer }
root :object
end
parse JSON, %("abc")
parse JSON, %(123)
parse JSON, %([1,2,3])
parse JSON, %({"a": 1, "b": 2, "c": [1,2,3], "d": ["a", "b"], "e": {"e": "\\"five\\""}})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment