162 character(*),
intent(in) :: expr
163 type(
token),
allocatable,
intent(out) :: tokens(:)
164 integer,
intent(out) :: ntokens
166 character(:),
allocatable :: temp
167 integer :: i, pos, len_expr
169 logical,
save :: in_comment
171 if (
allocated(tokens))
deallocate(tokens)
174 temp =
trim(adjustl(expr)) //
' '
179 do while (i <= len_expr)
180 if (temp(i:i) ==
' ')
then
186 if (.not. in_word)
then
187 ntokens = ntokens + 1
190 message=
'The maximum number of tokens has been reached', &
191 label=
label_type(
'Too many tokens in expression.', 1, 1)), &
198 if (temp(i:i) ==
'(' .or. temp(i:i) ==
')')
then
199 tokens(ntokens)%value = temp(i:i)
200 tokens(ntokens)%type = parenthesis
201 tokens(ntokens)%start = i
204 else if (temp(i:i + 1) ==
'&&' .or. temp(i:i + 1) ==
'||' .or. temp(i:i + 1) ==
'==' .or. &
205 temp(i:i + 1) ==
'!=' .or. temp(i:i + 1) ==
'<=' .or. temp(i:i + 1) ==
'>=')
then
206 tokens(ntokens)%value = temp(i:i + 1)
207 tokens(ntokens)%type = operation
208 tokens(ntokens)%start = i
211 else if (temp(i:i) ==
'!')
then
212 tokens(ntokens)%value = temp(i:i)
213 tokens(ntokens)%type = operation
214 tokens(ntokens)%start = i
217 else if (temp(i:i + 1) ==
'**')
then
218 tokens(ntokens)%value = temp(i:i + 1)
219 tokens(ntokens)%type = operation
220 tokens(ntokens)%start = i
223 else if (temp(i:i + 1) ==
'<<' .or. temp(i:i + 1) ==
'>>')
then
224 tokens(ntokens)%value = temp(i:i + 1)
225 tokens(ntokens)%type = operation
226 tokens(ntokens)%start = i
229 else if (temp(i:i) ==
'<' .or. temp(i:i) ==
'>' .or. temp(i:i) ==
'=' .or. &
230 temp(i:i) ==
'+' .or. temp(i:i) ==
'-' .or. temp(i:i) ==
'*' .or. &
231 temp(i:i) ==
'/' .or. temp(i:i) ==
'%' .or. &
232 temp(i:i) ==
'?' .or. temp(i:i) ==
':')
then
233 tokens(ntokens)%value = temp(i:i)
234 tokens(ntokens)%type = operation
235 tokens(ntokens)%start = i
238 else if (temp(i:i) ==
'&' .or. temp(i:i) ==
'|' .or. temp(i:i) ==
'^' .or. &
239 temp(i:i) ==
'~')
then
240 tokens(ntokens)%value = temp(i:i)
241 tokens(ntokens)%type = operation
242 tokens(ntokens)%start = i
247 do while (i <= len_expr .and. temp(i:i) ==
' ')
250 if (i <= len_expr .and. temp(i:i) ==
'(')
then
253 do while (pos <= len_expr .and. temp(pos:pos) /=
')')
256 tokens(ntokens)%value =
trim(adjustl(temp(i:pos - 1)))
257 tokens(ntokens)%type = defined
258 tokens(ntokens)%start = i
262 do while (pos <= len_expr .and. temp(pos:pos) /=
' ')
265 tokens(ntokens)%value =
trim(adjustl(temp(i:pos - 1)))
266 tokens(ntokens)%type = defined
267 tokens(ntokens)%start = i
273 tokens(ntokens)%value =
trim(adjustl(temp(i:pos - 1)))
274 tokens(ntokens)%type = number
275 tokens(ntokens)%start = i
280 do while (pos <= len_expr .and.
is_digit(temp(pos:pos)))
283 tokens(ntokens)%value =
trim(adjustl(temp(i:pos - 1)))
284 tokens(ntokens)%type = number
285 tokens(ntokens)%start = i
290 do while (pos <= len_expr .and. temp(pos:pos) /=
' ' .and. &
291 temp(pos:pos) /=
'(' .and. temp(pos:pos) /=
')')
294 tokens(ntokens)%value =
trim(temp(i:pos - 1))
295 tokens(ntokens)%type = identifier
296 tokens(ntokens)%start = i
352 integer function strtol_with_base(str, base, success)
result(val)
353 character(*),
intent(in) :: str
354 integer,
intent(inout) :: base
355 logical,
intent(out),
optional :: success
357 integer :: i, len, digit
359 logical :: is_valid, isdigit, is_lower_hex, is_upper_hex
360 character(len=len_trim(str)) :: work_str
362 val = 0; is_valid = .true.
363 work_str = adjustl(str)
364 len = len_trim(work_str)
369 if (work_str(1:2) ==
'0x' .or. work_str(1:2) ==
'0X')
then
371 work_str = work_str(3:len)
373 else if (work_str(1:2) ==
'0b' .or. work_str(1:2) ==
'0B')
then
375 work_str = work_str(3:len)
379 if (work_str(1:1) ==
'0')
then
394 if (base /= 2 .and. base /= 8 .and. base /= 10 .and. base /= 16)
then
396 if (
present(success)) success = .false.
406 isdigit = c >=
'0' .and. c <=
'9'
407 if (isdigit) digit = ichar(c) - ichar(
'0')
409 is_lower_hex = base == 16 .and. c >=
'a' .and. c <=
'f'
410 if (is_lower_hex) digit = ichar(c) - ichar(
'a') + 10
412 is_upper_hex = base == 16 .and. c >=
'A' .and. c <=
'F'
413 if (is_upper_hex) digit = ichar(c) - ichar(
'A') + 10
416 if (digit == -1)
then
420 if (digit >= base)
then
426 if (val > (huge(val) - digit) / base)
then
432 val = val * base + digit
436 if (
present(success)) success = is_valid
logical function, public starts_with(str, arg1, idx)
Checks if a string starts with a given prefix Returns .true. if the string str (after trimming leadin...
integer, parameter, public tokens_enum
Kind parameter for token type enumeration. Values are (unknown, number, operation,...
subroutine, public tokenize(expr, tokens, ntokens)
Tokenizes a preprocessor expression into an array of token structures. Handles whitespace,...
logical function is_typeless(str, pos)
Detects whether a string starts a typeless constant (hex, octal, binary). Used to avoid treating them...