class NestedText::InlineParser

A LL(1) recursive descent parser for inline NT types.

Public Class Methods

new(line) click to toggle source
# File lib/nestedtext/inline_parser.rb, line 9
def initialize(line)
  @inline_scanner = InlineScanner.new(line)
end

Public Instance Methods

parse() click to toggle source
# File lib/nestedtext/inline_parser.rb, line 13
def parse
  result = parse_any
  unless @inline_scanner.empty?
    raise Errors::ParseInlineExtraCharactersAfterDelimiterError.new(@inline_scanner.line, @inline_scanner.pos,
                                                                    @inline_scanner.remaining)
  end
  result
end

Private Instance Methods

consume_whitespaces() click to toggle source
# File lib/nestedtext/inline_parser.rb, line 41
def consume_whitespaces
  @inline_scanner.read_next while !@inline_scanner.empty? && [' ', "\t"].include?(@inline_scanner.peek)
end
parse_any() click to toggle source
# File lib/nestedtext/inline_parser.rb, line 24
def parse_any
  return nil if @inline_scanner.peek.nil?

  consume_whitespaces # Leading
  result = case @inline_scanner.peek
           when '{'
             parse_dict
           when '['
             parse_list
           else # Inline string
             parse_string
           end

  consume_whitespaces # Trailing
  result
end
parse_dict() click to toggle source
# File lib/nestedtext/inline_parser.rb, line 76
def parse_dict
  result = {}
  loop do
    @inline_scanner.read_next
    break if result.empty? && @inline_scanner.peek == '}'

    key = parse_key
    value = parse_any
    result[key] = value
    break unless @inline_scanner.peek == ','
  end
  if @inline_scanner.empty?
    raise Errors::ParseInlineNoClosingDelimiterError.new(@inline_scanner.line,
                                                         @inline_scanner.pos)
  end
  parse_dict_last_char
  result
end
parse_dict_last_char() click to toggle source
# File lib/nestedtext/inline_parser.rb, line 68
def parse_dict_last_char
  last_char = @inline_scanner.read_next
  return if last_char == '}'

  raise Errors::ParseInlineDictSyntaxError.new(@inline_scanner.line,
                                               @inline_scanner.pos - 1, last_char)
end
parse_key() click to toggle source
# File lib/nestedtext/inline_parser.rb, line 55
def parse_key
  key = []
  until @inline_scanner.empty? || [':', '{', '}', '[', ']', ','].include?(@inline_scanner.peek)
    key << @inline_scanner.read_next
  end
  if @inline_scanner.empty?
    raise Errors::ParseInlineNoClosingDelimiterError.new(@inline_scanner.line,
                                                         @inline_scanner.pos)
  end
  parse_key_last_char(key)
  key.join.strip
end
parse_key_last_char(key) click to toggle source
# File lib/nestedtext/inline_parser.rb, line 45
def parse_key_last_char(key)
  last_char = @inline_scanner.read_next
  if last_char == '}' && key.empty?
    raise Errors::ParseInlineMissingValueError.new(@inline_scanner.line, @inline_scanner.pos - 1)
  end
  return if last_char == ':'

  raise Errors::ParseInlineDictKeySyntaxError.new(@inline_scanner.line, @inline_scanner.pos - 1, last_char)
end
parse_list() click to toggle source
# File lib/nestedtext/inline_parser.rb, line 108
def parse_list
  result = []
  loop do
    @inline_scanner.read_next
    break if result.empty? && @inline_scanner.peek == ']'

    result << parse_any
    break unless @inline_scanner.peek == ','
  end
  if @inline_scanner.empty?
    raise Errors::ParseInlineNoClosingDelimiterError.new(@inline_scanner.line,
                                                         @inline_scanner.pos)
  end
  parse_list_last_char(result)
  result
end
parse_list_last_char(result) click to toggle source
# File lib/nestedtext/inline_parser.rb, line 95
def parse_list_last_char(result)
  last_char = @inline_scanner.read_next
  return unless last_char != ']'

  if result[-1] == ''
    raise Errors::ParseInlineMissingValueError.new(@inline_scanner.line,
                                                   @inline_scanner.pos - 1)
  else
    raise Errors::ParseInlineListSyntaxError.new(@inline_scanner.line,
                                                 @inline_scanner.pos - 1, last_char)
  end
end
parse_string() click to toggle source
# File lib/nestedtext/inline_parser.rb, line 125
def parse_string
  inline_string = []
  until @inline_scanner.empty? || ['{', '}', '[', ']', ','].include?(@inline_scanner.peek)
    inline_string << @inline_scanner.read_next
  end
  inline_string.join.rstrip # Trim trailing whitespaces that lead up to next break point.
end