Skip to content

Instantly share code, notes, and snippets.

@NigelThorne
Created February 5, 2013 23:48
Show Gist options
  • Save NigelThorne/4718832 to your computer and use it in GitHub Desktop.
Save NigelThorne/4718832 to your computer and use it in GitHub Desktop.
composing parslet parsers
require 'rubygems'
require 'parslet'
#This needs a few more 'as' calls to annotate the output
class JSONParser < Parslet::Parser
def initialize(number_parser)
@number_parser
end
rule(:space) { match('[\s\n]').repeat(1)}
rule(:space?) { space.maybe }
rule(:digit) { match('[0-9]') }
rule(:hexdigit) { match('[0-9a-fA-F]') }
rule(:comma) { space? >> str(',') >> space? }
rule(:colon) { space? >> str(':') >> space? }
rule(:number) { @number_parser }
rule(:escaped_character) { str('\\') >> (match('["\\\\/bfnrt]') | (str('u') >> hexdigit.repeat(4,4))) }
rule(:string){
str('"') >> (
escaped_character | str('"').absent? >> any)
).repeat.as(:string) >> str('"')
}
rule(:value){
(string |
number |
object |
array |
str('true').as(:true) |
str('false').as(:false) |
str('null').as(:null)).as(:val)
}
rule(:entry) { string >> colon >> value }
rule(:pair_list) { entry>> (comma >> entry).repeat }
rule(:object) { str('{') >> space? >> pair_list.maybe >> space? >> str('}') }
rule(:value_list) { value >> (comma >> value).repeat }
rule(:array) { str('[') >> space? >> value_list.maybe >> space? >> str(']')}
rule(:json) { space? >> value >> space?}
root(:json)
end
class NumberParser < ParsletParser
rule(:space) { match('[\s\n]').repeat(1)}
rule(:space?) { space.maybe }
rule(:digit) { match('[0-9]') }
rule(:number) {space? >> str('-').maybe >>
(str('0') | (match('[1-9]') >> digit.repeat)) >>
(str('.') >> digit.repeat).maybe >>
((str('e')| str('E')) >> (str('+')|str('-')).maybe >> digit.repeat ).maybe}
root(:number)
end
json_parser = JSONParser.new(NumberParser.new)
@JeremyNevill
Copy link

Nigel, just a quick note to say thanks for your help... used your suggestion and it fits my needs perfectly, most appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment