25   public:: 
assignment(=), 
operator(*), 
operator(/), 
operator(+)
    31     character(TOKEN), 
pointer:: name(:)
    32     character(TOKEN):: offset
    33     real(DP), 
pointer:: power(:)
    44   interface assignment(=)
    64     character(*), 
intent(in):: name(u%nelems)
    65     real(DP), 
intent(in):: power(u%nelems)
    66     integer:: i, n, j, onazi
    67     integer:: table(u%nelems)
    69     if (u%nelems < 1) 
return    73       if (name(i) == 
'') cycle
    76         if (name(j) == name(i)) 
then    81         table(i) = table(onazi)
    87     allocate(u%name(n), u%power(n))
    90       if (table(i) == 0) cycle
    91       u%name(table(i)) = name(i)
    92       u%power(table(i)) = u%power(table(i)) + power(i)
    97   type(
units) function dcUnitsMul(u1, u2) result(result)
    98     type(
units), 
intent(in):: u1, u2
   100     character(TOKEN), 
allocatable:: name(:)
   101     real(DP), 
allocatable:: power(:)
   102     result%factor = u1%factor * u2%factor
   103     result%nelems = u1%nelems + u2%nelems
   107       nullify(result%name, result%power)
   110     allocate(name(n), power(n))
   111     name = (/u1%name, u2%name/)
   112     power = (/u1%power, u2%power/)
   114     deallocate(name, power)
   117   type(
units) function dcUnitsDiv(u1, u2) result(result)
   120     character(TOKEN), 
allocatable:: name(:)
   121     real(DP), 
allocatable:: power(:)
   122     if (abs(u2%factor) < tiny(u2%factor)) 
then   123       result%factor = sign(u1%factor, 1.0_dp) * &
   124         & sign(u2%factor, 1.0_dp) * &
   127       result%factor = u1%factor / u2%factor
   129     result%nelems = u1%nelems + u2%nelems
   133       nullify(result%name, result%power)
   136     allocate(name(n), power(n))
   139       name(1:n1) = u1%name(1:n1)
   140       power(1:n1) = u1%power(1:n1)
   144       name(n1:n) = u2%name(1:u2%nelems)
   145       power(n1:n) = -u2%power(1:u2%nelems)
   148     deallocate(name, power)
   151   type(
units) function dcUnitsAdd(u1, u2) result(result)
   154     result%offset = u1%offset
   155     result%nelems = u1%nelems
   156     result%factor = u1%factor + u2%factor
   158     if (x%nelems == 0) 
then   159       nullify(result%name, result%power)   
   162     if (all(abs(x%power(1:result%nelems)) < tiny(0.0_dp))) 
then   163       allocate(result%name(result%nelems), result%power(result%nelems))
   164       result%name = u1%name
   165       result%power = u1%power
   170     result%offset = 
"MISMATCH"   171     nullify(result%name, result%power)   
   174   logical function add_okay(u1, u2) 
result(result)
   177     character(STRING):: debug
   183     if (x%nelems == 0) 
then   185     else if (all(abs(x%power(1:x%nelems)) < tiny(0.0_dp))) 
then   204     if (
associated(u%name)) 
deallocate(u%name)
   205     if (
associated(u%power)) 
deallocate(u%power)
   215     character(*), 
intent(out):: string
   216     type(
units), 
intent(in):: u
   217     integer:: i, ip, npower
   218     character(TOKEN):: buffer
   219     character:: mul = 
'.'   220     real(DP), 
parameter:: allowed = epsilon(1.0_dp) * 16.0
   222     if (u%nelems < 0) 
then   223       string = 
'error from ' // u%offset
   227     write(buffer, 
"(1pg20.12)") u%factor
   229     if (u%nelems < 1) 
return   231     if (abs(u%factor - 1.0) < allowed) 
then   233     else if (abs(u%factor + 1.0) < allowed) 
then   237     ip = len_trim(string) + 1
   239       npower = nint(u%power(i))
   240       if (abs(1.0 - u%power(i)) < allowed) 
then   242       else if (abs(npower - u%power(i)) < allowed) 
then   243         write(buffer, 
"(i10)") npower
   244         buffer = adjustl(buffer)
   246         write(buffer, 
"(1pg10.3)") u%power(i)
   247         buffer = adjustl(buffer)
   249       if (buffer == 
'0') cycle
   250       string = trim(string) // mul // trim(u%name(i)) // trim(buffer)
   252     if (ip <= len(string)) string(ip:ip) = 
' '   253     if (string(1:1) == 
" ") string = adjustl(string)
   254     if (u%offset /= 
"") 
then   255       string = trim(string) // 
'@' // trim(u%offset)
   264     type(
units), 
intent(out):: u
   265     character(*), 
intent(in):: cunits
   270       character(TOKEN):: name
   271       real(DP):: power, factor
   273     type(elem_units), 
target:: ustack(100)
   284     type(paren_t):: pstack(50)
   288     integer, 
parameter:: Y_INIT = 1, y_number = 2, y_name = 3, &
   289       & y_nx = 4, y_ni = 5, y_mul = 6, y_shift = 7
   290     integer:: yparse_status = y_init
   296     character(TOKEN):: cvalue
   302     if (
associated(u%name)) 
deallocate(u%name)
   303     if (
associated(u%power)) 
deallocate(u%power)
   307     if (cunits == 
"") 
return   311     yparse_status = y_init
   317         select case(yparse_status)
   319           pstack(pi)%factor = pstack(pi)%factor * ivalue(1)
   320           yparse_status = y_number
   322           i = pstack(pi)%power_exp
   323           ustack(i:ui)%power = ustack(i:ui)%power * ivalue(1) 
   332         select case(yparse_status)
   334           pstack(pi)%factor = pstack(pi)%factor * dvalue
   335           yparse_status = y_number
   337           i = pstack(pi)%power_exp
   338           ustack(i:ui)%power = ustack(i:ui)%power * dvalue
   347         select case(yparse_status)
   348         case (y_init, y_number, y_mul)
   349           ustack(ui)%name = cvalue
   350           yparse_status = y_name
   354           ustack(ui)%name = cvalue
   355           yparse_status = y_name
   362         select case(yparse_status)
   369         select case(yparse_status)
   370         case (y_number, y_name)
   372           yparse_status = y_mul
   377         select case(yparse_status)
   378         case (y_number, y_name)
   380           pstack(pi)%factor_inv = .true.
   381           yparse_status = y_mul
   388         yparse_status = y_shift
   405     u%factor = product(ustack(1:ui)%factor)
   411       print *, 
operator"DCUnitsBuild: syntax error, (**) ignored"   415       print *, 
"DCUnitsBuild: unexpected token <", &
   416         & trim(cvalue), 
"> ignored"   422       pstack(pi)%power_exp = ui
   428       i = pstack(pi)%factor_exp
   429       factor = product(ustack(i:ui)%factor) * pstack(pi)%factor
   430       if (pstack(pi)%factor_inv) 
then   431         ustack(i:ui)%power = -ustack(i:ui)%power
   432         factor = 1.0_dp / factor
   434       ustack(i)%factor = factor
   435       ustack(i+1:ui)%factor = 1.0_dp
   437       pstack(pi)%factor = 1.0_dp
   438       pstack(pi)%factor_exp = ui
   451       if (ui >= 
size(ustack)) stop 
'DCUnitsBuild: too many elements'   454       ustack(ui)%factor = 1.0_dp
   455       ustack(ui)%power = 1.0_dp
   464       if (pi >= 
size(pstack)) stop 
'DCUnitsBuild: too many parens'   467       pstack(pi)%factor_exp = ui
   468       pstack(pi)%factor = 1.0_dp
   469       pstack(pi)%factor_inv = .false.
   470       pstack(pi)%power_exp = ui
   471       pstack(pi)%paren_exp = ui
 
integer, parameter, public s_exponent
 
integer, parameter, public s_eof
 
integer, parameter, public s_openpar
 
integer, parameter, public token
単語やキーワードを保持する文字型変数の種別型パラメタ 
 
type(units) function dcunitsadd(u1, u2)
 
subroutine dcunitstostring(string, u)
 
subroutine dcunitsbuild(u, cunits)
 
integer, parameter, public s_shift
 
integer, parameter, public s_real
 
type(units) function dcunitsdiv(u1, u2)
 
subroutine dcunitsdeallocate(u)
 
integer, parameter, public dp
倍精度実数型変数 
 
integer, parameter, public s_divide
 
subroutine, private units_simplify(u, name, power)
 
subroutine dcunitsclear(u)
 
logical function, public add_okay(u1, u2)
 
integer, parameter, public s_multiply
 
integer, parameter, public s_closepar
 
type(units) function dcunitsmul(u1, u2)
 
integer, parameter, public s_text
 
subroutine, public dcunitsgettoken(tokentype, ivalue, dvalue, cvalue)
 
subroutine, public dcunitssetline(line)
 
integer, parameter, public s_integer
 
subroutine units_finalize
 
integer, parameter, public string
文字列を保持する 文字型変数の種別型パラメタ