fortran66のブログ

fortran について書きます。

【ニュース】Intel Fortran 2025.0 出る!

ifx 2025.0 少し Fortran 2023 に対応

overview

www.intel.com

Compiler Release Notes

You can specify new pure intrinsic subroutines SPLIT and TOKENIZE.

www.intel.com

Fortran 2023 機能としては、文字列から単語を切り出すためのサブルーチン SPLIT と TOKENIZE の二つが実装されたようです。

John Reid の The new features of Fortran 2023 を参考にして、以下で試してみます。

https://wg5-fortran.org/N2201-N2250/N2212.pdf

Fortran 2023 機能を試す

split

指定した区切り文字の位置を順々に返してくれます。

ソース・プログラム

    program split_test
        implicit none
        character(len = :), allocatable :: text
        integer :: ipos
        text = 'The rain in Spain stays mainly in the plain.'
        
        ! split
        
        ipos = 0
        do      
            call split(text, ' .', ipos)       
            print *, ipos
            print *, text(:ipos-1)
            if (ipos > len_trim(text)) exit
        end do
    end program split_test

実行例

           4
 The
           9
 The rain
          12
 The rain in
          18
 The rain in Spain
          24
 The rain in Spain stays
          31
 The rain in Spain stays mainly
          34
 The rain in Spain stays mainly in
          38
 The rain in Spain stays mainly in the
          44
 The rain in Spain stays mainly in the plain
          45
 The rain in Spain stays mainly in the plain.

tokenize

ソース・プログラム

tokenize は二つのサブルーチンの総称名になっていて、引数の与え方で振る舞いが異なります。

最初の tokenize の呼び出しでは、指定した区切り文字で切り出した文字列が配列に入って返されます。文字列の配列は長さが同じにならないとダメなので、空白を padding されて最長の単語文字列の長さで返されます。またオプションで各区切り文字も返してもらえます。

二番目の tokenize の呼び出しでは、指定した区切り文字で区切られた単語の最初と最後の文字の位置をそれぞれ配列に返します。文字列内の位置を返す点では split に少し近いところがありますが、区切り文字の位置を返すか token の位置を返すかの違いがあります。

なお Fortran の継続行の記号 & は、文字列の途中で改行するとき余計な空白を入れないために、末尾の&は次の行の & のところから連続するようになっています。

    program token_test
        implicit none
        character(len = :), allocatable :: text, tokens(:), separator(:)
        integer, allocatable :: first(:), last(:)
        integer :: i
        
        ! tokenize 1
         
        text = 'Old King Cole was a merry old soul,&
               &And a merry old soul was he;'
        
        call tokenize(text, ' ,;', tokens,  separator)        
        do i = 1, size(tokens)
               print *, i, ':', tokens(i), ':'
        end do            
        
        do i = 1, size(separator)
            print *, i, ':', separator(i), ':'
        end do            
        
        ! tokenize 2

        print *        
        call tokenize(text, ' ,;', first, last)
        do i = 1, size(first)            
            print *, i, first(i), last(i), ':', text(first(i):last(i)), ':'
        end do            
    end program token_test

実行結果

           1 :Old  :
           2 :King :
           3 :Cole :
           4 :was  :
           5 :a    :
           6 :merry:
           7 :old  :
           8 :soul :
           9 :And  :
          10 :a    :
          11 :merry:
          12 :old  :
          13 :soul :
          14 :was  :
          15 :he   :
          16 :     :
           1 : :
           2 : :
           3 : :
           4 : :
           5 : :
           6 : :
           7 : :
           8 :,:
           9 : :
          10 : :
          11 : :
          12 : :
          13 : :
          14 : :
          15 :;:

           1           1           3 :Old:
           2           5           8 :King:
           3          10          13 :Cole:
           4          15          17 :was:
           5          19          19 :a:
           6          21          25 :merry:
           7          27          29 :old:
           8          31          34 :soul:
           9          36          38 :And:
          10          40          40 :a:
          11          42          46 :merry:
          12          48          50 :old:
          13          52          55 :soul:
          14          57          59 :was:
          15          61          62 :he:
          16          64          63 ::