class Jsonerino::Lexer
Constants
- SIMPLE_ESCAPE_SEQUENCES_MATCHER
- SIMPLE_TOKENS_MATCHER
Attributes
i[R]
Public Class Methods
new(contents)
click to toggle source
# File lib/jsonerino/lexer.rb, line 26 def initialize(contents) @contents = contents @i = 0 @l = 1 # Line number (row) @li = 1 # Character in current line (column) @c = contents[@i] end
Public Instance Methods
next_token()
click to toggle source
# File lib/jsonerino/lexer.rb, line 34 def next_token skip_whitespace while more_content? v = collect_simple_token return v if v # Numbers in JSON are only allowed to start with a minus sign return collect_number if number? return collect_string if @c == '"' return collect_id if Helpers.alphanumeric?(@c) raise "Unexpected character '#{@c}'" end nil end
Private Instance Methods
advance()
click to toggle source
# File lib/jsonerino/lexer.rb, line 70 def advance return unless more_content? @i += 1 @li += 1 c = @c @c = @contents[@i] c end
collect_escape_sequence()
click to toggle source
# File lib/jsonerino/lexer.rb, line 112 def collect_escape_sequence advance if (escape = Lexer::SIMPLE_ESCAPE_SEQUENCES_MATCHER.find { |x| x[0] == @c }) escape[1] elsif @c == 'u' collect_unicode_escape else @c end end
collect_id()
click to toggle source
# File lib/jsonerino/lexer.rb, line 80 def collect_id start_i = @li str = '' while @c && Helpers.alphanumeric?(@c) str += @c advance end Token.new Token::TOKEN_ID, str, start_i, @li, @l end
collect_number()
click to toggle source
# File lib/jsonerino/lexer.rb, line 134 def collect_number start_i = @li str_number = '' loop do str_number += @c advance break unless @c && (Helpers.numeric?(@c) || ['.', '-', '+', 'e', 'E'].include?(@c)) end number = str_number.match?(/[\.e]/i) ? str_number.to_f : str_number.to_i Token.new Token::TOKEN_NUMBER, number, start_i, @li, @l end
collect_simple_token()
click to toggle source
# File lib/jsonerino/lexer.rb, line 90 def collect_simple_token start_i = @li token = Lexer::SIMPLE_TOKENS_MATCHER.find { |x| x[0] == @c } return nil unless token Token.new token[1], advance, start_i, @li, @l end
collect_string()
click to toggle source
# File lib/jsonerino/lexer.rb, line 98 def collect_string start_i = @li advance str = '' while @c && @c != '"' str += @c == '\\' ? collect_escape_sequence : @c advance end advance Token.new Token::TOKEN_STRING, str, start_i, @li, @l end
collect_unicode_escape()
click to toggle source
# File lib/jsonerino/lexer.rb, line 124 def collect_unicode_escape str_number = 4.times.inject('0x') do |str| advance raise "Invalid unicode escape sequence #{@c}" unless Helpers.hex?(@c) str + @c end str_number.to_i.chr end
more_content?()
click to toggle source
# File lib/jsonerino/lexer.rb, line 146 def more_content? @i < @contents.length end
number?()
click to toggle source
# File lib/jsonerino/lexer.rb, line 56 def number? Helpers.numeric?(@c) || @c == '-' end
skip_whitespace()
click to toggle source
# File lib/jsonerino/lexer.rb, line 60 def skip_whitespace while [' ', "\n", "\t"].include?(@c) c = advance if c == "\n" @li = 1 @l += 1 end end end