Fortran 90中DATA语句的语法错误

时间:2016-08-24 09:58:28

标签: fortran fortran90 numerical-methods

我必须计算一些复杂的积分,为此我得到了我用Fortran 77编写的主管旧程序。但是我几乎没有问题。主要与DATA Statement的语法错误有关。这是具有计算实数积分的函数的代码的一部分:

FUNCTION  CAUSSA(F,A,B,EPS)
  IMPLICIT DOUBLE PRECISION (A-H,O-Z)
  external f
  REAL :: W(12),X(12)
  DATA CONST /1.0D-12/
  DATA W &
1 /0.10122 85362 9037 , 0.22238 10344 5337 , 0.31370 66458 7788 ,&
2 0.36268 37833 7836 , 0.02715 24594 1175 , 0.06225 35239 3864 ,&
3 0.09515 85116 8249 , 0.12462 89712 5553 , 0.14959 59888 1657 ,&
4 0.16915 65193 9500 , 0.18260 34150 4492 , 0.18945 06104 5506 /

  DATA X &
1 /0.96028 98564 9753 , 0.79666 64774 1362 , 0.52553 24099 1632 ,&
2 0.18343 46424 9565 , 0.98940 09349 9165 , 0.94457 50230 7323 ,&
3 0.86563 12023 8783 , 0.75540 44083 5500 , 0.61787 62444 0264 ,&
4 0.45801 67776 5722 , 0.28160 35507 7925 , 0.09501 25098 3763 /
  DELTA=CONST*DABS(A-B)
  CAUSSA=0.d0
  AA=A
5 Y=B-AA
  IF(DABS(Y) .LE. DELTA) RETURN
2 BB=AA+Y
  C1=0.5*(AA+BB)
  C2=C1-AA
  S8=0.d0
  S16=0.d0
  DO 1 I=1,4
  U=X(I)*C2
1 S8=S8+W(I)*(F(C1+U)+F(C1-U))
  DO 3 I = 5,12
  U=X(I)*C2
3 S16=S16+W(I)*(F(C1+U)+F(C1-U))
  S8=S8*C2
  S16=S16*C2
  IF(DABS(S16-S8).GT.EPS*DABS(S16)) GO TO 4
  CAUSSA= CAUSSA+S16
  A=BB
  GO TO 5
4 Y=0.5*Y
  IF(DABS(Y) .GT. DELTA) GO TO 2
  write(2,7)
  write(5,7)
7 FORMAT(1X,35HCAUSSA...TOO HIGH ACCURACY REQUIRED)
  CAUSSA=0.d0
  RETURN
END

编译结果如下:

 sample.f90:11: 

 1 /0.10122 85362 9037 , 0.22238 10344 5337 , 0.31370 66458 7788 ,&    
 1
 Error: Syntax error in DATA statement at (1)
 sample.f90:17:

 1 /0.96028 98564 9753 , 0.79666 64774 1362 , 0.52553 24099 1632 ,&
 1     
 Error: Syntax error in DATA statement at (1)

我使用gfortran版本4.4.7。我试图重写那些数组,但结果总是一样的。虽然这个功能不是最好的集成,但我仍然需要它。没有它,那个旧程序正在崩溃。 我很感激任何建议。

1 个答案:

答案 0 :(得分:0)

您的原始代码错误地混合了自由格式和固定源格式。通过使用尾随符号&执行自由格式的续行,而不是在下一行的第6列中输入字符。在固定源形式中,前六列是为语句标签保留的,第1列也用于表示注释行。在现代代码中,使用结构化控制语句(例如select caseif-then-else)语句标签并不常见。因此很少使用前五列,因为它们很少被使用。

以下是自由格式和固定源格式的相同代码:

program main

    use ISO_Fortran_env, only: &
        compiler_version, &
        compiler_options

    ! Explicit typing only
    implicit none

    ! Variable declarations
    double precision :: a, b, eps, x

    a = 1.0d0
    b = 2.0d0
    eps = epsilon(a)
    x = caussa(my_func, a, b, eps)

    print '(/4a/)', &
    ' This file was compiled using ', compiler_version(), &
    ' using the options ', compiler_options()

contains

    function my_func(arg) result (return_value)
      ! Dummy arguments
      double precision, intent (in) :: arg
      double precision              :: return_value

      return_value = arg * 42.0d0

    end function my_func

    function caussa(f,a,b,eps)

      use ISO_Fortran_env, only: &
          stderr => ERROR_UNIT

      implicit double precision (a-h,o-z)
      external f
      integer :: i
      real    :: w(12),x(12)
      data const /1.0d-12/
      data w &
        /0.10122853629037, 0.22238103445337, 0.31370664587788 ,&
        0.36268378337836, 0.02715245941175, 0.06225352393864 , &
        0.09515851168249, 0.12462897125553, 0.14959598881657 , &
        0.16915651939500, 0.18260341504492, 0.18945061045506 /

      data x &
        /0.96028985649753, 0.79666647741362, 0.52553240991632, &
        0.18343464249565, 0.98940093499165, 0.94457502307323, &
        0.86563120238783, 0.75540440835500, 0.61787624440264, &
        0.45801677765722, 0.28160355077925, 0.09501250983763 /

    delta=const*dabs(a-b)
    caussa=0.d0
    aa=a
5   y=b-aa
    if (dabs(y) <= delta) return
2   bb=aa+y
    c1=0.5*(aa+bb)
    c2=c1-aa
    s8=0.d0
    s16=0.d0
    do 1 i=1,4
        u=x(i)*c2
1       s8=s8+w(i)*(f(c1+u)+f(c1-u))
        do 3 i = 5,12
            u=x(i)*c2
3           s16=s16+w(i)*(f(c1+u)+f(c1-u))
            s8=s8*c2
            s16=s16*c2
            if (dabs(s16-s8)>eps*dabs(s16)) go to 4
            caussa = caussa+s16
            a = bb
            go to 5
4           y = 0.5*y
            if (dabs(y) > delta) go to 2
            write(2,7)
            write(stderr,7)
            !
            ! 7 format(1x,35hcaussa...too high accuracy required)
            ! Hollerith format specifier is a Fortran 95 deleted feature
            !
7               format(1x, 'caussa...too high accuracy required')
            caussa=0.d0

    end function caussa

end program main

这是固定格式版本

      PROGRAM MAIN

      USE ISO_FORTRAN_ENV, ONLY:
     1 COMPILER_VERSION,
     2 COMPILER_OPTIONS

C EXPLICIT TYPING ONLY
      IMPLICIT NONE

C VARIABLE DECLARATIONS
      DOUBLE PRECISION :: A, B, EPS, X

      A = 1.0D0
      B = 2.0D0
      EPS = EPSILON(A)
      X = CAUSSA(MY_FUNC, A, B, EPS)

      PRINT '(/4A/)',
     1 ' THIS FILE WAS COMPILED USING ', COMPILER_VERSION(),
     2 ' USING THE OPTIONS ', COMPILER_OPTIONS()

      CONTAINS

      FUNCTION MY_FUNC(ARG) RESULT (RETURN_VALUE)
C DUMMY ARGUMENTS
      DOUBLE PRECISION, INTENT (IN) :: ARG
      DOUBLE PRECISION              :: RETURN_VALUE

      RETURN_VALUE = ARG * 42.0D0

      END FUNCTION MY_FUNC

      FUNCTION CAUSSA(F,A,B,EPS)

      USE ISO_FORTRAN_ENV, ONLY:
     1 STDERR => ERROR_UNIT
      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
      EXTERNAL F
      INTEGER I
      REAL :: W(12), X(12)
      DATA CONST /1.0D-12/
      DATA W
     1 /0.10122 85362 9037, 0.22238 10344 5337, 0.31370 66458 7788,
     2 0.36268 37833 7836, 0.02715 24594 1175, 0.06225 35239 3864,
     3 0.09515 85116 8249, 0.12462 89712 5553, 0.14959 59888 1657,
     4 0.16915 65193 9500, 0.18260 34150 4492, 0.18945 06104 5506 /
      DATA X
     1 /0.96028 98564 9753, 0.79666 64774 1362, 0.52553 24099 1632,
     2 0.18343 46424 9565, 0.98940 09349 9165, 0.94457 50230 7323,
     3 0.86563 12023 8783, 0.75540 44083 5500, 0.61787 62444 0264,
     4 0.45801 67776 5722, 0.28160 35507 7925, 0.09501 25098 3763 /

      DELTA=CONST*DABS(A-B)
      CAUSSA=0.D0
      AA=A
  5   Y=B-AA
      IF(DABS(Y) .LE. DELTA) RETURN
  2   BB=AA+Y
      C1=0.5*(AA+BB)
      C2=C1-AA
      S8=0.D0
      S16=0.D0
      DO 1 I=1,4
      U=X(I)*C2
  1   S8=S8+W(I)*(F(C1+U)+F(C1-U))
      DO 3 I = 5,12
      U=X(I)*C2
  3   S16=S16+W(I)*(F(C1+U)+F(C1-U))
      S8=S8*C2
      S16=S16*C2
      IF(DABS(S16-S8).GT.EPS*DABS(S16)) GO TO 4
      CAUSSA= CAUSSA+S16
      A=BB
      GO TO 5
 4    Y=0.5*Y
      IF(DABS(Y) .GT. DELTA) GO TO 2
      WRITE(2,7)
      WRITE(STDERR,7)
C
C 7   FORMAT(1X,35HCAUSSA...TOO HIGH ACCURACY REQUIRED)
C HOLLERITH FORMAT SPECIFIER IS A FORTRAN 95 DELETED FEATURE
C
  7   FORMAT(1X, 'CAUSSA...TOO HIGH ACCURACY REQUIRED')
      CAUSSA=0.D0
      RETURN
      END FUNCTION CAUSSA
      END PROGRAM MAIN

自由形式引入了“重要空白”的概念。 在固定来源中,空白在大多数情况下都是微不足道的。下面是一个固定源语句的示例,显示了现在被认为是重要空白的内容,后面是没有空格的等效语句:

DO N = 1, MAX ITER S

DO N = 1, MAXITERS

注意我们如何改写

  DATA W
1 /0.10122 85362 9037, blah blah

as

 data w &
 /0.10122853629037, blah blah