2016-08-24 575 views
0

我必須計算一些復積分,爲此我從我的導師舊程序中編寫Fortran 77.但是我幾乎沒有遇到任何問題。大多數與DATA語句的語法錯誤有關。這是代碼的函數計算實積分的一部分:Fortran 90中的DATA語句的語法錯誤

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。我試圖重寫那些數組,但結果總是一樣的。雖然這個功能不是最好的集成,但我仍然需要它。沒有它,那個舊程序就崩潰了。 我希望有任何建議。

+0

您可以嘗試在編譯命令中添加'-ffixed-form'(或將文件擴展名從'.f90'改爲'.f')。 –

+0

它看起來像有人試圖通過添加自由格式語句連續標記(行尾的'&')來將固定格式的源代碼轉換爲自由格式的源文件。沒有做更多(在這種情況下),這是無效的。難道你不能回到固定源代碼,還是需要完全轉換爲自由格式? – francescalus

+0

這是最初的碼?如果不是,你可以發佈原來的嗎? – innoSPG

回答

3

如果你想編譯這個自由形式源,有兩件事情,你可能會需要改變

  1. 我敢肯定,標籤是在連續行是非法的,所以他們應該被刪除
  2. gfortran會誤解浮點數之間的空格,所以這些也應該被刪除。

事情是這樣的:

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/

或許應該正確編譯[寫在瀏覽器中說明,並沒有經過測試。

+0

我的猜測是,在OP的原始代碼中,可能看起來是連續行中的一位數字語句標籤,實際上是在第6列中,這使得它們成爲連續標記。 SO的代碼格式不遵守衝卡布局的規則。 –

+0

@HighPerformanceMark:是的,它可能是正確的。但我認爲問題實際上可能在於OP將代碼從固定格式重新格式化爲自由格式,而不是其它任何格式。 – talonmies

+1

一種經常使用的方法可使固定格式和自由格式的連續行工作,即在要繼續的行中追加&列73,並在連續行中前加6列。固定的自由格式轉換程序不應該保留引用格式的延續。 – tim18

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 

data w & 
/0.10122853629037, blah blah