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: *
****************************************************************/
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;
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;
/* 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;