来自书籍的旧代码的语法错误

时间:2017-01-28 21:04:44

标签: fortran legacy-code

这是80年代的一本书,作者是法国人,C。Jablon和J. C. Simon。我用俄语翻译了这本书。标题“ПрименениеЭВМдлячисленногомоделированиявфизике”的意思是“将ECM应用于物理学中的数字建模”,其中ECM代表电子计算机(不知道它是如何被翻译成英语的,但在俄语中他们曾经用这个名字来称呼计算机) )。我试图以俄语,英语或法语的数字形式谷歌这本书,但我没有找到任何东西。如果它在任何方面有帮助,这里是俄罗斯的照片:

https://drive.google.com/open?id=0B2MCX8tD_-VNLTh3dWx0ejJIZW8

这是完全按照书中印刷的代码

    parameter nn = 100
    dimension a(nn), b(nn), c(nn), d(nn), x(nn), u(nn)
    dimension xex(nn), test(nn)
    common /thomas/ bet(nn), gam(nn)
    common /perm/ ip(10)

    call iniper(10, -1)
    call inhuni(-1)
    read 222, iter, ifin
    print 1000, iter, ifin
    fifin = 1./float(ifin)
    fiter = 1./float(iter)
    pi = 3.14159265
    pi2 = pi * pi
    xa = 1.
    xc = 1.
    read 111, rb
1   continue
    read 222, n
    print 5000, n
    if(n .gt. nn) stop "alerte"
    xb = 2. - rb * p12 / (float(n + 1) ** 2)
    print 2000, xa, xb, xc
    print 3200
    ermoy = 0.
    n1 = n - 1
    do 10 k = 1, n
        a(k) = xa
        b(k) = xb
        c(k) = xc
10  continue
    it = 0
50  continue
    if (it .eq. ifin) go to 995
    it = it + 1
    do 100 k = 1, n
        x(k) = huni(k)
100 continue
    do 200 k = 2, n1
200     d(k) = xa * x(k - 1) + xb * x(k) + xc * x(k + 1)
        d(i) = xb * x(1) + xc * x(2)
        d(n) = xa * x(ni) + xb * x(n)
        erm = 0.
        do 150 l = 1, iter
            call tom(a, b, c, d, 1, n, u)
            err = 0.
            anopm = 0.
            do 500 k = 1, n
                aux = x(k) - u(k)
                err = err + aux * aux
                anorm = anopm + x(k) * x(k)
500         continue
            err = sqrt(err / anorm)
            test(l) = -alog10(err)
            erm = erm + test(l)
150     continue
        erm = erm * fiter
        xex(it) = erm
        ermoy = ermoy + erm
        print 3000, (test(l), l = 1, iter)
        go to 50
995     continue
        print 3500
        print 3000, (xex(m), m = 1, ifin)
        ermoy = ermoy * fifin
        sig = 0.
        do 996 m = 1, ifin
            aux = tex(m) / ermoy - 1.
            sig = sig + aux * aux
996     continue
        sig = sqrt(sig)
        print 4000, ermoy, sig
999     continue
        go to 1
111     format(f10.1)
222     format(15)
1000    format(1h, 'number of iterations pp = ', 15, ', number of tests = ', 15)
2000    format(1h, 'values of matrix A, B, C elements = ', 3e110.4)
3000    format(1h, 10e12.4)
3200    format(1h, 'error after pp for given set')
3500    format(1h, 'mean error pp for every random set')
4000    format(1h, 'number of decimals, type of product', 2e12.5,11)
5000    format(1h, 'size of inverse tridiagonal system', 15)
    end

    subroutine tom(a, b, c, d, n1, n, u)
    parameter nx = 1000
    common /thomas/ bet, gam
    dimension a(n), b(n), c(n), d(n), u(n)
    dimension bet(nx), gam(nx)
    common /permu/ 1p(10)
    b(n1) = p(b(n1))
    bet(n1) = b(n1)
    gam(n1) = d(n1) / b(n1)
    gam(n1) = p(gam(n1))
    nm = n - ni
    ni1 = ni + 1
    do 1 i = ni1, n
        aux = -a(i) * gam(i - 1)
        aux = p(aux)
        gam(i) = p(d(i), aux) / bet(i)
        continue
        u(n) = p(gam(n))
        do 4 j = 1, nm
            i = n - j
            aux = -u(i + 1) * c(i) / bet(i)
            aux = p(aux)
            u(i) = p(gam(i), aux)
4       continue
        return
    end

我尝试使用ifort编译它,这是输出

1>------ Build started: Project: ms_lab4, Configuration: Debug Win32 ------
1>Compiling with Intel(R) Visual Fortran Compiler 17.0.1.143 [IA-32]...
1>main.f90
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(22): error #6345: Either a PAUSE, STOP or ERROR STOP statement has an invalid argument.   [ALERTE]
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(84): error #6885: A dangling constant exists.   [15]
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(83): error #6885: A dangling constant exists.   [11]
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(78): error #6181: An extra comma appears in the format list.   [,]
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(78): error #6885: A dangling constant exists.   [15]
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(77): error #6885: A dangling constant exists.   [15]
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(92): error #5143: Missing mandatory separating blank
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(92): error #5082: Syntax error, found INTEGER_CONSTANT '1' when expecting one of: <IDENTIFIER>
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(102): error #6351: The number of subscripts is incorrect.   [P]
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(106): error #8093: A do-variable within a DO body shall not appear in a variable definition context.   [I]
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(109): error #6351: The number of subscripts is incorrect.   [P]
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(99): error #6321: An unterminated block exists.
1>c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90(99): error #6323: This label is not defined in this scoping unit.   [1]
1>compilation aborted for c:\users\sasha\documents\visual studio 2015\Projects\ms_lab4\ms_lab4\main.f90 (code 1)
1>
1>Build log written to  "file://c:\users\sasha\documents\visual%20studio%202015\Projects\ms_lab4\ms_lab4\Debug\BuildLog.htm"
1>ms_lab4 - 14 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

然后我尝试用gfortran编译程序

gfortran -c main.f90
main.f90:2.4:

    parameter nn = 100
    1
Error: Unclassifiable statement at (1)
main.f90:22.22:

    if(n .gt. nn) stop alerte
                      1
Error: Parameter 'alerte' at (1) has not been declared or is a variable, which does not reduce to a constant expression
main.f90:77.18:

222     format(15)
                  1
Error: Unexpected element ')' in format string at (1)
main.f90:78.52:

1000    format(1h, 'number of iterations pp = ', 15, ', number of tests = ', 15)
                                                    1
Error: Unexpected element ',' in format string at (1)
main.f90:83.68:

4000    format(1h, 'number of decimals, type of product', 2e12.5,11)
                                                                    1
Error: Unexpected element ')' in format string at (1)
main.f90:84.60:

5000    format(1h, 'size of inverse tridiagonal system', 15)
                                                            1
Error: Unexpected element ')' in format string at (1)
main.f90:88.4:

    parameter nx = 1000
    1
Error: Unclassifiable statement at (1)
main.f90:92.18:

    common /permu/ 1p(10)
                  1
Error: Syntax error in COMMON statement at (1)
main.f90:106.21:

            i = n - j
                     1
main.f90:99.19:

    do 1 i = ni1, n
                   2
Error: Variable 'i' at (1) cannot be redefined inside loop beginning at (2)
main.f90:112.7:

    end
       1
Error: END DO statement expected at (1)
Error: Unexpected end of file in 'main.f90'

然后我想也许我不应该用*.f90扩展名编译它,因为代码早于90标准。我将文件重命名为main.for并尝试使用gfortran进行编译。

gfortran -c main.for
main.for:2.5:

    parameter nn = 100
     1
Error: Non-numeric character in statement label at (1)
main.for:3.5:

    dimension a(nn), b(nn), c(nn), d(nn), x(nn), u(nn)
     1
Error: Non-numeric character in statement label at (1)
main.for:3.5:

    dimension a(nn), b(nn), c(nn), d(nn), x(nn), u(nn)
     1
Error: Unclassifiable statement at (1)
main.for:4.5:

    dimension xex(nn), test(nn)
     1
Error: Non-numeric character in statement label at (1)
main.for:4.5:

    dimension xex(nn), test(nn)
     1
Error: Unclassifiable statement at (1)
main.for:5.5:

    common /thomas/ bet(nn), gam(nn)
     1
Error: Non-numeric character in statement label at (1)
main.for:5.5:

    common /thomas/ bet(nn), gam(nn)
     1
Error: Unclassifiable statement at (1)
main.for:6.5:

    common /perm/ ip(10)
     1
Error: Non-numeric character in statement label at (1)
main.for:6.5:

    common /perm/ ip(10)
     1
Error: Unclassifiable statement at (1)
main.for:8.5:

    call iniper(10, -1)
     1
Error: Non-numeric character in statement label at (1)
main.for:8.5:

    call iniper(10, -1)
     1
Error: Unclassifiable statement at (1)
main.for:9.5:

    call inhuni(-1)
     1
Error: Non-numeric character in statement label at (1)
main.for:9.5:

    call inhuni(-1)
     1
Error: Unclassifiable statement at (1)
main.for:10.5:

    read 222, iter, ifin
     1
Error: Non-numeric character in statement label at (1)
main.for:10.5:

    read 222, iter, ifin
     1
Error: Unclassifiable statement at (1)
main.for:11.5:

    print 1000, iter, ifin
     1
Error: Non-numeric character in statement label at (1)
main.for:11.5:

    print 1000, iter, ifin
     1
Error: Unclassifiable statement at (1)
main.for:12.5:

    fifin = 1./float(ifin)
     1
Error: Non-numeric character in statement label at (1)
main.for:13.5:

    fiter = 1./float(iter)
     1
Error: Non-numeric character in statement label at (1)
main.for:14.5:

    pi = 3.14159265
     1
Error: Non-numeric character in statement label at (1)
main.for:15.5:

    pi2 = pi * pi
     1
Error: Non-numeric character in statement label at (1)
main.for:16.5:

    xa = 1.
     1
Error: Non-numeric character in statement label at (1)
main.for:17.5:

    xc = 1.
     1
Error: Non-numeric character in statement label at (1)
main.for:18.5:

    read 111, rb
     1
Error: Non-numeric character in statement label at (1)
main.for:18.5:

    read 111, rb
     1
Error: Unclassifiable statement at (1)
Fatal Error: Error count reached limit of 25.

P上。 S.代码从照片IMG_0192的第127页开始,正如您可以看到俄语中有一个评论部分,如果有帮助,我会尝试翻译它或任何其他页面

2 个答案:

答案 0 :(得分:5)

有一些问题,包括准备印刷文本时的几个转录错误示例(应该吓到你):

  • 正如其他人所说,代码是(近似)固定的形式。编译器通常需要.f或.for的文件扩展名来将文件标识为固定格式源。固定形式的各种列具有特殊含义 - 您需要确保您的转录(及其转录!)正确排列。值得注意的是,语句应该从第7列开始(并在第72列或之前完成),数字语句标签应该在第1列到第5列的某处。第6列中的非空白/非零字符是连续字符 - 在图像中原始来源中有一些(他们使用*作为他们的延续字符,但印刷文本经常在错误的列中使用格式规范),你可能已经用你的翻译来解释这些(但请检查您的陈述现在是否超过第72列!)。

  • 其他怪癖之一的固定来源形式是,在字符上下文之外,语句中的空白并不重要。这可能会给代码作者,代码阅读器和代码编译器带来很大的混乱。根据标准,open语句实际上将由符合标准的Fortran编译器解析为对变量parameternn的错误赋值语句。这可能是一个参数语句 - 其语法是parameter(nn=100)。子例程中会出现类似的语句。他们使用的任何编译器都支持源语法作为语言的(不一致的)扩展。

  • 因为源使用隐式类型,请注意变量名中的转录错误可能无法检测到。您还需要考虑任何数字文字中这些错误的可能性。您将不得不仔细检查源,看它确实有意义。我选择的案例包括标记为222的语句中的15格式规范,可能应该是I5,并且在公共块规范中包含名为1P的变量,前导{{ 1}}不应该在那里。此外,一些格式规范使用hollerith编辑描述符,其方式并没有多大意义 - 我怀疑逗号和空格已被交换。

在许多情况下,您需要对原作者的意图进行逆向工程。

答案 1 :(得分:0)

Non-numeric character in statement label at (1)听起来你没有为固定格式正确格式化,这意味着第1列是为字母C保留的 - 意味着整行是注释或数字作为跳转标记,第6列在多行代码的情况下保留用于标记,第7列到第72列用于实际代码,请参阅此链接a german wiki https://de.wikibooks.org/wiki/Fortran:_FORTRAN_77:_Programmaufbau