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
文字列を保持する 文字型変数の種別型パラメタ