Search code examples
cobolmainframe

Errors in if Statement


I'm getting the following errors in one, but not both, of my if statements.

 165  IGYPS2000-S   Expected a data-name, but found "TO".  The "ADD" statement was discarded.

 169  IGYPS2096-S   An incomplete condition was found in a conditional expression.  The operand(s) was(were) discarded.

 169  IGYPS2079-S   Expected a verb or "NEXT SENTENCE", but found ""F"".  The statement was discarded.            




           IF MARITAL-STATUS-IN = "S"
           ADD 1 TO SINGLE-COUNT
           ADD 1 TO OVERALL-COUNT
           ADD SALARY-IN TO SINGLE-TOTAL
           ADD SALARY-IN TO OVERALL-TOTAL
           IF GENDER-IN = "M"
               ADD 1 TO SINGLE-MALE-COUNT
               ADD SALARY-IN TO SINGLE-MALE-TOTAL
           IF GENDER-IN = "F"
               ADD 1 TO SINGLE-FEMALE-COUNT
               ADD SALARY-IN TO SINGLE-FEMALE-TOTAL
       END-IF.

       IF MARITAL-STATUS-IN = "M"
           ADD 1 TO MARRIED-COUNT
           ADD 1 TO OVERALL-COUNT               line 165
           ADD SALARY-IN TO MARRIED-TOTAL
           ADD SALARY IN TO OVERALL-TOTAL
           IF GENDER-IN = "M"
               ADD 1 TO MARRIED-MALE-COUNT
               ADD SALARY-IN TO MARRIED-MALE-TOTAL
           IF GENDER-IN "F"
               ADD 1 TO MARRIED-FEMALE-COUNT
               ADD SALARY-IN TO MARRIED-FEMALE-TOTAL
       END-IF.

If you need to see anymore of my code just let me know. This is my first time writing nested if's.


Solution

  • piet.t and Bruce Martin have correctly spotted the errors which are giving you those compiler diagnostics. You did not help by listing the wrong line as number 165.

    An easy thing to do to avoid this problem is to get the compiler to embed the diagnostics, as well as listing them at the end of the compile. Indeed it is unusual for this not to be the default at your installation.

    To get around it not being the default you can do this:

    CBL FLAG(I,I)
    

    Start that in column 12, and make it the first line in the program source whilst you are testing.

    The first I says "list diagnostic messages at the end of the compile listing, from severity I upwards". The second I says "embed diagnostic messages in the compile listing of the source, from severity I upwards".

    All compiler options and information about ways to use them is included in the Enterprise COBOL Programming Guide, available for free on the internet from IBM.

    The relevant part of the listing would look something like this (I'm just pasting in without reference to an actual listing):

       IF MARITAL-STATUS-IN = "S"
       ADD 1 TO SINGLE-COUNT
       ADD 1 TO OVERALL-COUNT
       ADD SALARY-IN TO SINGLE-TOTAL
       ADD SALARY-IN TO OVERALL-TOTAL
       IF GENDER-IN = "M"
           ADD 1 TO SINGLE-MALE-COUNT
           ADD SALARY-IN TO SINGLE-MALE-TOTAL
           IF GENDER-IN = "F"
               ADD 1 TO SINGLE-FEMALE-COUNT
               ADD SALARY-IN TO SINGLE-FEMALE-TOTAL
       END-IF.
    
       IF MARITAL-STATUS-IN = "M"
           ADD 1 TO MARRIED-COUNT
           ADD 1 TO OVERALL-COUNT              
           ADD SALARY-IN TO MARRIED-TOTAL
           ADD SALARY IN TO OVERALL-TOTAL
     165  IGYPS2000-S   Expected a data-name, but found "TO".  The "ADD" statement was discarded.
    
           IF GENDER-IN = "M"
               ADD 1 TO MARRIED-MALE-COUNT
               ADD SALARY-IN TO MARRIED-MALE-TOTAL
           IF GENDER-IN "F"
     169  IGYPS2096-S   An incomplete condition was found in a conditional expression.  The operand(s) was(were) discarded.
    
     169  IGYPS2079-S   Expected a verb or "NEXT SENTENCE", but found ""F"".  The statement was discarded.            
               ADD 1 TO MARRIED-FEMALE-COUNT
               ADD SALARY-IN TO MARRIED-FEMALE-TOTAL
       END-IF.
    

    As has been pointed out, you have some problems with the way you have constructed your IFs as well:

    IF MARITAL-STATUS-IN = "S"
        ADD 1 TO SINGLE-COUNT
        ADD 1 TO OVERALL-COUNT
        ADD SALARY-IN TO SINGLE-TOTAL
        ADD SALARY-IN TO OVERALL-TOTAL
        IF GENDER-IN = "M"
            ADD 1 TO SINGLE-MALE-COUNT
            ADD SALARY-IN TO SINGLE-MALE-TOTAL
                IF GENDER-IN = "F"
                    ADD 1 TO SINGLE-FEMALE-COUNT
                    ADD SALARY-IN TO SINGLE-FEMALE-TOTAL
                END-IF.
    
                IF MARITAL-STATUS-IN = "M"
                    ADD 1 TO MARRIED-COUNT
                    ADD 1 TO OVERALL-COUNT              
                    ADD SALARY-IN TO MARRIED-TOTAL
                    ADD SALARY IN TO OVERALL-TOTAL
                    IF GENDER-IN = "M"
                        ADD 1 TO MARRIED-MALE-COUNT
                        ADD SALARY-IN TO MARRIED-MALE-TOTAL
                        IF GENDER-IN "F"
                            ADD 1 TO MARRIED-FEMALE-COUNT
                            ADD SALARY-IN TO MARRIED-FEMALE-TOTAL
                        END-IF.
    

    You are using two different methods to terminate your IFs. The END-IF scope-delimiter and the full-stop/period. The use of the second means that your indentation does not match the "logical" indentation.

    IF MARITAL-STATUS-IN = "S"
        ADD 1 TO SINGLE-COUNT
        ADD 1 TO OVERALL-COUNT
        ADD SALARY-IN TO SINGLE-TOTAL
        ADD SALARY-IN TO OVERALL-TOTAL
        IF GENDER-IN = "M"
            ADD 1 TO SINGLE-MALE-COUNT
            ADD SALARY-IN TO SINGLE-MALE-TOTAL
                IF GENDER-IN = "F"
                    ADD 1 TO SINGLE-FEMALE-COUNT
                    ADD SALARY-IN TO SINGLE-FEMALE-TOTAL
                END-IF.
    
    IF MARITAL-STATUS-IN = "M"
        ADD 1 TO MARRIED-COUNT
        ADD 1 TO OVERALL-COUNT              
        ADD SALARY-IN TO MARRIED-TOTAL
        ADD SALARY IN TO OVERALL-TOTAL
        IF GENDER-IN = "M"
            ADD 1 TO MARRIED-MALE-COUNT
            ADD SALARY-IN TO MARRIED-MALE-TOTAL
            IF GENDER-IN "F"
                ADD 1 TO MARRIED-FEMALE-COUNT
                ADD SALARY-IN TO MARRIED-FEMALE-TOTAL
            END-IF.
    

    Note, I have not corrected your nesting for the GENDER-IN test.

    It is much, much better to just use the scope-delimiter to end any conditions. Use an absolute minimum of full-stops/periods.

    PROCEDURE DIVISION.
    any-paragraph-name-or-SECTION-name.
        some code 
        . 
    

    That is: end of PROCEDURE DIVISION header (after the items on USING if you have one of those); before a paragraph/SECTION; end of a paragraph/SECTION label; end of a paragraph/SECTION; end of the program.

    There is some overlap there, as a program does not require that there are paragraphs/SECTIONS within it.

    Keep the content of your IFs simple. Avoid repeated code. I've put an example of your code, re-arranged, following. There are two styles, the nested-IF for the Single (since the purpose of this work is probably the nested-IF) and a different way for the Married.

    IF MARITAL-STATUS-IN = "S"
        PERFORM COUNT-ANY-PERSON
        PERFORM COUNT-SINGLE-PEOPLE
        IF GENDER-IN = "M"
            ADD 1 TO SINGLE-MALE-COUNT
            ADD SALARY-IN TO SINGLE-MALE-TOTAL
        END-IF
        IF GENDER-IN = "F"
            ADD 1 TO SINGLE-FEMALE-COUNT
            ADD SALARY-IN TO SINGLE-FEMALE-TOTAL
        END-IF
    END-IF
    
    IF MARITAL-STATUS-IN = "M"
        PERFORM COUNT-ANY-PERSON
        PERFORM COUNT-MARRIED-PEOPLE
    END-IF
        .
    COUNT-ANY-PERSON.
        ADD 1 TO OVERALL-COUNT
        ADD SALARY-IN TO OVERALL-TOTAL
        .
    COUNT-SINGLE-PEOPLE.
        ADD 1 TO SINGLE-COUNT
        ADD SALARY-IN TO SINGLE-TOTAL
        .
    COUNT-MARRIED-PEOPLE.
        ADD 1 TO MARRIED-COUNT
        ADD SALARY-IN TO MARRIED-TOTAL
        IF GENDER-IN = "M"
            ADD 1 TO MARRIED-MALE-COUNT
            ADD SALARY-IN TO MARRIED-MALE-TOTAL
        END-IF
        IF GENDER-IN = "F"
            ADD 1 TO MARRIED-FEMALE-COUNT
            ADD SALARY-IN TO MARRIED-FEMALE-TOTAL
        END-IF
        .
    

    Married/single may be mutually exclusive. If so, use ELSE rather than the second test. Male/female may be mutually exclusive. If so, use ELSE rather than the second test. If they are not mutually exclusive, find out what else you need to count, rather then just have data slip through the program.

    You should look to use 88-level condition names, rather that test for literals. Makes your program easier to understand, and easier to maintain.