@@ -321,6 +321,7 @@ def parse_array
321321 if is_strictly_empty ( value )
322322 @scanner . getch
323323 elsif value == "..." && @scanner . string . chars [ @scanner . charpos - 1 ] == '.'
324+ # just skip
324325 else
325326 arr << value
326327 end
@@ -437,71 +438,72 @@ def parse_string
437438 skip_whitespaces
438439 if peek_char ( 1 ) == '\\'
439440 # Ok this is a quoted string, skip
440- rstring_delimiter_missing = true
441- i = skip_to_character ( rstring_delimiter , start_idx : 1 )
441+ rstring_delimiter_missing = false
442+ end
443+
444+ i = skip_to_character ( rstring_delimiter , start_idx : 1 )
445+ next_c = peek_char ( i )
446+ if next_c
447+ i += 1
448+ # found a delimiter, now we need to check that is followed strictly by a comma or brace
449+ # or the string ended
450+ i = skip_whitespaces_at ( start_idx : i )
442451 next_c = peek_char ( i )
443- if next_c
444- i += 1
445- # found a delimiter, now we need to check that is followed strictly by a comma or brace
446- # or the string ended
447- i = skip_whitespaces_at ( start_idx : i )
452+ if next_c . nil? || [ ',' , '}' ] . include? ( next_c )
453+ rstring_delimiter_missing = false
454+ else
455+ # OK but this could still be some garbage at the end of the string
456+ # So we need to check if we find a new lstring_delimiter afterwards
457+ # If we do, maybe this is a missing delimiter
458+ i = skip_to_character ( lstring_delimiter , start_idx : i )
448459 next_c = peek_char ( i )
449- if next_c . nil? || [ ',' , '}' ] . include? ( next_c )
460+ if next_c . nil?
450461 rstring_delimiter_missing = false
451462 else
452- # OK but this could still be some garbage at the end of the string
453- # So we need to check if we find a new lstring_delimiter afterwards
454- # If we do, maybe this is a missing delimiter
455- i = skip_to_character ( lstring_delimiter , start_idx : i )
463+ # But again, this could just be something a bit stupid like "lorem, "ipsum" sic"
464+ # Check if we find a : afterwards (skipping space)
465+ i = skip_whitespaces_at ( start_idx : i + 1 )
456466 next_c = peek_char ( i )
457- if next_c . nil?
467+ if next_c && next_c != ":"
458468 rstring_delimiter_missing = false
459- else
460- # But again, this could just be something a bit stupid like "lorem, "ipsum" sic"
461- # Check if we find a : afterwards (skipping space)
462- i = skip_whitespaces_at ( start_idx : i + 1 )
463- next_c = peek_char ( i )
464- if next_c && next_c != ":"
465- rstring_delimiter_missing = false
466- end
467469 end
468470 end
471+ end
472+ else
473+ # There could be a case in which even the next key:value is missing delimeters
474+ # because it might be a systemic issue with the output
475+ # So let's check if we can find a : in the string instead
476+ i = skip_to_character ( ':' , start_idx : 1 )
477+ next_c = peek_char ( i )
478+ if next_c
479+ # OK then this is a systemic issue with the output
480+ break
469481 else
470- # There could be a case in which even the next key:value is missing delimeters
471- # because it might be a systemic issue with the output
472- # So let's check if we can find a : in the string instead
473- i = skip_to_character ( ':' , start_idx : 1 )
474- next_c = peek_char ( i )
475- if next_c
476- # OK then this is a systemic issue with the output
477- break
478- else
479- # skip any whitespace first
480- i = skip_whitespaces_at ( start_idx : 1 )
481- # We couldn't find any rstring_delimeter before the end of the string
482- # check if this is the last string of an object and therefore we can keep going
483- # make an exception if this is the last char before the closing brace
484- j = skip_to_character ( '}' , start_idx : i )
485- if j - i > 1
486- # Ok it's not right after the comma
487- # Let's ignore
488- rstring_delimiter_missing = false
489- elsif peek_char ( j )
490- # Check for an unmatched opening brace in string_acc
491- string_acc . reverse . chars . each do |c |
492- if c == '{'
493- # Ok then this is part of the string
494- rstring_delimiter_missing = false
495- break
496- end
482+ # skip any whitespace first
483+ i = skip_whitespaces_at ( start_idx : 1 )
484+ # We couldn't find any rstring_delimeter before the end of the string
485+ # check if this is the last string of an object and therefore we can keep going
486+ # make an exception if this is the last char before the closing brace
487+ j = skip_to_character ( '}' , start_idx : i )
488+ if j - i > 1
489+ # Ok it's not right after the comma
490+ # Let's ignore
491+ rstring_delimiter_missing = false
492+ elsif peek_char ( j )
493+ # Check for an unmatched opening brace in string_acc
494+ string_acc . reverse . chars . each do |c |
495+ if c == '{'
496+ # Ok then this is part of the string
497+ rstring_delimiter_missing = false
498+ break
497499 end
498500 end
499501 end
500502 end
503+ end
501504
502- if rstring_delimiter_missing
503- break
504- end
505+ if rstring_delimiter_missing
506+ break
505507 end
506508 end
507509
@@ -511,6 +513,14 @@ def parse_string
511513 break unless peek_char ( i )
512514 end
513515
516+ if current_context? ( :object_value ) && char == '}'
517+ # We found the end of an object while parsing a value
518+ # Check if the object is really over, to avoid doubling the closing brace
519+ i = skip_whitespaces_at ( start_idx : 1 )
520+ next_c = peek_char ( i )
521+ break unless next_c
522+ end
523+
514524 string_acc << char
515525 @scanner . getch # Consume the character
516526 char = peek_char
0 commit comments