Syntax Help for Cobol

Viewed 278

I am currently writing a program for my Cobol class to calculate the tuition of students. However, I keep getting syntax errors:

   jdoodle.cobc: in Paragraph '100-MAIN-Module':
   jdoodle.cobc:33: error: syntax error, unexpected END
   jdoodle.cobc:36: error: syntax error, unexpected END
   jdoodle.cobc:40: error: syntax error, unexpected END-PERFORM

I have tried deleting moving it elsewhere, checked spelling, and can not seem to get rid of these errors.

   IDENTIFICATION DIVISION.
   PROGRAM-ID. Tuition.
   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.
       SELECT IN-STUDENT-FILE 
           ASSIGN TO 'name.dat'
           ORGANIZATION IS LINE SEQUENTIAL.    
       SELECT OUT-STUDENT-FILE 
           ASSIGN TO 'tuition.dat'
           ORGANIZATION IS LINE SEQUENTIAL.
   DATA DIVISION.
   FILE SECTION.
   FD IN-STUDENT-FILE.
   01 IN-STUDENT-REC.
       05 STUDENTNAME-IN  PICTURE X(20).
       05 NUMCRED-IN      PICTURE 99.
       05                 PICTURE X(58).
   FD OUT-STUDENT-FILE.
   01 OUT-STUDENT-REC.
       05 STUDENTNAME-OUT PICTURE X(20).
       05                 PICTURE X(20).
       05 NUMCRED-OUT     PICTURE 99.
       05                 PICTURE X(20).
       05 TUITION-OUT     PICTURE X(4).
   WORKING-STORAGE SECTION.
   01 TUITION             PICTURE 9(4).
   01 EOF                 PICTURE X.
   PROCEDURE DIVISION.
   100-MAIN-MODULE.
       OPEN INPUT IN-STUDENT-FILE
            OUTPUT OUT-STUDENT-FILE
        PERFORM UNTIL END OF FILE = 'YES'
           READ IN-STUDENT-FILE
               AT END
                   MOVE 'YES' TO END OF FILE
               NOT AT END
                   PERFORM 200-PROCESS-RTN
           END-READ.
        END-PERFORM.
         CLOSE IN-STUDENT-FILE
               OUT-STUDENT-FILE
         STOP RUN.
   200-PROCESS-RTN.
       MOVE STUDENTNAME-IN TO STUDENTNAME-OUT
       MOVE NUMCRED-IN TO NUMCRED-OUT
       IF NUMCRED-IN < 12 THEN
           MULTIPLY NUMCRED-IN BY 525 GIVING TUITION
       ELSE
           SET TUITION TO 6300
       END-IF
       MOVE TUITION TO TUITION-OUT
       DISPLAY OUT-STUDENT-REC
       WRITE OUT-STUDENT-REC.

I am in my third week of class and besides a sample program that was given to us, this is the first I have tried to write.

3 Answers

You use a "variable" called END OF FILE.
For COBOL this is an invalid name as it includes the reserved word END, use END-OF-FILE instead and you get to another error with a better message telling you that END-OF-FILE is not defined; do so and you should be able to get further.

Two things. First, as was mentioned before field names cannot have spaces in them. Second: A period ends a statement not a verb. Don't use them unless you have to, which is only at the end of a paragraph; the scope terminators by themselves are are fine unless it's on the last statement in a paragraph.

  PERFORM UNTIL END-OF-FILE = 'YES'
     READ IN-STUDENT-FILE
        AT END
           MOVE 'YES' TO END-OF-FILE
        NOT AT END
           PERFORM 200-PROCESS-RTN
     END-READ. <- This period ends the statement not just the read
  END-PERFORM.  <- leaving this hanging

There are a variety of different aspects to this code that you could change. Firstly, there is no specific requirement for capitalisation. Lowercase can be used and personally, i believe this to be a lot easier on the eye.

You also don't need to use 'picture' and this can be abbreviated to 'pic', saving time on development.

using a variable named 'END OF FILE' is not necessary, it's a lot easier to simply make a flag and initialise that as false to start with before being able to manipulate this when required, level 88 variables are great for this.

Again, this is completely down to personal preference but i don't like to use paragraphs and stick to sections, i feel like this makes it a lot easier to manage the structure of your programme.

In your code you have used full-stops at the end of the read, the full-stop on its own would be seen as 'end-read' therefore as you already have one the compiler is reading the first full-stop as 'end-perform' and throwing an error for this. The way i use full stops is having one at the end of each section, clearly visible so that i know its there.

I have refactored your code in the way that i would have wrote it. Please have a look over this and see what you think.

identification division.
program-id. Tuition.
environment division.
input-output section.
file-control.
   select in-student-file
       assign to 'name.dat'
       organization is line sequential.    
   select out-student-file 
       assign to 'tuition.dat'
       organization is line sequential.

data division.    
file section.    
   fd in-student-file.    
      01 in-student-rec.
         05 studentname-in  pic x(20).
         05 numcred-in      pic 99.
         05                 pic X(58).    

   fd out-section-file.    
      01 out-student-rec.
         05 studentname-out pic X(20).
         05                 pic X(20).
         05 numcred-out     pic 99.
         05                 pic X(20).
         05 tuition-out     pic X(4).    
working-storage section.    
   01  tuition              pic 9(4).   
   01  ws-file-at-end       pic x.
       88 fl-eof            value "Y" false "N". 

procedure division.

*************************************************
*********Structure of programme******************
*************************************************    
main section.
   perform startup
   perform main-process until fl-eof-true
   perform closedown
   go-back
   .

*************************************************
***********Open necessary files******************
*************************************************
startup section.
   open input in-student-file
   open output out-student-file
   set fl-eof to false
   .

*************************************************
********Reads until flag end of file*************
*************************************************
main-process section.
   read in-student-file
      at end 
        set fl-eof to true
      not at end
        perform process-and-return
   end-read
   .

*************************************************
******Process the student tuition****************
*************************************************
process-and-return section.
   move studentname-in to studentname-out
   move numcred-in to numcred-out

   if numcred-in < 12 then
      multiply numcred-in by 525 giving tuition
   else
      set tuition to 6300
   end-if

   move tuition to tuition-out
   display out-student-rec
   write out-student-rec
   .

*************************************************
******Close all necessary files******************
*************************************************
closedown section.
   close in-student-file
   close out-student-file
   .          
Related