I prepared one for my shop. You may use it. There are various Standard & Guidelines related errors/warnings that are specific to my shop. Please remove/modify them. I don't know if attaching docs is allowed here so I'm pasting the entire code below. This may serve as a basic guideline.
/* REXX - CHECKS JCL SYNTAX / S&G ETC *
/**********************************************************************
/* INPUT - INDSN : THE JCL IS COPIED TO IT FROM THE CONDOR LIB *
/* OUTPUT - ERROR LISTING IN SPOOL *
/**********************************************************************
/* DEVOLOPED BY - RITWIK DAS / NIIT / 1ST VERSION - 01 NOV 2008 *
/**********************************************************************
JOBSTMT = ' JOB '
DDSTMT = ' DD '
EXECSTMT = ' EXEC '
COMSTMT = '//*'
INCSTMT = './'
ADRSPPARM = 'ADDRSPC='
CONDPARM = 'COND='
NOTFPARM = 'NOTIFY='
PSWDPARM = 'PASSWORD='
PRFMPARM = 'PERFORM='
PRTYPARM = 'PRTY='
RDPARM = 'RD='
RSTPARM = 'RESTART='
TIMPARM = 'TIME='
USERPARM = 'USER='
K = 1
J = 1
/**********************************************************************
/* READS THE INPUT QSAM FILE *
/**********************************************************************
"EXECIO * DISKR INFILE ( STEM INPFILE. FINIS"
INRECNUM = INPFILE.0
SAY 'INPUT JCL LINE-COUNT = ' INRECNUM
SAY ' '
/**********************************************************************
DO I = 2 TO INRECNUM BY 1
FLAG_COM = 0
FLAG_INC = 0
FLAG_SPACE = 0
FLAG_DCB = 0
FLAG_AMP = 0
FLAG_STEP = 0
FLAG_STEP1 = 0
FLAG_DUMM = 0
FLAG_TAPE = 0
FLAG_SYSO = 0
FLAG_TAPE2 = 0
FLAG_TAPE3 = 0
FLAG_BANK1 = 0
FLAG_BANK2 = 0
FLAG_DISP = 0
FLAG_DSN = 0
FLAG_DD = 0
FLAG_EX = 0
DISPLAY_EX = 0
EXPOSCHK = 0
DISPLAY_JC = 0
FLAG_TYPR = 0
DISPDD1 = 0
DISPDD2 = 0
DISPDD3 = 0
DISPDD4 = 0
FLAG_INC = WORDPOS_CHK(INCSTMT,INPFILE.I)
IF FLAG_INC = 1 THEN
/**********************************************************************
/* IGNORE IF IT IS AN INCLUDE *
/**********************************************************************
ITERATE
FLAG_COM = WORDPOS_CHK(COMSTMT,INPFILE.I)
IF FLAG_COM = 1 THEN
/**********************************************************************
/* IGNORE IF IT IS A COMMENT *
/**********************************************************************
ITERATE
IF I = 2 THEN DO
/**********************************************************************
/* CHECKS THE JOB STATEMENT - ACCOUNTING PARM AND POSITION OF 'JOB' *
/* JOBNAME SHOUD START WITH C, FREQ = D,W,B,M,Q,S,A,X,R,T *
/**********************************************************************
FLAG_JOB = WORDPOS_CHK(JOBSTMT,INPFILE.I)
CALL JOBNAM_CHK
IF FLAG_JOB \= 11 & FLAG_JOB \= 0 & I = 2 THEN DO
IF DISPLAY_JC <> 1 THEN
SAY '>>> ' INPFILE.I
SAY 'W : KEYWORD JOB SHOULD BE AT POSITION 12'
END
FLAG_AC = WORDPOS_CHK('(P,0,U102U3)',INPFILE.I)
IF FLAG_AC = 0 THEN DO
IF DISPLAY_JC <> 1 THEN
SAY '>>> ' INPFILE.I
SAY 'E : ACC PARM SHOULD BE = (P,0,U102U3)'
END
SAY ' '
CALL JOBCARD_CHK
/**********************************************************************
/* JOBCARD_CHK - SUBROUTINE *
/*--------------------------------------------------------------------*
/* CHECK THE ADDITIONAL JOB PARAMETERS TO SEE IF THEY COMPLY WITH THE *
/* STANDARD OF JCL CODING FOLLOWED AT UTICA NATIONAL *
/**********************************************************************
END /* END FOR JOBCARD CHECK */
FLAG_AMP = WORDPOS_CHK('AMP=',INPFILE.I)
IF FLAG_AMP <> 12 & FLAG_AMP <> 0 THEN DO
SAY '>>> ' INPFILE.I
SAY 'W : KEYWORD AMP SHOULD BE AT POSITION 12'
SAY ' '
END
FLAG_DISP = WORDPOS_CHK('DISP=',INPFILE.I)
IF FLAG_DISP <> 12 & FLAG_DISP <> 0 THEN DO
SAY '>>> ' INPFILE.I
SAY 'W : KEYWORD DISP SHOULD BE AT POSITION 12'
SAY ' '
END
FLAG_SPAC = WORDPOS_CHK('SPACE=',INPFILE.I)
IF FLAG_SPAC <> 12 & FLAG_SPAC <> 0 THEN DO
SAY '>>> ' INPFILE.I
SAY 'W : KEYWORD SPACE SHOULD BE AT POSITION 12'
SAY ' '
END
FLAG_SYSO = WORDPOS_CHK('SYSOUT=',INPFILE.I)
IF FLAG_SYSO <> 12 & FLAG_SYSO <> 0 THEN DO
SAY '>>> ' INPFILE.I
SAY 'W : KEYWORD SYSOUT SHOULD BE AT POSITION 12'
SAY ' '
END
FLAG_DUMM = WORDPOS_CHK('DUMMY',INPFILE.I)
IF FLAG_DUMM <> 12 & FLAG_SYSO <> 0 THEN DO
SAY '>>> ' INPFILE.I
SAY 'W : KEYWORD DUMMY SHOULD BE AT POSITION 12'
SAY ' '
END
FLAG_DD = WORDPOS_CHK(DDSTMT,INPFILE.I)
IF FLAG_DD \= 0 THEN DO
IF FLAG_DD \= 11 THEN DO
SAY '>>> ' INPFILE.I
SAY 'W : KEYWORD DD SHOULD BE AT POSITION 12'
DISPDD1 = 1
END
FLAG_DSN = WORDPOS_CHK('DSN=',INPFILE.I)
IF FLAG_DSN <> 0 THEN DO
IF FLAG_DSN <> 18 THEN DO
IF DISPDD1 <> 1 THEN
SAY '>>> ' INPFILE.I
SAY 'W : KEYWORD DSN SHOULD BE AT POSITION 18'
DISPDD2 = 1
END
CALL DSN_EXIST
FLAG_TAPE = WORDPOS_CHK('TAPE.',INPFILE.I)
IF FLAG_TAPE <> 0 & DISPDD4 = 0 THEN DO
/**********************************************************************
/* GO FOR TAPE NAME CHECKING IF THE DS EXISTS (DISPDD4 = 1) *
/**********************************************************************
FLAG_BANK1 = WORDPOS_CHK('TAPE.B1',INPFILE.I)
FLAG_BANK2 = WORDPOS_CHK('TAPE.B2',INPFILE.I)
FLAG_TAPE2 = WORDPOS_CHK('TAPE.D2',INPFILE.I)
FLAG_TAPE3 = WORDPOS_CHK('TAPE.D3',INPFILE.I)
IF FLAG_TAPE2 = 0 & FLAG_TAPE3 = 0 THEN DO
IF FLAG_BANK1 = 0 & FLAG_BANK2 = 0 THEN DO
IF DISPDD1 <> 1 & DISPDD2 <> 1 THEN
SAY '>>> ' INPFILE.I
SAY 'E : ONLY TAPE.D2*,TAPE.D3*,TAPE.B1*,TAPE.B2* AR
ALLOWED'
DISPDD3 = 1
END
END
END /* END FOR TAPE CHECK */
IF DISPDD1 = 1 ³ DISPDD2 = 1³DISPDD3 = 1 ³ DISPDD4 = 1 ³ ,
DISPDD5 = 1 THEN
SAY ' '
END
END
FLAG_EX = WORDPOS_CHK(EXECSTMT,INPFILE.I)
IF FLAG_EX \= 0 THEN DO
FLAG_STEP = WORDPOS_CHK('//S',INPFILE.I)
FLAG_STEP1 = WORDPOS_CHK('//UNITECH',INPFILE.I)
IF FLAG_STEP = 0 & FLAG_STEP1 = 0 THEN DO
SAY '>>> ' INPFILE.I
SAY 'W : STEPNAME SHOULD BE LIKE - S010, S020, S030....'
DISPLAY_EX = 1
END
IF FLAG_EX \= 11 THEN DO
IF DISPLAY_EX <> 1 THEN
SAY '>>> ' INPFILE.I
SAY 'W : KEYWORD EXEC SHOULD BE AT POSITION 12'
EXPOSCHK = 1
END
IF DISPLAY_EX = 1 THEN
SAY ' '
IF EXPOSCHK = 1 THEN
SAY ' '
END
END /* END DO */
CALL TRAILER
EXIT /* END MAIN */
/**********************************************************************
/* FUNCTION WORDPOS_CHK(SUBDATA,DATA) *
/**********************************************************************
WORDPOS_CHK:
ARG SUBSTRING, MAINSTRING
IDFLAG = POS(SUBSTRING,MAINSTRING)
RETURN IDFLAG
/**********************************************************************
/* SUBROUTINE FOR CHECKING THE JOBCARD *
/**********************************************************************
JOBCARD_CHK:
I = I + 1
DO FOREVER
FLAG_EX1 = WORDPOS_CHK(EXECSTMT,INPFILE.I)
IF FLAG_EX1 <> 0 THEN DO
LEAVE
END
FLAG_COM1 = WORDPOS_CHK(COMSTMT,INPFILE.I)
FLAG_INC1 = WORDPOS_CHK(INCSTMT,INPFILE.I)
IF FLAG_COM1 = 1 THEN DO
I = I + 1
ITERATE
END
IF FLAG_INC1 = 1 THEN DO
I = I + 1
ITERATE
END
JOBCARD.J = INPFILE.I
J = J + 1
I = I + 1
FLAG_COM1 = 0
FLAG_INC1 = 0
END
JOBCARD.0 = J - 1
DO K = 1 TO JOBCARD.0 BY 1
FLAG_TYPR = WORDPOS_CHK('TYPRUN=HOLD',JOBCARD.K)
FLAG_ADRS = WORDPOS_CHK(ADRSPPARM,JOBCARD.K)
IF FLAG_ADRS <> 0 THEN DO
SAY '>>> ' JOBCARD.K
SAY 'E : PARAMETER ADDRSPC SHOULD NOT BE USED IN JOBCARD'
SAY ' '
END
FLAG_COND = WORDPOS_CHK(CONDPARM,JOBCARD.K)
IF FLAG_COND <> 0 THEN DO
SAY '>>> ' JOBCARD.K
SAY 'E : PARAMETER COND SHOULD NOT BE USED IN JOBCARD'
SAY ' '
END
FLAG_NOTF = WORDPOS_CHK(NOTFPARM,JOBCARD.K)
IF FLAG_NOTF <> 0 THEN DO
SAY '>>> ' JOBCARD.K
SAY 'E : PARAMETER NOTIFY SHOULD NOT BE USED IN JOBCARD'
SAY ' '
END
FLAG_PSWD = WORDPOS_CHK(PSWDPARM,JOBCARD.K)
IF FLAG_PSWD <> 0 THEN DO
SAY '>>> ' JOBCARD.K
SAY 'E : PARAMETER PASSWORD SHOULD NOT BE USED IN JOBCARD'
SAY ' '
END
FLAG_PRFM = WORDPOS_CHK(PRFMPARM,JOBCARD.K)
IF FLAG_PRFM <> 0 THEN DO
SAY '>>> ' JOBCARD.K
SAY 'E : PARAMETER PERFORM SHOULD NOT BE USED IN JOBCARD'
SAY ' '
END
FLAG_PRTY = WORDPOS_CHK(PRTYPARM,JOBCARD.K)
IF FLAG_PRTY <> 0 THEN DO
SAY '>>> ' JOBCARD.K
SAY 'E : PARAMETER PRTY SHOULD NOT BE USED IN JOBCARD'
SAY ' '
END
FLAG_RD = WORDPOS_CHK(RDPARM,JOBCARD.K)
IF FLAG_RD <> 0 THEN DO
SAY '>>> ' JOBCARD.K
SAY 'E : PARAMETER RD SHOULD NOT BE USED IN JOBCARD'
SAY ' '
END
FLAG_RST = WORDPOS_CHK(RSTPARM,JOBCARD.K)
IF FLAG_RST <> 0 THEN DO
SAY '>>> ' JOBCARD.K
SAY 'E : PARAMETER RESTART SHOULD NOT BE USED IN JOBCARD'
SAY ' '
END
FLAG_TIM = WORDPOS_CHK(TIMPARM,JOBCARD.K)
IF FLAG_TIM <> 0 THEN DO
SAY '>>> ' JOBCARD.K
SAY 'E : PARAMETER TIME SHOULD NOT BE USED IN JOBCARD'
SAY ' '
END
/* MSGCLASS CHECK */
FLAG_MSG = WORDPOS_CHK('MSGCLASS=',JOBCARD.K)
IF FLAG_MSG <> 0 THEN DO
MS_POS = FLAG_MSG + 9
MSGCLASS = SUBSTR(JOBCARD.K,MS_POS,1)
VALID_MCLASS = 0
SELECT
WHEN MSGCLASS = "1" THEN VALID_MCLASS = 1
WHEN MSGCLASS = "?" THEN VALID_MCLASS = 1
WHEN MSGCLASS = "C" THEN VALID_MCLASS = 1
WHEN MSGCLASS = "X" THEN VALID_MCLASS = 1
OTHERWISE NOP
END
IF VALID_MCLASS = 0 THEN DO
SAY '>>> ' JOBCARD.K
SAY 'E : MSGCLASS SHOULD BE ANY OF THEM - 1,?,C,X'
SAY ' '
END
END
/* MSGCLASS CHECK ENDS */
/* JOBCLASS CHECK */
FLAG_JC = WORDPOS_CHK(' CLASS=',JOBCARD.K)
IF FLAG_JC <> 0 THEN DO
JC_POS = FLAG_JC + 7
JOBCLASS = SUBSTR(JOBCARD.K,JC_POS,1)
VALID_CLASS = 0
SELECT
WHEN JOBCLASS = "A" THEN VALID_CLASS = 1
WHEN JOBCLASS = "C" THEN VALID_CLASS = 1
WHEN JOBCLASS = "S" THEN VALID_CLASS = 1
WHEN JOBCLASS = "W" THEN VALID_CLASS = 1
OTHERWISE NOP
END
IF VALID_CLASS = 0 THEN DO
SAY '>>> ' JOBCARD.K
SAY 'E : JOBCLASS SHOULD BE ANY OF THEM - A,C,S,W'
SAY ' '
END
END
/* JOBCLASS CHECK ENDS */
FLAG_USER = WORDPOS_CHK(USERPARM,JOBCARD.K)
IF FLAG_USER <> 0 THEN DO
SAY '>>> ' JOBCARD.K
SAY 'E : PARAMETER USER SHOULD NOT BE USED IN JOBCARD'
SAY ' '
END
END /* END-DO */
IF FLAG_TYPR = 0 THEN DO
SAY 'W : TYPRUN=HOLD PARAMETER IS REQUIRED FOR PROD JOBS'
SAY ' '
END
RETURN /* RETURN FROM THE JOBCARD_CHK SUBROUTINE */
/**********************************************************************
/* SUBROUTINE FOR CHECKING THE EXISTENCE OF THE DS *
/**********************************************************************
DSN_EXIST:
NOC = 0
INV = 0
STARTPOS = 0
ENDPOS = 0
GDG1 = 0
GDG2 = 0
IF FLAG_DSN <> 0 THEN DO
STARTPOS = FLAG_DSN + 4
ENDPOS = POS(',',INPFILE.I,FLAG_DSN)
/* SAY 'STARTPOS = ' STARTPOS */
GDG1 = POS('(',INPFILE.I,FLAG_DSN)
GDG2 = POS(')',INPFILE.I,FLAG_DSN)
IF GDG1 <> 0 & GDG2 <> 0 THEN
ENDPOS = GDG1
IF ENDPOS = 0 THEN
ENDPOS = POS(' ',INPFILE.I,FLAG_DSN)
/* SAY 'ENDPOS = ' ENDPOS */
LEN = ENDPOS - STARTPOS
DSNAME = SUBSTR(INPFILE.I,STARTPOS,LEN)
/* SAY 'DS NAME = ' DSNAME */
TSOLIST = "LISTDS "
TSOLIST = TSOLIST ³³ "'"
TSOLIST = TSOLIST ³³ DSNAME
TSOLIST = TSOLIST ³³ "'"
/* SAY 'TSOLIST = ' TSOLIST */
DUMMY = OUTTRAP("OUTPUT_LINE.","*")
" " TSOLIST " "
NUMLINES = OUTPUT_LINE.0 /*
SAY NUMLINES "LINES WERE CREATED" */
DUMMY = OUTTRAP("OFF")
NOC = WORDPOS_CHK('NOT IN CATALOG',OUTPUT_LINE.2)
INV = WORDPOS_CHK('INVALID',OUTPUT_LINE.1)
FLAG_TMP = 0
FLAG_DOT = 0
FLAG_DOT = WORDPOS_CHK('.',DSNAME)
FLAG_TMP = WORDPOS_CHK('&&',DSNAME)
IF FLAG_TMP = 1 & FLAG_DOT = 0 & LEN < 9 THEN
INV = 0
FLAG_D = 0
FLAG_DN = 0
FLAG_X = 0
R = I + 1
DO FOREVER
FLAG_DN = WORDPOS_CHK('(NEW,',INPFILE.R)
FLAG_X = WORDPOS_CHK(' EXEC ',INPFILE.R)
FLAG_D = WORDPOS_CHK(' DD ',INPFILE.R)
IF FLAG_DN <> 0 ³ FLAG_X <> 0 ³ FLAG_D <> 0 THEN
LEAVE
R = R + 1
END
IF NOC <> 0 & FLAG_DN = 0 THEN DO
IF DISPDD1 = 0 ³ DISPDD2 = 0 THEN
SAY '>>> ' INPFILE.I
SAY 'E : ' OUTPUT_LINE.2
DISPDD4 = 1
END
IF INV <> 0 THEN DO
SAY 'E :' OUTPUT_LINE.1
DISPDD5 = 1
END
END
RETURN
/**********************************************************************
/* ADDS A TRAILER AFTER THE JCL SCAN MESSAGES *
/**********************************************************************
TRAILER:
STARLINE = COPIES('*',80)
BLANKLINE = ''
SAY STARLINE
SAY BLANKLINE
SAY ' UTICA NATIONAL INSURANCE GROUP ' ,
DATE()
SAY ' UNICLAIMS IT '
SAY BLANKLINE
SAY ' REXX TOOL TO CHECK JCL SYNTAX & CODING STANDARD'
SAY BLANKLINE
SAY ' DEVELOPED BY : '
SAY '-------------------------------------'
SAY '| RITWIK DAS |'
SAY '| NIIT TECHNOLOGIES INC. |'
SAY '-------------------------------------'
SAY BLANKLINE
SAY STARLINE
RETURN
/**********************************************************************
/* CHECKS IF THE JOBNAME CONFORMS UNICLAIMS STANDARD *
/**********************************************************************
JOBNAM_CHK:
JN_START = 3
JOBPREF = SUBSTR(INPFILE.I,JN_START,2)
JN_VALID = 0
SELECT
WHEN JOBPREF = "CD" THEN JN_VALID = 1
WHEN JOBPREF = "CW" THEN JN_VALID = 1
WHEN JOBPREF = "CB" THEN JN_VALID = 1
WHEN JOBPREF = "CM" THEN JN_VALID = 1
WHEN JOBPREF = "CQ" THEN JN_VALID = 1
WHEN JOBPREF = "CS" THEN JN_VALID = 1
WHEN JOBPREF = "CA" THEN JN_VALID = 1
WHEN JOBPREF = "CX" THEN JN_VALID = 1
WHEN JOBPREF = "CR" THEN JN_VALID = 1
WHEN JOBPREF = "CT" THEN JN_VALID = 1
OTHERWISE NOP
END
IF JN_VALID = 0 THEN DO
SAY '>>> ' INPFILE.I
SAY 'E : JOBNAME NOT AS PER STANDARD'
END
DISPLAY_JC = 1
RETURN