LL1P80: PROC;
/****************************************************************
*               LL(1) GRAMMAR ANALYZER - PHASE 8                *
*PURPOSE:                                                       *
*    THIS PROGRAM VALIDATES THAT THE GRAMMAR ANALYZED WAS IN-   *
*    DEED LL(1).  THIS IS DONE BY INSURING THAT THE SELECTION   *
*    SETS OF ALL PRODUCTIONS WITH THE SAME LEFT-HAND-SIDE ARE   *
*    DISJOINT (I.E. HAVE NO COMMON ELEMENTS).                   *
*INPUT:                                                         *
*    1) BASIC GRAMMAR TABLES                                    *
*    2) NULLABLE NON-TERMINALS AND PRODUCTIONS TABLES           *
*    3) ARRAY2 = THE SELECTION SET FOR ALL PRODUCTIONS          *
*OUTPUT:                                                        *
*OUTLINE:                                                       *
*REMARKS:                                                       *
****************************************************************/

/****************************************************************
* * * * * * * * * * * COMMON DATA DEFINITIONS * * * * * * * * * *
****************************************************************/

/*      * * *  COMMON REPLACEMENTS  * * *       */
%REPLACE TRUE BY '1'B;
%REPLACE FALSE BY '0'B;

%INCLUDE 'LL1CMN.DCL';  /* GET COMMON AREAS. */
       DCL NUM_ERR FIXED;


/****************************************************************
* * * * * * * * * * * COMMON PROCUDURES * * * * * * * * * * * * *
****************************************************************/


%INCLUDE 'LL1PRC.DCL';


/****************************************************************
* * * * * * * * * * GRAMMAR ANALYSIS PROCEDURES * * * * * * * * *
****************************************************************/


VALD_SS: PROC;
/*THIS ROUTINE IS VALIDATES THAT ALL SELECTION SETS FOR   */
/*EACH NON-TERMINAL ARE DISJOINT.  */
       DCL I FIXED;            /* INDICES */
       DCL J FIXED;
       DCL K FIXED;
       DCL L FIXED;
       DCL SAMLHS(256) BIN(15);
       DCL NUMSAM BIN(15);
       DCL CURNTRM CHAR;
       DCL TMPSET(32) BIT(8);
       DCL DISJNT BIT(1);

/* MAIN LOOP - LOOP FOR ALL NONTERMINALS. */
       DO I=1 TO LENGTH(NTRM);
          CURNTRM=SUBSTR(NTRM,I,1);

/* FIND ALL PRODUCTIONS FOR THIS NON-TERMINAL WHERE IT IS THE LHS. */
          NUMSAM=0;
          DO J=1 TO NUMPRD;
             IF CURNTRM=LHS(J) THEN    /**NON-TERMINAL IS LHS**/
                DO;
                   NUMSAM=NUMSAM+1;
                   SAMLHS(NUMSAM)=J;   /*SAVE PRODUCTION NUMBER.*/
                END;
          END;

/* INSURE THAT ALL SELECTION SETS FOR THIS NON-TERMINAL ARE DISJOINT. */
          IF NUMSAM<2 THEN     /*NOT ENOUGH SETS*/
             ;
          ELSE
             DO J=1 TO NUMSAM-1; /*LOOP FOR EACH SET*/
                DO K=J+1 TO NUMSAM; /*LOOP FOR REMAINING SETS*/
                   DO L=1 TO 32; /*FIND COMMON ELEMENTS*/
                      TMPSET(L)=ARRAY2(SAMLHS(J),L) & ARRAY2(SAMLHS(K),L);
                   END;
                   DISJNT=TRUE; /*DEFAULT TO DISJOINT*/
                   DO L=1 TO 32;
                      IF TMPSET(L)='00000000'B THEN /**DISJOINT**/
                         ;
                      ELSE
                         DO;
                            DISJNT=FALSE;
                            L=32;
                         END;
                   END;
                   IF DISJNT THEN
                      ;
                   ELSE
                      DO;
                         NUM_ERR=NUM_ERR+1;
                         PUT FILE(LSTFIL) SKIP
                          LIST('***WARNING: THE SELECTION SET FOR',
                               ' PRODUCTIONS',SAMLHS(J),' AND',SAMLHS(K),
                               ' ARE NOT DISJOINT!!!');
                      END;
                END;
             END;

/* END OF MAIN LOOP */
       END;

/* RETURN TO CALLER. */
       END VALD_SS;


/****************************************************************
* * * * * * * * * * * GRAMMAR PRINT PROCUDURES * * * * * * * * **
****************************************************************/

PRINT_PRODUCTIONS: PROC;
/*THIS ROUTINE IS RESPONSIBLE FOR PRINTING THE VOCABULARY. */
       DCL I BIN(15);          /* INDEXES */
       DCL J BIN(15);
       DCL K BIN(15);
       DCL NUM_LINES BIN(15);  /* MAXIMUM NUMBER OF LINES */
       DCL LHS_ENT CHAR(10) VARYING;
       DCL RHS_ENT(5) CHAR(10) VARYING;

/* OUTPUT THE HEADING. */
       ON ENDPAGE(LSTFIL)
          BEGIN;
             PUT FILE(LSTFIL) PAGE;
             PUT FILE(LSTFIL) SKIP(3)
                 EDIT('*** PRODUCTION LISTING W/SELECTION SETS***','PAGE',
                       PAGENO(LSTFIL)-1)
                 (X(20),A(42),X(10),A(4),F(4));
             PUT FILE(LSTFIL) SKIP(1);
          END;
       SIGNAL ENDPAGE(LSTFIL);

/* PRINT THE REPORT LINES. */
       PUT FILE(LSTFIL) SKIP(1)
                 EDIT('STARTING SYMBOL: ',VOC(CHRNUM(STRSYM)))
                 (X(14),A(17),A(10));
       DO I=1 TO NUMPRD;
          LHS_ENT=VOC(CHRNUM(LHS(I)));
          DO J=1 TO 5;
             IF J>LENGTH(RHS(I)) THEN
                RHS_ENT(J)='';
             ELSE
                RHS_ENT(J)=VOC(CHRNUM(SUBSTR(RHS(I),J,1)));
          END;
          PUT FILE(LSTFIL) SKIP(1)
              EDIT(I,LHS_ENT,' -> ',(RHS_ENT(J) DO J=1 TO 5),';')
                 (F(4),X(01),A,A(04),5(A,X(01)),A(1));
          PUT FILE(LSTFIL) SKIP(1) EDIT('{') (X(20),A);
          K=0;
          DO J=LENGTH(NTRM)+1 TO NUMVOC;
             IF TSTBIT(I,J,ADDR(ARRAY2)) THEN
                DO;
                   K=K+1;
                   IF K>9 THEN
                      DO;
                         PUT FILE(LSTFIL) SKIP EDIT(' ') (X(20),A);
                         K=0;
                      END;
                   PUT FILE(LSTFIL) LIST(VOC(J)||' ');
                END;
          END;
          IF TSTBIT(I,NUMVOC+1,ADDR(ARRAY2)) THEN
             PUT FILE(LSTFIL) LIST('''_|_'' }');
          ELSE
             PUT FILE(LSTFIL) LIST('}');
          PUT FILE(LSTFIL) SKIP;
       END;

       END  PRINT_PRODUCTIONS;


/****************************************************************
* * * * * * * * * * * MAIN LINE PROCEDURE * * * * * * * * * * * *
****************************************************************/


/* ANALYZE THE GRAMMAR. */
       PUT SKIP LIST('BEGINNING PHASE 8 PROCESSING.');
       PUT FILE(LSTFIL) PAGE;

/* CALCULATE THE SELECTION SET. */
       PUT SKIP LIST('VALIDATING THE SELECTION SETS...');
       NUM_ERR=0;
       CALL VALD_SS;           /*VALIDATE THE RELATION.*/

/* PRINT THE PRODUCTIONS IF NO ERRORS. */
       PUT SKIP LIST('PRINTING THE PRODUCTIONS...');
       IF NUM_ERR=0 THEN
          CALL PRINT_PRODUCTIONS;      /*VALIDATE THE RELATION.*/

/* RETURN TO CALLER. */
       PUT FILE(LSTFIL) SKIP LIST('THERE WERE',NUM_ERR,' ERRORS FOUND.');
       PUT SKIP LIST('THERE WERE',NUM_ERR,' ERRORS FOUND.');
       PUT SKIP LIST('PHASE 8 PROCESSING COMPLETE.');
       END LL1P80;