module LEXER use ERROR_M, only: DO_ERROR use TRACES_M, only: TRACES implicit NONE private integer, public, parameter :: T_AT = 1 ! @ (maybe a D modifier) integer, public, parameter :: T_CHARS = T_AT + 1 ! @...@ integer, public, parameter :: T_COMMA = T_CHARS + 1 ! , integer, public, parameter :: T_DEVICE = T_COMMA + 1 ! % integer, public, parameter :: T_DONE = T_DEVICE + 1 integer, public, parameter :: T_HASH = T_DONE + 1 ! # integer, public, parameter :: T_MINUS = T_HASH + 1 ! - integer, public, parameter :: T_NAME = T_MINUS + 1 ! L ( L+D)* integer, public, parameter :: T_NUMBER = T_NAME + 1 ! Unsigned integer, public, parameter :: T_OTHER = T_NUMBER + 1 ! Anything else integer, public, parameter :: T_PLUS = T_OTHER + 1 ! & or + integer, public, parameter :: T_STAR = T_PLUS + 1 ! * character(6), public :: TokenNames(t_at:t_star) = & & (/ 'AT ', 'CHARS ', 'COMMA ', 'DEVICE', 'DONE ', 'HASH ', 'MINUS ', & & 'NAME ', 'NUMBER', 'OTHER ', 'PLUS ', 'STAR ' /) public :: LEX contains subroutine LEX ( LINE, START, END, TOKEN ) ! Examine LINE starting at START. Return the TOKEN type (one of T_... ! above) and its END. character(len=*), intent(in) :: LINE integer, intent(inout) :: START integer, intent(out) :: END integer, intent(out) :: TOKEN if ( start > len(line) ) then end = len(line) + 1 token = t_done go to 999 end if end = start - 1 if ( line(start:start) == '' ) then if ( start <= 21 ) then token = t_done return else if ( line(end:end) /= ',' ) then token = t_done end = end + 1 return else start = start + 1 end if end if end = start select case ( line(end:end) ) case ( ' ' ) token = t_done case ( '@' ) ! T_chars end = len(line) do while ( line(end:end) /= '@' ) end = end - 1 end do token = t_other if ( end == start ) then token = t_at ! T_at, maybe a D modifier else if ( end == start + 1 ) then call do_error ( 'Zero-length character literal' ) else token = t_chars end if case ( ',' ) ! T_comma token = t_comma case ( '%' ) ! May be T_device if ( line(end+1:end+1) >= 'A' .and. line(end+1:end+1) <= 'Z' .and. & & line(end+2:end+2) >= '0' .and. line(end+2:end+2) <= '9' ) then end = end + 2 token = t_device else token = t_other end if case ( '#' ) ! T_hash token = t_hash case ( '-' ) ! T_minus token = t_minus case ( 'A' : 'Z' ) ! T_name token = t_name do while ( line(end:end) >= 'A' .and. line(end:end) <= 'Z' .or. & & line(end:end) >= '0' .and. line(end:end) <= '9' ) if ( end == len(line) ) go to 999 end = end + 1 end do end = end - 1 case ( '0' : '9' ) ! T_number token = t_number do while ( line(end:end) >= '0' .and. line(end:end) <= '9' ) if ( end == len(line) ) go to 999 end = end + 1 end do end = end - 1 case ( '&' ) ! T_plus token = t_plus case ( '*' ) token = t_star case default token = t_other end select 999 continue if ( index(traces,'l') /= 0 ) & & print *, 'Lexer: token = ', line(start:end), ' = ', tokenNames(token) end subroutine LEX end module LEXER