Core parsing routine.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(json_core), | intent(inout) | :: | json | |||
integer(kind=IK), | intent(in) | :: | unit | file unit number |
||
character(kind=CK,len=*), | intent(in) | :: | str | string containing JSON
data (only used if |
||
type(json_value), | pointer | :: | value | JSON data that is extracted |
recursive subroutine parse_value(json, unit, str, value)
implicit none
class(json_core),intent(inout) :: json
integer(IK),intent(in) :: unit !! file unit number
character(kind=CK,len=*),intent(in) :: str !! string containing JSON
!! data (only used if `unit=0`)
type(json_value),pointer :: value !! JSON data that is extracted
logical(LK) :: eof !! end-of-file flag
character(kind=CK,len=1) :: c !! character read from file
!! (or string) 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(value)) then
call json%throw_exception('Error in parse_value: value pointer not associated.')
return
end if
! pop the next non whitespace character off the file
call json%pop_char(unit, str=str, eof=eof, skip_ws=.true., &
skip_comments=json%allow_comments, popped=c)
if (eof) then
return
else
select case (c)
case (start_object)
! start object
call json%to_object(value) !allocate class
call json%parse_object(unit, str, value)
case (start_array)
! start array
call json%to_array(value) !allocate class
call json%parse_array(unit, str, value)
case (end_array)
! end an empty array
call json%push_char(c)
nullify(value)
case (quotation_mark)
! string
call json%to_string(value) !allocate class
select case (value%var_type)
case (json_string)
#if defined __GFORTRAN__
! write to a tmp variable because of
! a bug in 4.9 gfortran compiler.
call json%parse_string(unit,str,tmp)
value%str_value = tmp
if (allocated(tmp)) deallocate(tmp)
#else
call json%parse_string(unit,str,value%str_value)
#endif
end select
case (CK_'t') !true_str(1:1) gfortran bug work around
!true
call json%parse_for_chars(unit, str, true_str(2:))
!allocate class and set value:
if (.not. json%exception_thrown) call json%to_logical(value,.true.)
case (CK_'f') !false_str(1:1) gfortran bug work around
!false
call json%parse_for_chars(unit, str, false_str(2:))
!allocate class and set value:
if (.not. json%exception_thrown) call json%to_logical(value,.false.)
case (CK_'n') !null_str(1:1) gfortran bug work around
!null
call json%parse_for_chars(unit, str, null_str(2:))
if (.not. json%exception_thrown) call json%to_null(value) ! allocate class
case(CK_'-', CK_'0': CK_'9')
call json%push_char(c)
call json%parse_number(unit, str, value)
case default
call json%throw_exception('Error in parse_value:'//&
' Unexpected character while parsing value. "'//&
c//'"')
end select
end if
end if
end subroutine parse_value