CALC_BDW: PROC;
/*THIS ROUTINE IS RESPONSIBLE FOR CALCULATING THE RELATION*/
/*BEGINS-DIRECTLY-WITH. WE SAY THAT <A> BEGINS-DIRECTLY- */
/*WITH B IF A SEQUENCE BEGINNING WITH B CAN BE OBTAINED */
/*FROM A BY APPLYING EXACTLY ONE PRODUCTION AND THEN OP- */
/*TIONALLY REPLACING NON-TERMINALS WITH EPSILON. THUS, WE*/
/*BUILD THE RELATIONSHIP FOR ALL NON-TERMINALS WHICH HAVE */
/*A NONE NULL RIGHT-HAND-SIDE. FIRST, THE FIRST SYMBOL ON*/
/*THE RIGHT-HAND-SIDE IS PART OF THE RELATIONSHIP. ALSO, */
/*THE FOLLOWING SYMBOL IS PART OF IT AS LONG AS THE CUR- */
/*RENT ONE IS A NULLABLE NON-TERMINAL. */
DCL I BIN(15); /* INDEXES */
DCL J BIN(15);
/* CALCULATE THE RELATION. */
DO I=1 TO NUMPRD; /* LOOP THRU ALL PRODUCTIONS. */
IF LENGTH(RHS(I))=0 THEN /*EPSILON PRODUCTION*/
;
ELSE
DO J=1 TO LENGTH(RHS(I));
CALL SETBIT(CHRNUM(LHS(I)),
CHRNUM(SUBSTR(RHS(I),J,1)),ADDR(ARRAY1));
IF ISNLNT(SUBSTR(RHS(I),J,1)) THEN
;
ELSE
J=LENGTH(RHS(I));
END;
END;
/* RETURN TO CALLER. */
END CALC_BDW;
CALC_BW: PROC;
/*THIS ROUTINE IS RESPONSIBLE FOR CALCULATING THE RELATION*/
/*BEGINS-WITH. BEGINS-WITH IS THE REFLEXIVE TRANSITIVE */
/*CLOSURE OF THE RELATION, BEGINS-DIRECTLY-WITH. */
/* CALCULATE IT. */
CALL CLOSUR(ADDR(ARRAY1));
/* RETURN TO CALLER. */
END CALC_BW;
CALC_FIRST: PROC;
/*THIS ROUTINE IS RESPONSIBLE FOR CALCULATING THE RELATION*/
/*FIRST FOR PROCUTIONS. WE SAY THAT THE FIRST RELATION */
/*FOR A PRODUCTION IS THE UNION OF THE FIRST SYMBOL RELA- */
/*TION INCLUDING AND UNTIL THE FIRST NON-NULLABLE NON- */
/*TERMINAL IS FOUND OR A TERMINAL IS FOUND. THE FIRST */
/*SYMBOL RELATION IS SIMPLY THE PORTION OF THE BEGINS-WITH*/
/*MATRIX FOR NON-TERMINALS HORIZONTALLY AND TERMINALS */
/*VERTICALLY. */
DCL I BIN(15); /* INDEXES */
DCL J BIN(15);
DCL K BIN(15);
/* CALCULATE THE RELATION. */
DO I=1 TO NUMPRD; /* LOOP THRU ALL PRODUCTIONS. */
IF LENGTH(RHS(I))=0 THEN /*EPSILON PRODUCTION*/
;
ELSE
DO J=1 TO LENGTH(RHS(I));
IF ISTRM(SUBSTR(RHS(I),J,1)) THEN /**TERMINAL**/
DO;
CALL SETBIT(I,CHRNUM(SUBSTR(RHS(I),J,1)),
ADDR(ARRAY2));
J=LENGTH(RHS(I)); /*FORCE END OF LOOP.*/
END;
ELSE /**NON-TERMINAL**/
DO;
DO K=LENGTH(NTRM)+1 TO LENGTH(NTRM)+LENGTH(TRM);
IF TSTBIT(CHRNUM(SUBSTR(RHS(I),J,1)),
K,ADDR(ARRAY1)) THEN
CALL SETBIT(I,K,ADDR(ARRAY2));
END;
IF ISNLNT(SUBSTR(RHS(I),J,1)) THEN /**NULLABLE**/
;
ELSE
J=LENGTH(RHS(I)); /*FORCE END OF LOOP.*/
END;
END;
END;