You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

COBOL程序编译报错:意外标识符等语法问题求助

COBOL程序编译错误排查与修复建议

问题背景

正在完成学校作业的COBOL程序,编译时遇到多个无法定位原因的报错,程序代码及报错信息如下:

编译报错信息

Assign6.cbl:61: error: syntax error, unexpected Identifier
Assign6.cbl:72: error: 'INFILE' is not a field
Assign6.cbl:73: error: syntax error, unexpected NOT END
Assign6.cbl:130: error: syntax error, unexpected END-READ
Assign6.cbl:133: error: syntax error, unexpected Identifier
Assign6.cbl:137: error: syntax error, unexpected Identifier
Assign6.cbl:138: error: syntax error, unexpected Identifier
Assign6.cbl:139: error: syntax error, unexpected Identifier
Assign6.cbl:140: error: syntax error, unexpected Identifier
Assign6.cbl:144: error: syntax error, unexpected Identifier
Assign6.cbl:145: error: syntax error, unexpected Identifier
Assign6.cbl:146: error: syntax error, unexpected Identifier
Assign6.cbl:147: error: syntax error, unexpected Identifier
Assign6.cbl:151: error: syntax error, unexpected Identifier
Assign6.cbl:152: error: syntax error, unexpected Identifier
Assign6.cbl:153: error: syntax error, unexpected Identifier
Assign6.cbl:154: error: syntax error, unexpected Identifier

原程序代码

ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT INFILE ASSIGN TO "C:\home\josh\DataFiles\
      -         "Assignment#6_WeeklySalaryDataFile.dat"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT OUTPUT-FILE-A ASSIGN TO "C:\DataFiles\Salesperson
      -         "Recognition.rpt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT OUTPUT-FILE-B ASSIGN TO "C:\DataFiles\Salary
      -         "Expense.rpt"
               ORGANIZATION IS LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.
       FD  INFILE.
       01  INPUT-RECORD.
           05  EMPLOYEE-ID              PIC X(4).
           05  JOB-CODE                 PIC X.
           05  LAST-NAME                PIC X(14).
           05  FIRST-NAME               PIC X(14).
           05  START-DATE               PIC X(8).
           05  STORE-NUMBER             PIC X(4).
           05  WEEKLY-SALARY            PIC 9(6).
           05  SALES-AMOUNT             PIC 9(7).
       FD  OUTPUT-FILE-A.
       01  OUTPUT-RECORD-A.
           05  LAST-NAME-A              PIC X(14).
           05  FIRST-NAME-A             PIC X(14).
           05  STORE-NUMBER-A           PIC X(4).
       FD  OUTPUT-FILE-B.
       01  OUTPUT-RECORD-B.
           05  STORE-NUMBER-B           PIC X(4).
           05  JOB-CODE-B               PIC X.
           05  TOTAL-SALARY             PIC 9(4)V99.

       WORKING-STORAGE SECTION.
       01  PRESENT-DATE               PIC X(8).
       01  STORE1-M-TOTAL             PIC 9(4)V99.
       01  STORE1-S-TOTAL             PIC 9(4)V99.
       01  STORE1-A-TOTAL             PIC 9(4)V99.
       01  STORE1-C-TOTAL             PIC 9(4)V99.
       01  STORE2-M-TOTAL             PIC 9(4)V99.
       01  STORE2-S-TOTAL             PIC 9(4)V99.
       01  STORE2-A-TOTAL             PIC 9(4)V99.
       01  STORE2-C-TOTAL             PIC 9(4)V99.
       01  STORE3-M-TOTAL             PIC 9(4)V99.
       01  STORE3-S-TOTAL             PIC 9(4)V99.
       01  STORE3-A-TOTAL             PIC 9(4)V99.
       01  STORE3-C-TOTAL             PIC 9(4)V99.

       PROCEDURE DIVISION.
           OPEN INPUT INFILE
           OPEN OUTPUT OUTPUT-FILE-A
           OPEN OUTPUT OUTPUT-FILE-B
           MOVE FUNCTION CURRENT-DATE TO PRESENT-DATE
           WRITE OUTPUT-RECORD-A FROM "Employee recognition for the 
      -     "week ending: " PRESENT-DATE  (line 61/62)
           WRITE OUTPUT-RECORD-A FROM "--------------------------------
      -     "--------------------"
           WRITE OUTPUT-RECORD-A FROM "Last Name  First 
      -     "Name  Store #"
           WRITE OUTPUT-RECORD-A FROM "--------------------------------
      -     "--------------------"
           READ INFILE 
               AT END
                   GO TO END-READ
           PERFORM UNTIL INFILE **(line 72)**
               NOT AT END       **(line 73)**
               MOVE INPUT-RECORD TO OUTPUT-RECORD-A
                   IF JOB-CODE = 'S' AND
                       SALES-AMOUNT > 100000
                   THEN
                       WRITE OUTPUT-RECORD-A
                   END-IF
                   IF STORE-NUMBER = '0001'
                   THEN
                       IF JOB-CODE = 'M'
                       THEN
                           ADD WEEKLY-SALARY TO STORE1-M-TOTAL
                       ELSE IF JOB-CODE = 'S'
                       THEN
                           ADD WEEKLY-SALARY TO STORE1-S-TOTAL
                       ELSE IF JOB-CODE = 'A'
                       THEN
                           ADD WEEKLY-SALARY TO STORE1-A-TOTAL
                       ELSE IF JOB-CODE = 'C'
                       THEN
                           ADD WEEKLY-SALARY TO STORE1-C-TOTAL
                       END-IF
                   ELSE IF STORE-NUMBER = '0002'
                   THEN
                       IF JOB-CODE = 'M'
                       THEN
                           ADD WEEKLY-SALARY TO STORE2-M-TOTAL
                       ELSE IF JOB-CODE = 'S'
                       THEN
                           ADD WEEKLY-SALARY TO STORE2-S-TOTAL
                       ELSE IF JOB-CODE = 'A'
                       THEN
                           ADD WEEKLY-SALARY TO STORE2-A-TOTAL
                       ELSE IF JOB-CODE = 'C'
                       THEN
                           ADD WEEKLY-SALARY TO STORE2-C-TOTAL
                       END-IF
                   ELSE IF STORE-NUMBER = '0003'
                   THEN
                       IF JOB-CODE = 'M'
                       THEN
                           ADD WEEKLY-SALARY TO STORE3-M-TOTAL
                       ELSE IF JOB-CODE = 'S'
                       THEN
                           ADD WEEKLY-SALARY TO STORE3-S-TOTAL
                       ELSE IF JOB-CODE = 'A'
                       THEN
                           ADD WEEKLY-SALARY TO STORE3-A-TOTAL
                       ELSE IF JOB-CODE = 'C'
                       THEN
                           ADD WEEKLY-SALARY TO STORE3-C-TOTAL
                       END-IF
                   END-IF
                   READ INFILE AT END
                       GO TO END-READ
               END-PERFORM
           END-READ.  (line 130)
           WRITE OUTPUT-RECORD-B FROM "Salary expense for the week 
      -     "ending: " 
               PRESENT-DATE   (line 133)
           WRITE OUTPUT-RECORD-B FROM "--------------------------------
      -     "--------------------"
           WRITE OUTPUT-RECORD-B FROM "STORE #1"
           WRITE OUTPUT-RECORD-B FROM "Management: " STORE1-M-TOTAL**(line137)**
           WRITE OUTPUT-RECORD-B FROM "Sales: " STORE1-S-TOTAL **(line 138)**
           WRITE OUTPUT-RECORD-B FROM "Admin: " STORE1-A-TOTAL **(line 139)**
           WRITE OUTPUT-RECORD-B FROM "Custodial: " STORE1-C-TOTAL **(line 140)**
           WRITE OUTPUT-RECORD-B FROM "-------------------------------
      -     "---------------------"
           WRITE OUTPUT-RECORD-B FROM "STORE #2"
           WRITE OUTPUT-RECORD-B FROM "Management: " STORE2-M-TOTAL **(line 144)**
           WRITE OUTPUT-RECORD-B FROM "Sales: " STORE2-S-TOTAL **(line 145)**
           WRITE OUTPUT-RECORD-B FROM "Admin: " STORE2-A-TOTAL **(line 146)**
           WRITE OUTPUT-RECORD-B FROM "Custodial: " STORE2-C-TOTAL **(l 147)**
           WRITE OUTPUT-RECORD-B FROM "--------------------------------
      -     "--------------------"
           WRITE OUTPUT-RECORD-B FROM "STORE #3"
           WRITE OUTPUT-RECORD-B FROM "Management: " STORE3-M-TOTAL **(l 151)**
           WRITE OUTPUT-RECORD-B FROM "Sales: " STORE3-S-TOTAL  **(line 152)**
           WRITE OUTPUT-RECORD-B FROM "Admin: " STORE3-A-TOTAL **(line 153)**
           WRITE OUTPUT-RECORD-B FROM "Custodial: " STORE3-C-TOTAL **(line 154)**
           WRITE OUTPUT-RECORD-B FROM "--------------------------------
      -     "--------------------"
           CLOSE INFILE, OUTPUT-FILE-A, OUTPUT-FILE-B
           STOP RUN.

       end program Assignment6.

错误分析与修复步骤

1. WRITE语句语法错误(第61、133、137-154行)

COBOL的WRITE语句不允许在FROM子句中直接拼接字符串常量和变量,必须先将内容组合到预定义变量中:

  • 在WORKING-STORAGE SECTION添加输出组合变量:
    01  OUTPUT-LINE-A        PIC X(42).
    01  OUTPUT-LINE-B        PIC X(42).
    01  EDITED-SALARY        PIC $$$$.$9.
    
  • 使用STRING语句拼接内容后写入,例如第61行的修复:
    STRING "Employee recognition for the week ending: "
           PRESENT-DATE
           INTO OUTPUT-LINE-A
    WRITE OUTPUT-RECORD-A FROM OUTPUT-LINE-A
    
  • 数值汇总行需先编辑为可读格式再拼接,例如第137行:
    MOVE STORE1-M-TOTAL TO EDITED-SALARY
    STRING "Management: " EDITED-SALARY INTO OUTPUT-LINE-B
    WRITE OUTPUT-RECORD-B FROM OUTPUT-LINE-B
    

2. PERFORM循环条件错误(第72-73行)

COBOL不能直接将文件标识符作为PERFORM UNTIL的判断条件,需使用文件结束标志位:

  • 在WORKING-STORAGE SECTION添加标志位:
    01  END-OF-FILE-FLAG     PIC X VALUE 'N'.
    
  • 修改READ语句的AT END逻辑,替换GO TO为标志位赋值:
    READ INFILE
        AT END
            MOVE 'Y' TO END-OF-FILE-FLAG
    
  • 重构PERFORM循环:
    PERFORM UNTIL END-OF-FILE-FLAG = 'Y'
        MOVE INPUT-RECORD TO OUTPUT-RECORD-A
        * 原循环内IF逻辑保持不变
        READ INFILE
            AT END
                MOVE 'Y' TO END-OF-FILE-FLAG
    END-PERFORM
    

3. 多余的END-READ(第130行)

原代码中第一个READ语句未使用多行AT END逻辑,不需要END-READ关键字,直接删除该行即可。

4. 文件路径续行错误

COBOL字符串续行需在续行第7列放置续行符(通常为-),修改为:

SELECT INFILE ASSIGN TO "C:\home\josh\DataFiles\
-------         "Assignment#6_WeeklySalaryDataFile.dat"
               ORGANIZATION IS LINE SEQUENTIAL.

或直接将路径写在一行避免续行。

修复后核心代码示例

WORKING-STORAGE SECTION.
       01  PRESENT-DATE               PIC X(8).
       01  END-OF-FILE-FLAG           PIC X VALUE 'N'.
       01  OUTPUT-LINE-A              PIC X(42).
       01  OUTPUT-LINE-B              PIC X(42).
       01  EDITED-SALARY              PIC $$$$.$9.
       * 其余汇总变量保持不变...

       PROCEDURE DIVISION.
           OPEN INPUT INFILE
           OPEN OUTPUT OUTPUT-FILE-A
           OPEN OUTPUT OUTPUT-FILE-B
           MOVE FUNCTION CURRENT-DATE TO PRESENT-DATE
           * 修复第61行WRITE逻辑
           STRING "Employee recognition for the week ending: "
                  PRESENT-DATE
                  INTO OUTPUT-LINE-A
           WRITE OUTPUT-RECORD-A FROM OUTPUT-LINE-A
           WRITE OUTPUT-RECORD-A FROM "--------------------------------------------"
           WRITE OUTPUT-RECORD-A FROM "Last Name  First Name  Store #"
           WRITE OUTPUT-RECORD-A FROM "--------------------------------------------"
           READ INFILE
               AT END
                   MOVE 'Y' TO END-OF-FILE-FLAG
           PERFORM UNTIL END-OF-FILE-FLAG = 'Y'
               MOVE INPUT-RECORD TO OUTPUT-RECORD-A
               IF JOB-CODE = 'S' AND SALES-AMOUNT > 100000
                   WRITE OUTPUT-RECORD-A
               END-IF
               * 原STORE和JOB-CODE判断逻辑保持不变...
               READ INFILE
                   AT END
                       MOVE 'Y' TO END-OF-FILE-FLAG
           END-PERFORM
           * 修复第133行WRITE逻辑
           STRING "Salary expense for the week ending: "
                  PRESENT-DATE
                  INTO OUTPUT-LINE-B
           WRITE OUTPUT-RECORD-B FROM OUTPUT-LINE-B
           WRITE OUTPUT-RECORD-B FROM "--------------------------------------------"
           WRITE OUTPUT-RECORD-B FROM "STORE #1"
           * 修复第137行汇总WRITE逻辑
           MOVE STORE1-M-TOTAL TO EDITED-SALARY
           STRING "Management: " EDITED-SALARY INTO OUTPUT-LINE-B
           WRITE OUTPUT-RECORD-B FROM OUTPUT-LINE-B
           * 其余汇总行按相同方式修复...
           CLOSE INFILE, OUTPUT-FILE-A, OUTPUT-FILE-B
           STOP RUN.

内容的提问来源于stack exchange,提问作者J Phil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 21:27:02