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

