*DECK SSRRCS
PROC SSRRCS(CST, CSTRING, (LEN), OUTPARM, (MAX), OUTCNT, EC, ET);
# TITLE SSRRCS - RECOGNIZE COMMAND STRING. #
BEGIN # SSRRCS #
#
** SSRRCS - RECOGNIZE COMMAND STRING.
*
* A. LIM. 82/02/17.
*
* THIS PROCEDURE-S MAIN FUNCTION IS TO RECOGNIZE AN INPUT COMMAND
* STRING *CSTRING* (OPERATOR TYPEINS), GIVEN THE LENGTH *LEN* OF
* THE STRING, AND THE COMMAND-SYNTAX/SEMANTIC-TABLE *CST* THAT
* THIS STRING IS GOING TO CHECK AGAINST.
* IF THE STRING PASS BOTH THE SYNTAX AND SEMANTIC CHECKING,
* ON RETURNING TO THE CALLER, *OUTPARM* CONTAINS THE OUTPUT-
* PARAMETER-LIST RESULTING FROM THE CHECKINGS, AND *OUTCNT*
* REFLECTS THE COUNT OF NUMBER OF ENTRIES IN *OUTPARM*.
* ELSE, IF THE STRING FAIL IN EITHER CHECKING, AN ERROR
* CODE IN *EC* OR WITH ERROR TEXT IN *ET* WILL BE RETURNED.
* THIS PROCEDURE IS CALLED INTO EXECUTION BY:
* *CSSROC* *NVFOROC*
*
* PROC SSRRCS(CST, CSTRING, (LEN), OUTPARM, (MAX), OUTCNT, EC, ET)
*
* ENTRY CST = COMMAND SYNTAX/SEMANTIC TABLE THE CURRENT
* INPUT STRING IS GOING TO CHECK AGAINST.
* EACH COMMAND SYNTAX LINE IS TERMINATED BY AN
* END-OF-LINE (EOL$) TERMINATOR, AND THE TABLE
* IS TERMINATED BY A LAST ENTRY CONTAINING ONLY
* THE EOL$ AS THE FIRST CHARACTER.
* CSTRING = COMMAND STRING TO BE RECOGNIZED.
* LEN = LENGTH IN CHARACTERS OF COMMAND STRING.
* OUTPARM = ADDRESS OF OUTPUT-PARAMETER-LIST.
* MAX = MAX NO. OF ENTRIES ALLOWABLE IN OUTPARM.
*
* EXIT CST = UNCHANGED.
* CSTRING = UNCHANGED.
* LEN = UNCHANGED.
* OUTPARM = OUTPUT-PARAMETER-LIST.
* (MEANINGLESS IF EC NQ 0)
* MAX = UNCHANGED.
* OUTCNT = COUNT OF ACTUAL NO. OF ENTRIES IN OUTPARM.
* (MEANINGLESS IF EC NQ 0)
* EC = ERROR CODE:
* 0 = NO ERROR.
* 1 = PARAMETER TOO LONG.
* 2 = EXPECTING PERIOD.
* 3 = EXPECTING PERIOD OR COMMA.
* 4 = UNRECOGNIZED COMMAND.
* 5 = INVALID COMBINATION OF PARAMETERS.
* 6 = COMMAND MISSING PARAMETER.
* 7 = OUTPUT PARAMETER LIST TOO SHORT.
* 8 = INPUT MESSAGE TOO LONG.
* ET = ERROR TEXT(UP TO 10 CHARACTERS), CONTAINS THAT
* PART OF THE COMMAND STRING THAT IS IN ERROR.
*
* NOTE THIS PROCEDURE MIGHT END UP IN AN INFINITE LOOP, OR
* RESULT MIGHT BE UNPREDICTABLE IF CST WERE NOT BUILT
* CORRECTLY.
*
* METHOD:
*
* THE COMMAND SYNTAX TABLE *CST* IS INPUT TO THE COMMAND
* RECOGNIZER TO DEFINE THE SYNTAX AND THE SEMANTICS OF
* THE ALLOWABLE COMMANDS.
*
* THE TABLE IS ORDERED(SCANNED TOP TO BOTTOM) AND CONTAINS
* FLAG CHARACTERS TO DEFINE THE ORDER AND MEANING OF THE
* CHARACTERS TO BE ENTERED TO SELECT THE ACTION TO BE PERFORMED.
* THE TABLE IS DESIGNED TO BE BOTH HUMAN AND COMPUTER READABLE,
* AND CONCISE. INFORMATION ABOUT AN INDIVIDUAL COMMAND IS TO BE
* COLLECTED TOGETHER.
*
* THE SYNTAX TABLE CONTAINS THE SEMANTIC TABLE WITHIN IT. DURING
* THE SYNTAX SCAN, THE SEMANTICS (AND THEIR FLAG CHARACTERS) ARE
* IGNORED. DURING THE SEMANTIC SCAN, MOST OF THE SYNTAX TABLE IS
* IGNORED AND THE SEMANTIC FLAG CHARACTERS ARE USED FOR FURTHER
* CHECKING OF PROPERNESS OF THE INPUT LINE. SOME CHARACTERS ARE
* USED DURING BOTH SCANS, THUS THE REASON TO MERGE THE TWO TABLES
* AND KEEP THE INFORMATION ABOUT A COMMAND TOGETHER.
*
* DURING THE COMMAND RECOGNIZING PROCESS, BOTH THE INPUT LINE AND
* THE CURRENT LINE OF SYNTAX ARE BROKEN INTO TOKENS FOR COMPARISION.
* THIS BREAKING UP INTO TOKENS TAKES PLACE WHENEVER A TOKEN IS
* REQUIRED.
*
* STARTING WITH THE FIRST TOKEN OF THE FIRST LINE OF SYNTAX, THE
* SYNTAX TOKEN IS EXAMINED FOR ACTION TO PERFORM SUCH AS COMPARING
* THE TOKEN WITH THE NEXT INPUT TOKEN, STORING A PARAMETER CODE
* IN THE OUTPUT PARAMETER LIST, OR OTHER ACTION.
*
* AS TOKENS ARE READ FROM SYNTAX, POSSIBILITIES ARE CHECKED FOR
* MATCHING WITH WHAT WAS TYPED IN. AS LONG AS WHAT WAS TYPED IN
* IS ALLOWABLE WITHIN THE CURRENT SYNTAX LINE, THE PROCESS
* CONTINUES TO THE END OF THE INPUT LINE. IF AT ANY POINT AN
* INPUT TOKEN IS NOT PERMITTED ACCORDING TO THE SYNTAX LINE, ALL
* INFORMATION THAT MAY HAVE BEEN DETERMINED UP TO THIS POINT IS
* DISCARDED AND A FRESH START IS MADE USING THE NEXT SYNTAX LINE.
* WHEN THE LAST SYNTAX LINE DID NOT MATCH, THE TYPE-IN IS DECLARED
* INVALID AND REJECTED AS UNRECOGNIZED. WHEN THE END OF THE INPUT
* LINE IS REACHED AND THE SYNTAX HAS PASSED ALL TESTS THEN A
* SEMANTIC PASS IS DONE USING THE OUTPUT PARAMETER LIST AND THE
* SYNTAX LINE THAT WAS JUST USED TO PASS THE INPUT LINE. AT THIS
* TIME ANY DUPLICATE KEYWORDS, MISSING PARAMETERS AND DEFAULTS TO
* BE INSERTED ARE RECOGNIZED AND ADDED TO THE OUTPUT OR THE ENTIRE
* COMMAND REJECTED IF WHAT WAS ENTERED WAS INCORRECT.
*
* SYNTAX FLAG CHARACTERS:
*
* <A_B_C_....Z> = ANY OF THE CHARACTER STRINGS A, B, C....Z
* CAN MATCH AND ARE SYNONYMS. "_" CANNOT BE
* IN STRING
*
* [ = RESYNC POINT. IF MISMATCH OCCURS, SKIP AND TRY
* THE MATCH AT NEXT "[".
*
* @ = OUTPUT PARAMETER CODE
*
* ^ = END MATHCER. PERIOD OR COMMA OR END OF INPUT LINE
* CAN MATCH AND TERMINATE SCAN. COMMA CAN MATCHING
* SYNTAX SCAN TO FIRST "[" IF PRESENT.
*
* ? = PARAMETER, 1 TO 7 ALPHA-NUMERIC CHARACTERS.
* COUPLED WITH LAST OUTPUT PARAMETER CODE.
*
* & = CHARACTER STRING, 50 CHARACTERS MAXIMUM TO END
* OF THE LINE. ALSO TERMINATES SYNTAX SCAN.
*
* $ = END OF LINE TERMINATOR.
* IF WERE THE ONLY CHARACTER IN A SYNTAX LINE,
* THEN IT IS AN END OF TABLE INDICATOR.
*
* THE FIRST RESYNC POINT "[" HAS SPECIAL SIGNIFICANCE IN THAT IT IS
* THE POINT THE SYNTAX SCAN IS SET TO UPON MATCHING A COMMA, "^"
* IN THE SYNTAX WITH A "," IN THE INPUT LINE. IF A MISMATCH OCCURS
* WITH THE INPUT TOKEN THEN THE SYNTAX SCAN IS ADVANCED TO THE NEXT
* "[" AND ANOTHER COMPARISON IS MADE. WHEN NO MORE "[" POINTS
* REMAIN IN THE SYNTAX THEN A MISMATCH IS DECLARED, THE OUTPUT
* PARAMETER LIST IS DISCARDED, AND INPUT SCAN RESET TO THE BEGINNING
* OF THE INPUT LINE AND THE NEXT SYNTAX LINE IS TRIED.
*
* THE OUTPUT PARAMETER CODE "@" WHEN READ FROM SYNTAX RESULTS IN A
* NEW OUTPUT PARAMETER WORD TO BE ADDED AND THE NEXT THREE CHARACTERS
* FROM THE SYNTAX TABLE TO BE INSERTED INTO THE WORD. SHOULD A "?"
* BE READ FROM THE SYNTAX LINE, THEN THE NEXT TOKEN FROM INPUT IS
* STORED INTO THE OUTPUT PARAMETER WORD WITH THE LAST PARAMETER CODE.
*
*
* SEMANTIC FLAG CHARACTERS:
*
* \ = SET, ONLY ONE OF SET ALLOWED.
*
* ! = DEFAULT, ONLY ALLOWABLE WITHIN SET. INCLUDE
* IF NO OTHER MEMBER OF SET INCLUDED.
*
*
* A SET IN TERMS OF SEMANTICS IS THE LIST OF PARAMETER CODES (3
* CHARACTERS FOLLOWING "@") CONTAINED WITHIN PAIRS OF "\"
* CHARACTERS.
*
* ONLY ONE MEMBER OF A SET MAY BE PRESENT IN THE OUTPUT PARAMETER
* LIST, AND THIS ALSO DISALLOWS REPEATED OCCURRENCES OF THE SAME
* KEYWORD.
*
* IF THE CHARACTER "!" APPEARS WITHIN A SET, THEN ONE AND ONLY ONE
* PARAMETER CODE FROM THE SET MUST BE IN THE OUTPUT PARAMETER LIST.
* IF THE "!" CHARACTER IS FOLLOWED IMMEDIATELY BY THE "@" CHARACTER,
* THEN THE 3 CHARACTERS FOLLOWING THE "@" ARE THE DEFAULT AND WILL
* BE INSERTED INTO THE PARAMETER LIST IF NO OTHER MEMBER OF THE SET
* WAS IN THE INPUT. IF THE "!" CHARACTER IN THE SYNTAX WAS FOLLOWED
* BY A CHARACTER OTHER THAN "@" THEN AN ERROR IS DECLARED IF NO
* MEMBER OF THE SET WAS IN THE INPUT.
*
*
* SEMANTIC EXAMPLES:
*
* \![ \ = AT LEAST ONE PARAMETER MUST BE ENTERED AND
* THERE IS NO DEFAULT.
*
* \ \ = THE ENTIRE SET OF PARAMETERS IS OPTIONAL.
*
* \ !@DEF\ = DEFAULT, I.E. IF NO MEMBER OF SET IS ENTERED,
* THE PARAMETER CODE FOLLOWING THE "!@" CHARACTERS
* IS THE DEFAULT FOR THE SET.
*
#
#
**** PROC SSRRCS XREF LIST.
#
XREF
BEGIN
PROC SSBEBF; # EXTRACT BIT FIELD FROM A TABLE #
PROC SSBSBF; # STORE BIT FIELD INTO A TABLE #
PROC SSRGNT; # GET NEXT TOKEN FROM A COMMAND STRING #
END
#
****
#
# DEFS FOR ERROR CODE #
DEF NOERR$ # 0 #; # NO ERROR #
DEF PRMLNG$ # 1 #; # PARAMETER TOO LONG #
DEF EXPRD$ # 2 #; # EXPECTING PERIOD #
DEF EXPDCMA$ # 3 #; # EXPECTING PERIOD OR COMMA #
DEF UNRGCMD$ # 4 #; # UNRECOGNIZED COMMAND #
DEF INVCMPRM$ # 5 #; # INVALID COMBINATION OF PARAMETERS #
DEF CMDMSGPRM$ # 6 #; # COMMAND MISSING PARAMETER #
DEF OUTPMSH$ # 7 #; # OUTPUT PARAMETER LIST TOO SHORT #
DEF MSGLNG$ # 8 #; # INPUT MESSAGE TOO LONG #
DEF VALOUT$ # 9 #; # VALUE OUT-OF-RANGE #
# DEFS FOR SYNTAX, SEMANTIC AND INPUT FLAG CHARACTERS, AND OUTPUT #
# PARAMETER LIST CODE. #
DEF MESSAGE$ # "&" #; # SYNTAX- CHAR STRING, 50 OR LESS CHARS #
DEF PRMCODE$ # "@" #; # SYNTAX- OUTPUT PARAMETER CODE #
DEF CHARLEN$ # 6 #; # CHAR LENGTH IN BITS FOR OCT DISP-CODE #
DEF CHARWD$ # 10 #; # NO. OF 6-BIT CHAR PER CM WORD #
DEF COMMA$ # "," #; # SYNTAX AND SEMANTIC- SEPARATOR #
DEF A$ # "A" #; # INPUT- LOWER BOUND FOR ALPH-NUM STRING#
DEF EOL$ # "$" #; # SYNTAX- END OF LINE TERMINATOR #
DEF DFONEST$ # "!" #; # SEMANTIC- DEFAULT, ONE OF SET #
DEF ONESET$ # "\" #; # SEMANTIC- SET, ONE OF SET ALLOWED #
DEF ENDSYNST$ # ">" #; # SYNTAX- END OF SYNONYM SET #
DEF MAXMSGL$ # 50 #; # INPUT- MAX MESSAGE LENGTH IN CHARS #
DEF MAXSVC # 255 #; # INPUT- MAX NUMBER OF SVC CIRCUITS #
DEF ZERO$ # "0" #; # INPUT- LOWER BOUND FOR NUMERIC STRING #
DEF NINE$ # "9" #; # INPUT- UPPER BOUND OF ALPH-NUM STRING #
DEF PERIOD$ # "." #; # SEMANTIC- END OF INPUT TERMINATOR #
DEF ENDMH$ # "^" #; # SYNTAX- END MATCHER #
DEF PRMTR$ # "?" #; # SYNTAX- PARAMETER 1-7 ALPHA-NUM CHARS #
DEF RESYNC$ # "[" #; # SYNTAX- RESYNC CHAR #
DEF BEGSYNST$ # "<" #; # SYNTAX- BEGIN OF SYNONYM SET #
DEF SYNSPTR$ # "_" #; # SYNTAX- SEPARATOR FOR SYNONYM SET #
DEF VEB$ # "VEB" #; # OUTPUT-PARAMETER-LIST VERB CODE #
DEF RPARENTH # "(" # ;
DEF LPARENTH # ")" # ;
DEF MS0$ # "MS0" #; # PARAMETER CODE FOR SEND MESSAGE CMD #
# DEFS FOR ARRAY SIZES #
DEF CSTSIZ$ # 31 #; # CST SIZE = 30 ENTRY + 1 TERMINATE ENTR#
DEF CSSIZ$ # 14 #; # CMD STRING SZ= 139 + 1 TERMINATE CHAR #
# FORMAL PARAMETERS #
#
** CST - COMMAND SYNTAX/SEMANTIC TABLE
*
* THIS TABLE DEFINES THE SYNTAX AND SEMANTICS OF THE ALLOWABLE
* COMMANDS. IT IS THIS TABLE THAT THE INPUT STRING IS GOING TO
* CHECK AGAINST FOR VALID COMMAND.
#
ARRAY CST[00:CSTSIZ$] S(CSSIZ$);
BEGIN
ITEM CST$LINE C(00,00,140);
END
#
** CSTRING - COMMAND STRING.
*
* A COMMAND STRING OF *LEN* NUMBER OF CHARACTERS.
#
ARRAY CSTRING[00:00] S(CSSIZ$);
BEGIN
ITEM CS$STRING C(00,00,140);
END
ITEM LEN I; # LENGTH IN CHARS OF COMMAND STRING #
#
** OUTPARM - OUTPUT PARAMETER LIST.
*
* THIS ARRAY CONTAINS THE OUTPUT PARAMETER LIST RESULTING FROM
* A SUCCESSFUL RECOGNITION OF THE INPUT STRING.
* NOTE: THIS ARRAY SIZE HAS TO BE THE SAME AS *MAX*.
#
ARRAY OUTPARM[00:30] S(1);
BEGIN
ITEM OPM$WORD C(00,00,10); # WHOLE WORD REFERENCE #
ITEM OPM$VALUE C(00,00,07); # PARAMETER VALUE #
ITEM OPM$MSGL U(00,00,42); # MESSAGE LENGTH #
ITEM OPM$CODE C(00,42,03); # PARAMETER CODE #
END
ITEM MAX I; # MAX NO. OF ENTRIES IN OUTPARM #
ITEM OUTCNT I; # ACTUAL NO. OF ENTRIES IN OUTPARM #
ITEM EC I; # ERROR CODE #
ITEM ET C(10); # ERROR TEXT #
#
** PARMLST - PARAMETER LIST.
*
* THIS IS AN INTERMEDIATE PARAMETER LIST BUILT BY THE SYNTAX
* CHECKER WITH PARAMETERS IN THE ORDER AS IT IS ENTERED IN
* THE COMMAND. THEN IT IS USED BY THE SEMANTIC CHECKER TO
* BUILD THE ACTUAL OUTPUT PARAMETER LIST(OUTPARM) WITH
* PARAMETERS IN THE ORDER AS IT APPEARS IN THE COMMAND
* SYNTAX TABLE.
* NOTE: THIS ARRAY SIZE HAS TO BE THE SAME SIZE AS *OUTPARM*.
#
ARRAY PARMLST[00:30] S(1);
BEGIN
ITEM PML$WORD C(00,00,10); # WHOLE WORD REFERENCE #
ITEM PML$VALUE C(00,00,07); # PARAMETER VALUE #
ITEM PML$NCVAL U(00,00,08); # PARAMETER HEX VALUE #
ITEM PML$MSGL U(00,00,42); # MESSAGE LENGTH #
ITEM PML$CODE C(00,42,03); # PARAMETER CODE #
END
# ACTUAL PARAMETERS TO *SSBEBF*, *SSBSBF*, AND *SSRGNT* #
ITEM BLEN I; # NO. OF BITS TO EXTRACT/STORE (X6) #
ITEM GNTEC I; # ERROR CODE FROM *SSRGNT* #
ITEM IBIT I; # INPUT- START BIT POSITION W/I WORD #
ITEM IORD I; # INPUT- START WORD ORDINAL W/I TABLE #
ITEM IPOS I; # INPUT- NEXT CHAR POSITION #
ITEM IIPOS I; # INPUT- CURRENT CHAR POSITION #
ITEM ITOKEN C(10); # INPUT- CURRENT TOKEN #
ITEM PSPOS I; # SYNTAX- PREVIOUS CHAR POSITION #
ITEM PSTOKEN C(10); # SYNTAX- PREVIOUS TOKEN #
ITEM RESULT C(10); # RESULT OF EXTRACTION OF BIT FIELD #
ITEM SBIT I; # SYNTAX_ START BIT POSITION W/I WORD #
ITEM SORD I; # SYNTAX_ START WORD ORDINAL W/I TABLE #
ITEM SPOS I; # SYNTAX- NEXT CHAR POSITION #
ITEM STOKEN C(10); # SYNTAX- CURRENT TOKEN #
# GENERAL ITEMS #
ITEM CURLINE B; # LOOP EXIT VAR ON DONE WITH CURRENT LINE #
ITEM DONE B; # LOOP EXIT VAR ON PUT MSG INTO OUTPARM #
ITEM EOSET B; # LOOP EXIT VAR ON END OF SET #
ITEM ERROR B; # LOOP EXIT VAR ON ERROR #
ITEM FOUND B; # LOOP EXIT VAR ON FOUND CODE IN OUTPARM #
ITEM FRSTEOS B; # FIRST END OF SET FOUND FLAG #
ITEM I I; # INDUCTION VAR ON CST #
ITEM J I; # INDUCTION VAR #
ITEM K I; # INDUCTION VAR #
ITEM L I; # INDUCTION VAR #
ITEM M I; # INDUCTION VAR #
ITEM N I; # INDUCTION VAR #
ITEM MEMCNT I; # MEMBER COUNT #
ITEM MEMREQD B; # MEMBER REQUIRED FLAG #
ITEM MSGLEN I; # MESSAGE LENGTH IN CHARS #
ITEM OP I; # INDEX TO OUTPARM #
ITEM RESYNCFOUD B; # FIRST RESYNC FOUND FLAG #
ITEM RESYNCPONT I; # FIRST RESYNC POINT #
ITEM SETDFAULT C(7); # DEFAULT FOR THE SET #
ITEM SPASS B; # LOOP EXIT VAR ON SYNTAX/SEMANTIC PASS #
ITEM SVCBIN I; # BINARY VALUE OF SVC COUNT #
ITEM SVCCNT I; # SVC COUNT #
ITEM SVCCONT B; # LOOP EXIT VAR ON SVC CONVERSION PASS #
ITEM SYNYMACTVE B; # SYNONYM ACTIVE FLAG #
CONTROL EJECT;
#
* IF INPUT COMMAND STRING IS NULL, EXIT WITH
* EC = UNRECOGNIZED COMMAND.
#
IF LEN EQ 0
THEN
BEGIN
EC = UNRGCMD$;
GOTO EXIT;
END
# INITIALIZES VARIABLES AND ARRAYS #
EC = NOERR$; # PRESET ERROR CODE TO NO ERROR #
ET = " "; # PRESET ERROR TEXT TO BLANKS #
SPASS = FALSE; # PRESET SYNTAX CHECKING PASS TO FALSE #
ERROR = FALSE; # PRESET INPUT ERROR TO FALSE #
#
* START SYNTAX CHECKING OF THE INPUT COMMAND STRING UNTIL IT PASS
* ON A SYNTAX LINE, OR *CST* HAS BEEN EXHAUSTED, OR ERROR IS
* DETECTED IN INPUT.
#
FOR I = 0 STEP 1 WHILE ((NOT SPASS)
AND (NOT ERROR))
DO
BEGIN # PROCESSING SYNTAX TABLE #
IPOS = 0; # RESET TO BEGINNING OF INPUT #
SPOS = 0; # RESET TO BEGINNING OF A NEW SYTAX LINE #
CURLINE = TRUE; # RESET CURRENT SYNTAX LINE TO TRUE #
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC); # GET FIRST STKN #
IF STOKEN EQ EOL$
THEN
BEGIN
EC = UNRGCMD$; # END OF CST, UNRECOGNIZED COMMAND #
ERROR = TRUE;
END
ELSE
BEGIN # PROCESSING A NEW SYNTAX LINE #
RESYNCFOUD = FALSE; # RESET RESYNC-FOUND TO FALSE #
SYNYMACTVE = FALSE; # RESET SYNONYM_ACTIVE TO FALSE #
FOR J = 0 STEP 1 UNTIL 30
DO
BEGIN # CLEAR INTERMEDIATE PARAMETER LIST#
PML$WORD[J] = " ";
END
OUTCNT = 0; # RESET OUTCNT #
OP = 0; # RESET PARMLST INDEX TO FIRST ENTRY#
PML$VALUE[OP] = STOKEN; # ADD FIRST S-TOKEN TO PARMLST #
PML$CODE[OP] = VEB$; # ADD VERB CODE #
OUTCNT = OUTCNT + 1; # INCREMENT OUTCNT #
FOR J = 0 WHILE (STOKEN NQ COMMA$)
DO # LOOP TIL STOKEN = "," #
BEGIN
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC);
IF STOKEN EQ PRMCODE$
THEN
BEGIN # @, ADD NEXT TOKEN TO PARMLST #
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC);
OP = OP + 1; # ALLOC A NEW ENTRY IN PARMLST #
OUTCNT = OUTCNT + 1; # INCREMENT OUTCNT #
PML$CODE[OP] = STOKEN; # ADD TOKEN TO PARMLST #
END
END
# SKIP THE "," #
FOR J = 0 WHILE ((NOT SPASS)
AND (STOKEN NQ EOL$)
AND (CURLINE)
AND (NOT ERROR))
DO # LOOP TIL SYNTAX PASS, OR END OF SYN-LINE#
# OR NOT CURRENT SYN-LINE, OR INPUT ERROR #
BEGIN # CASE ON SYNTAX FLAG CHARACTERS #
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC);
IF STOKEN EQ PRMCODE$
THEN
BEGIN
GOTO LLPRMCODE;
END
ELSE IF STOKEN EQ RPARENTH
OR STOKEN EQ LPARENTH
THEN
BEGIN
GOTO LLPARENTH ;
END
ELSE IF STOKEN EQ PRMTR$
THEN
BEGIN
GOTO LLPRMTR;
END
ELSE IF STOKEN EQ ENDMH$
THEN
BEGIN
GOTO LLENDMH;
END
ELSE IF STOKEN EQ RESYNC$
THEN
BEGIN
GOTO LLRESYNC;
END
ELSE IF STOKEN EQ BEGSYNST$
THEN
BEGIN
GOTO LLBEGSYNST;
END
ELSE IF STOKEN EQ ENDSYNST$
THEN
BEGIN
GOTO LLENDSYNST;
END
ELSE IF STOKEN EQ MESSAGE$
THEN
BEGIN
GOTO LLMESSAGE;
END
ELSE IF ((STOKEN EQ SYNSPTR$)
OR (STOKEN EQ DFONEST$)
OR (STOKEN EQ ONESET$))
THEN
BEGIN
GOTO ENDCASE1;
END
ELSE
BEGIN
GOTO LLOTHER;
END
LLPRMCODE: # @, STORE PARAMETER CODE IN OUTPUT #
IF OP+1 GQ MAX
THEN
BEGIN
EC = OUTPMSH$; #OUTPUT PARAMETER LIST TOO SHORT#
ERROR = TRUE;
END
ELSE
BEGIN
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC);
IF STOKEN NQ EOL$
THEN
BEGIN
OP = OP + 1; # ALLOC A NEW ENTRY IN PARMLST #
OUTCNT = OUTCNT + 1; # INCREMENT OUTCNT #
PML$CODE[OP] = STOKEN; # ADD STOKEN TO PARMLST #
END
END
GOTO ENDCASE1;
LLPARENTH:
IF IPOS EQ LEN
THEN
SPASS = TRUE ;
ELSE
BEGIN
EC = UNRGCMD$ ;
ET = ITOKEN ;
ERROR = TRUE ;
END
GOTO ENDCASE1 ;
LLPRMTR: # ?, ALPHA-NUM STRING EXPECT IN INPUT #
IF IPOS GQ LEN
THEN
BEGIN
EC = CMDMSGPRM$; # COMMAND MISSING PARAMETER #
ERROR = TRUE;
END
ELSE
BEGIN
SSRGNT(CSTRING, IPOS, LEN, ITOKEN, GNTEC);
IF GNTEC NQ 0
THEN
BEGIN
EC = PRMLNG$; # PARAMETER TOO LONG #
ET = ITOKEN;
ERROR = TRUE;
END
ELSE
BEGIN
IF PML$CODE[OP] EQ "NC0" # NCIR PARAMETER #
THEN
BEGIN
SVCCNT = 0; # INITIALIZE SVC ACCUM. #
SVCCONT = TRUE; # INITIALIZE LOOP CONTINUE VAR #
FOR N = 0 STEP 1 WHILE SVCCONT
DO
BEGIN # CONVERT TOKEN TO INTEGER #
SVCCONT = N LQ 3; # SCAN FOUR CHARACTERS #
IF (C<N,1>ITOKEN GQ ZERO$)
AND (C<N,1>ITOKEN LQ NINE$)
THEN
BEGIN
SVCBIN = C<N,1>ITOKEN - O"33"; # CONVERT TO OCT.#
SVCCNT = (SVCCNT * 10) + SVCBIN; # UPDATE ACCUM.#
END
ELSE
IF C<N,1>ITOKEN NQ " " # CHAR NOT A SPACE #
THEN
BEGIN
CURLINE = FALSE; # NEXT SYN-LINE #
GOTO ENDCASE1;
END
ELSE
SVCCONT = FALSE; # EXIT LOOP AND RANGE CHECK #
END # FOR LOOP #
IF SVCCNT GR MAXSVC # MAX NO. OF SVC CIRCUITS #
THEN
BEGIN
EC = VALOUT$; # VALUE OUT-OF-RANGE #
ET = ITOKEN;
ERROR = TRUE;
END
ELSE
BEGIN
PML$NCVAL[OP] = SVCCNT; # STORE NO. SVCS #
GOTO ENDCASE1;
END
END # IF NC0 #
ELSE
IF (C<0,1>ITOKEN GQ A$) AND (C<0,1>ITOKEN LQ NINE$)
THEN
BEGIN # ALPHA-NUM STRING #
PML$VALUE[OP] = ITOKEN; # ADD ITOKEN TO PARMLST #
END
ELSE
BEGIN
CURLINE = FALSE; # NEXT SYN-LINE #
END
END
END
GOTO ENDCASE1;
LLENDMH: # "^ ", END OR COMMA MATCHER #
IF IPOS EQ LEN
THEN
BEGIN # NO "." IN INPUT, ONE IS ASSUMMED #
SPASS = TRUE; # SYNTAX PASS SUCCESSFUL #
END
ELSE
BEGIN
SSRGNT(CSTRING, IPOS, LEN, ITOKEN, GNTEC);
IF GNTEC NQ 0
THEN
BEGIN
EC = PRMLNG$;
ET = ITOKEN;
ERROR = TRUE;
END
ELSE
BEGIN
IF ITOKEN EQ PERIOD$
THEN
BEGIN
IF IPOS EQ LEN
THEN # END OF INPUT STRING #
BEGIN
SPASS = TRUE; # I-TOKEN = ".", SYNTAX PASS #
END
ELSE
BEGIN # PERIOD IN MIDST OF INPUT #
EC = UNRGCMD$;
ET = ITOKEN;
ERROR = TRUE;
END
END
ELSE IF ITOKEN EQ COMMA$
THEN
BEGIN # I-TOKEN = "," #
IF RESYNCFOUD
THEN
BEGIN # RESYNC FOUND #
PSPOS = SPOS - 2; # GET PREVIOUS TOKEN #
SSRGNT(CST[I], PSPOS, 0, PSTOKEN, GNTEC);
IF PSTOKEN NQ RESYNC$
THEN
BEGIN # "^" NOT PRECEDED BY "[" #
SPOS = RESYNCPONT; # RESET TO RESYNC PT #
END
END
ELSE
BEGIN
IF IPOS EQ LEN
THEN # END OF INPUT "," INSTEAD OF"."#
BEGIN
EC = EXPRD$; # EXPECTING PERIOD #
ET = ITOKEN;
ERROR = TRUE;
END
END
END
ELSE # OTHER #
BEGIN
EC = EXPDCMA$; # EXPECTING PERIOD OR COMMA #
ET = ITOKEN;
ERROR = TRUE;
END
END
END
GOTO ENDCASE1;
LLRESYNC: # [, FIRST RESYNC POINT #
RESYNCFOUD = TRUE; # SET RESYNC-FOUND TRUE #
RESYNCPONT = SPOS; # SET RESYNC-POINT TO CUR S-TKN #
GOTO ENDCASE1;
LLBEGSYNST: # <, BEING SYNONYM SET #
SYNYMACTVE = TRUE; # SET SYNONYM-ACTIVE TRUE #
GOTO ENDCASE1;
LLENDSYNST: # >, END OF SYNONYM SET #
SYNYMACTVE = FALSE; # SET SYNONYM_ACTIVE TO FALSE #
IF RESYNCFOUD
THEN
BEGIN # RESYNC FOUND #
FOR K = 0 WHILE ((STOKEN NQ RESYNC$)
AND (CURLINE))
DO # SKIP FORWARD TO NEXT "[" #
BEGIN
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC);
IF STOKEN EQ EOL$
THEN
BEGIN # END OF SYNTAX LINE #
CURLINE = FALSE; # SKIP TO NEXT SYNTAX LINE #
END
END
END
ELSE
BEGIN # RESYNC NOT FOUND #
CURLINE = FALSE; # SKIP TO NEXT SYNTAX LINE #
END
GOTO ENDCASE1;
LLMESSAGE: # &, TRNSFR ALL INPUT CHARS TO PARMLST #
MSGLEN = LEN - IPOS; # MESSAGE LENGTH #
IF MSGLEN GR MAXMSGL$
THEN
BEGIN # MESSAGE EXCEEDS LIMIT #
EC = MSGLNG$; # MESSAGE TOO LONG #
ERROR = TRUE;
END
ELSE
BEGIN # MESSAGE W/I LEN LIMIT #
PML$MSGL[OP] = MSGLEN; # ADD MSG LENGTH TO PARMLST #
# CONVERT IPOS INTO TABLE ORDINAL(IORD) AND STARTING #
# BIT(IBIT) WITHIN WORD. #
IORD = 0;
IBIT = IPOS * CHARLEN$;
FOR K = 0 WHILE (IPOS - CHARWD$) GR 0
DO
BEGIN
IPOS = IPOS - CHARWD$;
IORD = IORD + 1;
IBIT = IPOS * CHARLEN$;
END
DONE = FALSE; # RESET LOOP EXIT VAR TO FALSE #
IF IBIT EQ 60
THEN # ADJUST BIT POSITION TO BEG OF NEXT WRD #
BEGIN
IORD = IORD + 1;
IBIT = 0;
END
FOR K = 0 WHILE (NOT DONE)
DO # LOOP TIL ALL CHARS STORED IN PARMLST #
BEGIN
IF MSGLEN GR CHARWD$
THEN
BEGIN
MSGLEN = MSGLEN - CHARWD$; # DECREMENT MSGLEN #
BLEN = CHARWD$ * CHARLEN$; # STORE WHOLD WORD #
END
ELSE
BEGIN
BLEN = MSGLEN * CHARLEN$; # STORE MSGLEN NO OF CHAR #
DONE = TRUE; # AND THIS IS IT #
END
IF OP + 1 GQ MAX
THEN
BEGIN
EC = OUTPMSH$; # PARMLST TOO SHORT #
ERROR = TRUE;
DONE = TRUE;
END
ELSE
BEGIN
SSBEBF(CSTRING, IORD, IBIT, BLEN, RESULT);
OP = OP + 1; # ALLOC NEW ENTRY IN PARMLST #
OUTCNT = OUTCNT + 1; # INCREMENT OUTCNT, STORE CHARS #
SORD = 0;
SBIT = 0;
SSBSBF(PARMLST[OP], SORD, SBIT, BLEN, RESULT);
END
END
SPASS = TRUE; # TERMINATE SYNTAX CHECKING #
END
GOTO ENDCASE1;
LLOTHER: # OTHER, STRING TO BE COMPARED W/ INPUT #
IF IPOS GQ LEN
THEN
BEGIN # END OF INPUT STRING #
EC = CMDMSGPRM$; # COMMAND MISSING PARAMETER #
ERROR = TRUE;
END
ELSE
BEGIN
IIPOS = IPOS; # SAVE CUR CHAR POSITION #
SSRGNT(CSTRING, IPOS, LEN, ITOKEN, GNTEC);
IF GNTEC NQ 0
THEN
BEGIN
EC = PRMLNG$;
ET = ITOKEN;
ERROR = TRUE;
END
ELSE
BEGIN
IF STOKEN EQ ITOKEN
THEN
BEGIN # INPUT TOKEN MATCH #
IF SYNYMACTVE
THEN
BEGIN
FOR K = 0 WHILE (STOKEN NQ ENDSYNST$)
DO
BEGIN # SKIP FORWARD TO NEXT ">" TKN #
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC);
END
SYNYMACTVE = FALSE; # SET SYNONYM-ACTIVE FALSE #
END
END
ELSE
BEGIN # I-TOKEN NOT MATCH S-TOKEN #
IPOS = IIPOS; # RESET NXT POS TO CUR POS #
IF NOT SYNYMACTVE
THEN
BEGIN # SYNONYM NOT ACTIVE #
IF NOT RESYNCFOUD
THEN
BEGIN # RESYNC NOT FOUND #
CURLINE = FALSE; # SKIP TO NEXT SYNTAX LINE #
END
ELSE
BEGIN # RESYNC FOUND #
FOR K = 0 WHILE ((STOKEN NQ RESYNC$)
AND (CURLINE))
DO
BEGIN # SKIP FORWARD TO NEXT "[" #
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC);
IF STOKEN EQ EOL$
THEN
BEGIN # END OF SYNTAX LINE #
CURLINE = FALSE; # SKIP TO NEXT SYN-LINE #
END
ELSE
BEGIN
SYNYMACTVE = FALSE; # SET SYNONYM-ACT FALSE #
END
END
END
END
END
END
END
GOTO ENDCASE1;
ENDCASE1:
END # END CASE ON SYNTAX FLAGS #
END # PROCESSING A NEW SYNTAX LINE #
END # END PROCESSING SYNTAX TABLE #
IF NOT SPASS
THEN GOTO EXIT; # FAIL SYNTAX CHECKING, EXIT WITH ERROR #
#
* START SEMANTIC CHECKING USING THE INTERMEDIATE PARAMETER LIST AND
* THE SYNTAX LINE(LINE I-1) THAT THE INPUT LINE JUST PASSED AT.
* AT THIS TIME ANY DUPLICATE KEYWORDS, MISSING PARAMETERS AND
* DEFAULTS TO BE INSERTED ARE RECOGNIZED AND ADDED TO THE OUPUT
* OR THE ENTIRE COMMAND REJECTED IF WHAT WAS ENTERED IS INCORRECT.
#
FRSTEOS = FALSE; # CLEAR FIRST END OF SET FLAG #
I = I - 1; # RE-POSITION TO THE JUST PASSED SYN-LINE #
SPOS = 0; # RESET TO BEGINNING OF THE SYN-LINE #
ERROR = FALSE; # SET ERROR FLAG TO FALSE #
STOKEN = " "; # SET TO BLANK TO FORCE FIRST TIME LOOP #
#
* CLEAR OUTPUT PARMETER LIST.
#
FOR J = 0 STEP 1 UNTIL MAX
DO
BEGIN
OPM$WORD[J] = " ";
END
OP = 0; # SET OUTPARM INDEX TO 0 #
OPM$WORD[OP] = PML$WORD[0]; # COPY COMMAND VERB OVER #
FOR J = 0 WHILE ((STOKEN NQ EOL$)
AND (NOT ERROR))
DO # LOOP TIL END OF SYNTAX LINE OR ERROR #
BEGIN
EOSET = FALSE; # SET END OF SET TO FALSE #
MEMCNT = 0; # SET MEMBER COUNT TO 0 #
MEMREQD = FALSE; # SET MEMBER-REQUIRED TO FALSE #
SETDFAULT = " "; # SET SET-DEFAULT TO EMPTY #
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC);
FOR K = 0 WHILE ((STOKEN NQ EOL$)
AND (NOT ERROR)
AND (NOT EOSET))
DO # LOOP TIL END OF LINE, OR SET, OR ERROR #
BEGIN
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC);
IF STOKEN EQ PRMCODE$
THEN
BEGIN
GOTO LLSPRMCODE;
END
ELSE IF STOKEN EQ DFONEST$
THEN
BEGIN
GOTO LLDFONEST;
END
ELSE IF STOKEN EQ ONESET$
THEN
BEGIN
GOTO LLONESET;
END
ELSE
BEGIN
GOTO ENDCASE2;
END
LLSPRMCODE: # @, PARAMETER CODE #
FOUND = FALSE;
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC); # GET STOKEN #
FOR L = 1 STEP 1 WHILE ((L LS OUTCNT)
AND (NOT FOUND))
DO
BEGIN # SEE IF PARM CODE APPEARS IN PARMLST #
IF STOKEN EQ PML$CODE[L]
THEN
BEGIN
OP = OP + 1; # BUMP OUTPARM INDEX #
OPM$WORD[OP] = PML$WORD[L]; # COPY PARM TO OUTPARM #
FOR M=L+1 STEP 1 WHILE M LS OUTCNT
DO # CHECK FOR DUPLICATE DECLARATION #
BEGIN
IF STOKEN EQ PML$CODE[M]
THEN # IF DUPLICATE DECLARATIN FOUND #
BEGIN
ERROR = TRUE; # SET ERROR INDICATOR #
EC = INVCMPRM$; # SET ERROR CODE #
END
END
IF PML$CODE[L] EQ MS0$
THEN
BEGIN # MESSAGE CMD- COPY ENTIRE MESSAGE #
L = L + 1;
FOR M = OP+1 STEP 1 UNTIL OUTCNT-1
DO
BEGIN
OPM$WORD[M] = PML$WORD[L];
L = L + 1;
END
END
FOUND = TRUE;
END
END
IF FOUND
THEN
BEGIN # PARM CODE APPEARS IN PARMLST #
IF FRSTEOS
THEN # IF FIRST END OF SET FOUND #
BEGIN
MEMCNT = MEMCNT + 1; # INCREMENT MEMBER COUNT #
END
IF MEMCNT GR 1
THEN
BEGIN
EC = INVCMPRM$; # INVALID COMBINATION OF PARM #
ERROR = TRUE;
END
END
GOTO ENDCASE2;
LLDFONEST: # !, DEFAULT, OR ONE MEMBER OF SET #
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC); # GET NEXT TOKN#
IF STOKEN EQ PRMCODE$
THEN
BEGIN # STOKEN = "@" #
SSRGNT(CST[I], SPOS, 0, STOKEN, GNTEC);
FOUND = FALSE;
FOR L = 1 STEP 1 WHILE ((L LS OUTCNT)
AND (NOT FOUND))
DO # SEE IF NEXT TKN IN PARMLST #
BEGIN
IF STOKEN EQ PML$CODE[L]
THEN
BEGIN
MEMCNT = MEMCNT + 1; # INCREMENT MEMBER COUNT #
IF MEMCNT GR 1
THEN
BEGIN
EC = INVCMPRM$; # INVALID COMBINATION OF PARM #
ERROR = TRUE;
GOTO ENDCASE2;
END
OP = OP + 1;
OPM$WORD[OP] = PML$WORD[L];
FOUND = TRUE;
END
END
IF NOT FOUND
THEN
BEGIN # NEXT STOKEN NOT IN PARMLST #
SETDFAULT = STOKEN; # SAVE IT AS SET-DEFAULT #
END
END
ELSE
BEGIN # ! NOT FOLLOWED BY @ #
MEMREQD = TRUE; # SET MEMBER REQUIRED TO TRUE #
END
GOTO ENDCASE2;
LLONESET: # \, END OF SET #
IF MEMCNT EQ 0
THEN
BEGIN # MEMBER-COUNT = 0 #
IF SETDFAULT NQ " "
THEN
BEGIN # SET DEFAULT AVAILABLE #
IF OUTCNT LS MAX
THEN
BEGIN
PML$CODE[OUTCNT] = SETDFAULT; # ADD SDF TO PARMLST #
OPM$CODE[OUTCNT] = SETDFAULT; # ADD SDF TO OUTPARM #
OUTCNT = OUTCNT + 1; # INCREMENT OUTCNT #
END
ELSE
BEGIN
EC = OUTPMSH$; # PARMLST TOO SHORT #
ERROR = TRUE;
END
END
ELSE
BEGIN # SET-DEFAULT EMTPY #
IF MEMREQD
THEN
BEGIN # MEMBER REQUIRED TRUE #
EC = CMDMSGPRM$; # COMMAND MISSING PARAMETER #
ERROR = TRUE;
END
END
END
IF NOT FRSTEOS
THEN # IF 1ST END OF SET NOT FOUND YET #
BEGIN
FRSTEOS = TRUE; # SET FIRST END OF SET FLAG #
END
ELSE
BEGIN
EOSET = TRUE; # SET END OF SET FLAG #
END
GOTO ENDCASE2;
ENDCASE2:
END # END OF CASE ON SEMANTIC FLAGS #
END # END OF WHOLE SYNTAX LINE LOOP #
EXIT:
END # SSRRCS #
TERM