Class: EDN::RubyEdnParser
- Inherits:
-
Object
- Object
- EDN::RubyEdnParser
- Defined in:
- lib/edn/ruby_edn_parser.rb
Instance Method Summary collapse
- #call_reader(reader) ⇒ Object
- #eof? ⇒ Boolean
- #escape_char(ch) ⇒ Object
- #finish_float(whole_part) ⇒ Object
-
#initialize(source, *extra) ⇒ RubyEdnParser
constructor
A new instance of RubyEdnParser.
- #read(return_nothing = false) ⇒ Object
- #read_basic(return_nothing = false) ⇒ Object
- #read_char ⇒ Object
- #read_collection(clazz, closing) ⇒ Object
- #read_digits(min_digits = 0) ⇒ Object
- #read_eof ⇒ Object
- #read_extension ⇒ Object
- #read_keyword ⇒ Object
- #read_list ⇒ Object
- #read_map ⇒ Object
- #read_meta ⇒ Object
- #read_number(leading = '') ⇒ Object
- #read_number_or_symbol ⇒ Object
- #read_slash ⇒ Object
- #read_string ⇒ Object
- #read_symbol(leading = '') ⇒ Object
- #read_symbol_chars ⇒ Object
- #read_vector ⇒ Object
- #unknown ⇒ Object
Constructor Details
#initialize(source, *extra) ⇒ RubyEdnParser
Returns a new instance of RubyEdnParser.
7 8 9 10 |
# File 'lib/edn/ruby_edn_parser.rb', line 7 def initialize(source, *extra) io = source.instance_of?(String) ? StringIO.new(source) : source @s = CharStream.new(io) end |
Instance Method Details
#call_reader(reader) ⇒ Object
146 147 148 149 150 151 152 |
# File 'lib/edn/ruby_edn_parser.rb', line 146 def call_reader(reader) if reader.instance_of? Symbol self.send(reader) else self.instance_exec(&reader) end end |
#eof? ⇒ Boolean
22 23 24 |
# File 'lib/edn/ruby_edn_parser.rb', line 22 def eof? @s.eof? end |
#escape_char(ch) ⇒ Object
120 121 122 123 124 125 126 |
# File 'lib/edn/ruby_edn_parser.rb', line 120 def escape_char(ch) return '\\' if ch == '\\' return "\n" if ch == 'n' return "\t" if ch == 't' return "\r" if ch == 'r' ch end |
#finish_float(whole_part) ⇒ Object
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/edn/ruby_edn_parser.rb', line 185 def finish_float(whole_part) result = whole_part if @s.current == '.' result += '.' @s.advance result = @s.digit? ? result + read_digits : result + '0' #puts "aaa: #{result}" end if @s.current == 'e' || @s.current == 'E' @s.advance result = result + 'e' + read_digits #puts "bbb: #{result}" end #puts result result.to_f end |
#read(return_nothing = false) ⇒ Object
12 13 14 15 16 17 18 19 20 |
# File 'lib/edn/ruby_edn_parser.rb', line 12 def read(return_nothing=false) = value = read_basic(return_nothing) if && value != NOTHING value.extend EDN::Metadata value. = end value end |
#read_basic(return_nothing = false) ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/edn/ruby_edn_parser.rb', line 154 def read_basic(return_nothing=false) @s.skip_ws ch = @s.current result = call_reader(READERS[ch]) while NOTHING.equal?(result) && !return_nothing @s.skip_ws result = call_reader(READERS[@s.current]) end result end |
#read_char ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/edn/ruby_edn_parser.rb', line 34 def read_char result = @s.advance @s.advance until @s.eof? break unless @s.digit? || @s.alpha? result += @s.current @s.advance end return result if result.size == 1 case result when 'newline' "\n" when 'return' "\r" when 'tab' "\t" when 'space' " " else raise "Unknown char #{result}" end end |
#read_collection(clazz, closing) ⇒ Object
252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/edn/ruby_edn_parser.rb', line 252 def read_collection(clazz, closing) result = clazz.new while true @s.skip_ws raise "Unexpected eof" if @s.eof? break if @s.current == closing next_value = read(true) result << next_value unless next_value == NOTHING end @s.advance result end |
#read_digits(min_digits = 0) ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/edn/ruby_edn_parser.rb', line 166 def read_digits(min_digits=0) result = '' if @s.current == '+' || @s.current == '-' result << @s.current @s.advance end n_digits = 0 while @s.current =~ /[0-9]/ n_digits += 1 result << @s.current @s.advance end raise "Expected at least #{min_digits} digits, found #{result}" unless n_digits >= min_digits result end |
#read_eof ⇒ Object
30 31 32 |
# File 'lib/edn/ruby_edn_parser.rb', line 30 def read_eof EOF end |
#read_extension ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/edn/ruby_edn_parser.rb', line 91 def read_extension @s.advance if @s.current == '{' @s.advance read_collection(Set, '}') elsif @s.current == "_" @s.advance x = read NOTHING else tag = read_symbol_chars value = read EDN.tagged_element(tag, value) end end |
#read_keyword ⇒ Object
115 116 117 118 |
# File 'lib/edn/ruby_edn_parser.rb', line 115 def read_keyword @s.advance read_symbol_chars.to_sym end |
#read_list ⇒ Object
235 236 237 238 |
# File 'lib/edn/ruby_edn_parser.rb', line 235 def read_list @s.advance read_collection(EDN::Type::List, ')') end |
#read_map ⇒ Object
245 246 247 248 249 250 |
# File 'lib/edn/ruby_edn_parser.rb', line 245 def read_map @s.advance array = read_collection(Array, '}') raise "Need an even number of items for a map" unless array.count.even? Hash[*array] end |
#read_meta ⇒ Object
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/edn/ruby_edn_parser.rb', line 216 def = [] @s.skip_ws while @s.current == '^' @s.advance << read_basic @s.skip_ws end = .reverse.reduce({}) do |acc, m| case m when Symbol then acc.merge(m => true) when EDN::Type::Symbol then acc.merge(:tag => m) else acc.merge(m) end end .empty? ? nil : end |
#read_number(leading = '') ⇒ Object
204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/edn/ruby_edn_parser.rb', line 204 def read_number(leading='') result = leading + read_digits if %w{. e E}.include? @s.current return finish_float(result) elsif @s.skip_past('M') || @s.skip_past('N') result.to_i else result.to_i end end |
#read_number_or_symbol ⇒ Object
64 65 66 67 68 69 |
# File 'lib/edn/ruby_edn_parser.rb', line 64 def read_number_or_symbol leading = @s.current @s.advance return read_number(leading) if @s.digit? read_symbol(leading) end |
#read_slash ⇒ Object
59 60 61 62 |
# File 'lib/edn/ruby_edn_parser.rb', line 59 def read_slash @s.advance Type::Symbol.new('/') end |
#read_string ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/edn/ruby_edn_parser.rb', line 128 def read_string @s.advance result = '' until @s.current == '"' raise "Unexpected eof" if @s.eof? if @s.current == '\\' @s.advance result << escape_char(@s.current) else result << @s.current end @s.advance end @s.advance result end |
#read_symbol(leading = '') ⇒ Object
107 108 109 110 111 112 113 |
# File 'lib/edn/ruby_edn_parser.rb', line 107 def read_symbol(leading='') token = leading + read_symbol_chars return true if token == "true" return false if token == "false" return nil if token == "nil" Type::Symbol.new(token) end |
#read_symbol_chars ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/edn/ruby_edn_parser.rb', line 71 def read_symbol_chars result = '' ch = @s.current while SYMBOL_INTERIOR_CHARS.include?(ch) result << ch ch = @s.advance end return result unless @s.skip_past('/') result << '/' ch = @s.current while SYMBOL_INTERIOR_CHARS.include?(ch) result << ch ch = @s.advance end result end |
#read_vector ⇒ Object
240 241 242 243 |
# File 'lib/edn/ruby_edn_parser.rb', line 240 def read_vector @s.advance read_collection(Array, ']') end |
#unknown ⇒ Object
26 27 28 |
# File 'lib/edn/ruby_edn_parser.rb', line 26 def unknown raise "Don't know what to do with #{@s.current} #{@s.current.class}" end |