def string2token(t,nl,nt):
    """
    This function takes a string and returns a token. A token is a tuple 
    where the first element specifies the type of the data stored in the 
    second element. 

    In this case the data types are limited to numbers, either integer, real
    or complex, and strings. The types a denoted as follows:
    i - integer
    f - float/real
    c - complex
    s - string

    For navigational purposes two more elements added to identify the line
    number (nl) the token was on, and the token number (nt) within the line.
    """
    try:
       i_a = int(t)
       #
       # Toldiff should recognise that -0 and 0 are the same, however, in 
       # a text based comparison that is not automatic so we have to force this.
       #
       if i_a == 0:
         i_a = 0
       token = ("i",i_a,nl,nt)
    except ValueError:
       #
       # In Fortran double precision constants are often printed with a
       # "D" for the exponent rather than an "E", i.e. 1.0E+01 might be
       # printed as 1.0D+01 in Fortran. Python is not aware of this convention
       # so we need to replace any potential "D"-s to obtain valid floating
       # values.
       #
       z = t.replace("d","e")
       z = z.replace("D","e")
       try:
          i_f = float(z)
          #
          # Toldiff should recognise that -0.0 and 0.0 are the same, however,
          # in a text based comparison that is not automatic so we have to
          # force this.
          #
          if i_f == 0.0:
            i_f = 0.0
          token = ("f",i_f,nl,nt)
       except ValueError:
          #
          # The handling of complex numbers is unlikely to work in practice
          # as in most cases complex numbers are printed as (1.0,2.0)
          # rather than 1.0+2.0j. Therefore it is impossible to reliably 
          # distinguish between a complex number and a list of 2 real numbers.
          #
          try:
             i_c = complex(z)
             #
             # Toldiff should recognise that x-0.0j and x+0.0j and that
             # -0.0+y*j and 0.0+y*j are the same, however, in a text based
             # comparison that is not automatic so we have to force this.
             #
             if i_c.real == 0.0:
               i_c = complex(0.0,i_c.imag)
             if i_c.imag == 0.0:
               i_c = complex(i_c.real,0.0)
             token = ("c",i_c,nl,nt)
          except ValueError:
             token = ("s",t,nl,nt)
    return token