gtool5 Fortran 90/95 ライブラリ 1.0.0-rc5
English
Loading...
Searching...
No Matches
dcunits_com.f90
Go to the documentation of this file.
1!-----------------------------------------------------------------------
2! Copyright (c) 2000-2026 Gtool Development Group. All rights reserved.
3!-----------------------------------------------------------------------
4!>
5!> @author Eizi TOYODA, Yasuhiro MORIKAWA
6!> @copyright Copyright (C) GFD Dennou Club, 2000-2026. All rights reserved. <br/>
7!> License is BSD-2-Clause. see [COPYRIGHT](@ref COPYRIGHT) in detail
8!> @private
9!> @en
10!> @brief Internal module for dc_units
11!> @details
12!> This module provides internal constants and subroutines used by
13!> the dc_units module. It contains scanner/tokenizer functionality
14!> for parsing unit strings.
15!>
16!> @section dcunits_com_scanner Scanner symbols
17!>
18!> | Symbol | Description |
19!> |--------------|--------------------------|
20!> | S_EOF | End of file/string |
21!> | S_SHIFT | Shift operator (@, from, at) |
22!> | S_TEXT | Text/name token |
23!> | S_MULTIPLY | Multiply operator (*, .) |
24!> | S_DIVIDE | Divide operator (/) |
25!> | S_EXPONENT | Exponent operator (^, **)|
26!> | S_OPENPAR | Open parenthesis |
27!> | S_CLOSEPAR | Close parenthesis |
28!> | S_REAL | Real number |
29!> | S_INTEGER | Integer number |
30!>
31!> @enden
32!>
33!> @ja
34!> @brief dc_units モジュール用の内部モジュール
35!> @details
36!> dc_units モジュールで用いる内部の定数およびサブルーチンを提供します.
37!> 単位文字列をパースするためのスキャナ/トークナイザ機能を含みます.
38!>
39!> @section dcunits_com_scanner_ja スキャナシンボル
40!>
41!> | シンボル | 説明 |
42!> |--------------|--------------------------|
43!> | S_EOF | ファイル/文字列の終端 |
44!> | S_SHIFT | シフト演算子 (@, from, at) |
45!> | S_TEXT | テキスト/名前トークン |
46!> | S_MULTIPLY | 乗算演算子 (*, .) |
47!> | S_DIVIDE | 除算演算子 (/) |
48!> | S_EXPONENT | 指数演算子 (^, **) |
49!> | S_OPENPAR | 開き括弧 |
50!> | S_CLOSEPAR | 閉じ括弧 |
51!> | S_REAL | 実数 |
52!> | S_INTEGER | 整数 |
53!>
54!> @endja
55!>
56
58 use dc_types, only: dp, string
59 implicit none
60 private
64
65 !> @var S_EOF
66 !> @en End of file/string symbol @enden
67 !> @ja ファイル/文字列終端シンボル @endja
68 integer, parameter:: s_eof = -128
69
70 !> @var S_SHIFT
71 !> @en Shift operator symbol @enden
72 !> @ja シフト演算子シンボル @endja
73 integer, parameter:: s_shift = 300
74
75 !> @var S_TEXT
76 !> @en Text/name token symbol @enden
77 !> @ja テキスト/名前トークンシンボル @endja
78 integer, parameter:: s_text = 301
79
80 !> @var S_MULTIPLY
81 !> @en Multiply operator symbol @enden
82 !> @ja 乗算演算子シンボル @endja
83 integer, parameter:: s_multiply = 302
84
85 !> @var S_DIVIDE
86 !> @en Divide operator symbol @enden
87 !> @ja 除算演算子シンボル @endja
88 integer, parameter:: s_divide = 303
89
90 !> @var S_EXPONENT
91 !> @en Exponent operator symbol @enden
92 !> @ja 指数演算子シンボル @endja
93 integer, parameter:: s_exponent = 304
94
95 !> @var S_OPENPAR
96 !> @en Open parenthesis symbol @enden
97 !> @ja 開き括弧シンボル @endja
98 integer, parameter:: s_openpar = 305
99
100 !> @var S_CLOSEPAR
101 !> @en Close parenthesis symbol @enden
102 !> @ja 閉じ括弧シンボル @endja
103 integer, parameter:: s_closepar = 306
104
105 !> @var S_REAL
106 !> @en Real number symbol @enden
107 !> @ja 実数シンボル @endja
108 integer, parameter:: s_real = 307
109
110 !> @var S_INTEGER
111 !> @en Integer number symbol @enden
112 !> @ja 整数シンボル @endja
113 integer, parameter:: s_integer = 308
114
115 !> @var thisline
116 !> @en Scanner buffer for input line @enden
117 !> @ja スキャナバッファ(入力行) @endja
118 character(STRING), private, save:: thisline = ""
119
120 !> @var i
121 !> @en Current position in scanner buffer @enden
122 !> @ja スキャナバッファの現在位置 @endja
123 integer, private, save:: i = 1
124
125contains
126
127 !>
128 !> @en
129 !> @brief Set input line for scanner
130 !> @details
131 !> Sets the input line to be scanned and resets the scanner position.
132 !> @param[in] line Input line to scan
133 !> @enden
134 !>
135 !> @ja
136 !> @brief スキャナの入力行を設定します
137 !> @details
138 !> スキャンする入力行を設定し, スキャナ位置をリセットします.
139 !> @param[in] line スキャンする入力行
140 !> @endja
141 !>
142 subroutine dcunitssetline(line)
143 implicit none
144 character(*), intent(in):: line
145 thisline = line
146 i = 1
147 end subroutine dcunitssetline
148
149 !>
150 !> @en
151 !> @brief Get next token from input line
152 !> @details
153 !> Scans the input line and returns the next token.
154 !> Token types include operators, numbers, and text.
155 !> @param[out] tokentype Type of the token (S_EOF, S_TEXT, etc.)
156 !> @param[out] ivalue Integer values array (for integer tokens)
157 !> @param[out] dvalue Real value (for real number tokens)
158 !> @param[out] cvalue Character value (token string)
159 !> @enden
160 !>
161 !> @ja
162 !> @brief 入力行から次のトークンを取得します
163 !> @details
164 !> 入力行をスキャンし, 次のトークンを返します.
165 !> トークンの種類には演算子, 数値, テキストがあります.
166 !> @param[out] tokentype トークンの種類 (S_EOF, S_TEXT など)
167 !> @param[out] ivalue 整数値配列 (整数トークン用)
168 !> @param[out] dvalue 実数値 (実数トークン用)
169 !> @param[out] cvalue 文字値 (トークン文字列)
170 !> @endja
171 !>
172 subroutine dcunitsgettoken(tokentype, ivalue, dvalue, cvalue)
173 use dc_regex, only: match
174 implicit none
175 integer, intent(out):: tokentype
176 integer, intent(out):: ivalue(5)
177 real(dp), intent(out):: dvalue
178 character(*), intent(out):: cvalue
179 integer:: iend, istr, ilen, ios
180 ivalue = 0
181 dvalue = 0.0_dp
182 cvalue = ""
183 iend = len_trim(thisline)
184 do
185 if (i > iend) exit
186 ! '#' 文字が現われれば EOF シンボルを返す
187 call match("^##", thisline(i:), istr, ilen)
188 if (istr > 0) then
189 i = iend + 1
190 tokentype = s_eof
191 return
192 endif
193 ! 空白を無視
194 call match("^#s+", thisline(i:), istr, ilen)
195 if (istr > 0) then
196 i = i + ilen
197 if (i > iend) exit
198 endif
199 ! シフト演算子チェック
200 call match("^@", thisline(i:), istr, ilen)
201 if (istr <= 0) call match("^from", thisline(i:), istr, ilen)
202 if (istr <= 0) call match("^at", thisline(i:), istr, ilen)
203 if (istr > 0) then
204 i = i + ilen
205 tokentype = s_shift
206 cvalue = thisline(i: i+ilen-1)
207 return
208 endif
209 ! 名前チェック
210 call match("^#a#w*#a", thisline(i:), istr, ilen)
211 if (istr <= 0) call match("^[#a'""]", thisline(i:), istr, ilen)
212 if (istr > 0) then
213 tokentype = s_text
214 cvalue = thisline(i: i+ilen-1)
215 i = i + ilen
216 return
217 endif
218 ! '*' の前に '**' を認知せねば。
219 call match("^#^", thisline(i:), istr, ilen)
220 if (istr <= 0) call match("^#*#*", thisline(i:), istr, ilen)
221 if (istr > 0) then
222 tokentype = s_exponent
223 cvalue = thisline(i: i+ilen-1)
224 i = i + ilen
225 return
226 endif
227 ! 実数にならない小数点は S_MULTIPLY
228 call match("^#.[^#d]", thisline(i:), istr, ilen)
229 if (istr <= 0) call match("^#*", thisline(i:), istr, ilen)
230 if (istr > 0) then
231 tokentype = s_multiply
232 cvalue = thisline(i: i+ilen-1)
233 i = i + 1
234 return
235 endif
236 ! 実数チェック. 小数点は語頭にあれば必ず数字が伴うので安心せよ
237 call match("^[-+]?#d*#.#d*[EeDd][-+]?#d+", thisline(i:), istr, ilen)
238 if (istr <= 0) call match("^[-+]?#d*#.#d*", thisline(i:), istr, ilen)
239 if (istr > 0) then
240 read(thisline(i: i+ilen-1), fmt=*, &
241 & iostat=ios) dvalue
242 if (ios /= 0) dvalue = huge(dvalue)
243 cvalue = thisline(i: i+ilen-1)
244 tokentype = s_real
245 i = i + ilen
246 return
247 endif
248 ! 整数チェック
249 call match("^[-+]?#d+", thisline(i:), istr, ilen)
250 if (istr > 0) then
251 read(thisline(i: i+ilen-1), fmt=*, &
252 & iostat=ios) ivalue(1)
253 if (ios /= 0) ivalue(1) = huge(1)
254 cvalue = thisline(i: i+ilen-1)
255 tokentype = s_integer
256 i = i + ilen
257 return
258 endif
259 ! ほかの1字トークンチェック
260 if (thisline(i:i) == '/') then
261 tokentype = s_divide
262 cvalue = thisline(i:i)
263 i = i + 1
264 return
265 endif
266 if (thisline(i:i) == '(') then
267 tokentype = s_openpar
268 cvalue = thisline(i:i)
269 i = i + 1
270 return
271 endif
272 if (thisline(i:i) == ')') then
273 tokentype = s_closepar
274 cvalue = thisline(i:i)
275 i = i + 1
276 return
277 endif
278 ! だめだこりゃ。はい次いってみよう
279 tokentype = ichar(thisline(i:i))
280 cvalue = thisline(i:i)
281 i = i + 1
282 return
283 enddo
284 i = iend + 1
285 tokentype = s_eof
286 cvalue = ""
287 end subroutine dcunitsgettoken
288
289end module dcunits_com
シンプルな正規表現関数 'match' を提供します.
Definition dc_regex.f90:62
subroutine, public match(pattern, text, start, length)
Definition dc_regex.f90:469
種別型パラメタを提供します。
Definition dc_types.f90:55
integer, parameter, public string
文字列を保持する 文字型変数の種別型パラメタ
Definition dc_types.f90:137
integer, parameter, public dp
倍精度実数型変数
Definition dc_types.f90:92
dc_units モジュール用の内部モジュール
integer, parameter, public s_real
実数シンボル
integer, parameter, public s_closepar
閉じ括弧シンボル
integer, parameter, public s_text
テキスト/名前トークンシンボル
integer, parameter, public s_multiply
乗算演算子シンボル
integer, parameter, public s_openpar
開き括弧シンボル
integer, parameter, public s_shift
シフト演算子シンボル
integer, parameter, public s_integer
整数シンボル
integer, parameter, public s_eof
ファイル/文字列終端シンボル
subroutine, public dcunitsgettoken(tokentype, ivalue, dvalue, cvalue)
subroutine, public dcunitssetline(line)
integer, parameter, public s_exponent
指数演算子シンボル
integer, parameter, public s_divide
除算演算子シンボル