Core parsing routine.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(json_core), | intent(inout) | :: | json | |||
integer(kind=IK), | intent(in) | :: | unit |
file unit number (if parsing from a file) |
||
character(kind=CK, len=*), | intent(in) | :: | str |
JSON string (if parsing from a string) |
||
type(json_value), | pointer | :: | parent |
the parsed object will be added as a child of this |
||
logical(kind=LK), | intent(in) | :: | expecting_next_element |
if true, this object is preceeded by a comma, so we expect a valid object to exist. used to check for trailing delimiters. |
recursive subroutine parse_object(json, unit, str, parent, expecting_next_element) implicit none class(json_core),intent(inout) :: json integer(IK),intent(in) :: unit !! file unit number (if parsing from a file) character(kind=CK,len=*),intent(in) :: str !! JSON string (if parsing from a string) type(json_value),pointer :: parent !! the parsed object will be added as a child of this logical(LK),intent(in) :: expecting_next_element !! if true, this object is preceeded by a comma, so !! we expect a valid object to exist. used to check !! for trailing delimiters. type(json_value),pointer :: pair !! temp variable logical(LK) :: eof !! end of file flag character(kind=CK,len=1) :: c !! character returned by [[pop_char]] #if defined __GFORTRAN__ character(kind=CK,len=:),allocatable :: tmp !! this is a work-around for a bug !! in the gfortran 4.9 compiler. #endif if (.not. json%exception_thrown) then !the routine is being called incorrectly. if (.not. associated(parent)) then call json%throw_exception('Error in parse_object: parent pointer not associated.') end if nullify(pair) !probably not necessary ! pair name call json%pop_char(unit, str=str, eof=eof, skip_ws=.true., & skip_comments=json%allow_comments, popped=c) if (eof) then call json%throw_exception('Error in parse_object:'//& ' Unexpected end of file while parsing start of object.') return else if (end_object == c) then ! end of an empty object if (expecting_next_element .and. .not. json%allow_trailing_comma) then ! this is a dangling comma. call json%throw_exception('Error in parse_object: '//& 'Dangling comma when parsing an object.') end if return else if (quotation_mark == c) then call json_value_create(pair) #if defined __GFORTRAN__ call json%parse_string(unit,str,tmp) ! write to a tmp variable because of pair%name = tmp ! a bug in 4.9 gfortran compiler. deallocate(tmp) #else call json%parse_string(unit,str,pair%name) #endif if (json%exception_thrown) then call json%destroy(pair) return end if else call json%throw_exception('Error in parse_object: Expecting string: "'//c//'"') return end if ! pair value call json%pop_char(unit, str=str, eof=eof, skip_ws=.true., & skip_comments=json%allow_comments, popped=c) if (eof) then call json%destroy(pair) call json%throw_exception('Error in parse_object:'//& ' Unexpected end of file while parsing object member.') return else if (colon_char == c) then ! parse the value call json%parse_value(unit, str, pair) if (json%exception_thrown) then call json%destroy(pair) return else call json%add(parent, pair) end if else call json%destroy(pair) call json%throw_exception('Error in parse_object:'//& ' Expecting : and then a value: '//c) return end if ! another possible pair call json%pop_char(unit, str=str, eof=eof, skip_ws=.true., & skip_comments=json%allow_comments, popped=c) if (eof) then call json%throw_exception('Error in parse_object: '//& 'End of file encountered when parsing an object') return else if (delimiter == c) then ! read the next member call json%parse_object(unit = unit, str=str, parent = parent, & expecting_next_element=.true.) else if (end_object == c) then ! end of object return else call json%throw_exception('Error in parse_object: Expecting end of object: '//c) return end if end if end subroutine parse_object