MainframeSupports
tip uge 10/2013:

I denne uge vil jeg vise dig et stykke kode, jeg typisk benytter til at scanne PARM-arealet fra EXEC-kortet. Helt generelt er det en større sag at kode en scanner til at fortolke en lang tekst, som for eksempel et program. Hvor stor en sag det er, afhænger i høj grad af, hvor avanceret en syntaks, du ønsker at scanne. Denne scanner kan fortolke en syntaks, hvor hver parameter i PARM-arealet er adskilt af et komma. Du kan selv ændre dette til et hvilket som helst andet tegn. En parameter kan enten være numerisk eller bare en tegnstreng. En numerisk parameter oversættes til en integer variabel (BINARY eller DECIMAL).

Selve koden har jeg implementeret som en procedure i PLI uden parametre. Det bør derfor være en smal sag at oversætte koden til COBOL. I det følgende eksempel er første parameter maxRecords, som er antallet af records (FIXED BIN(31)), jeg ønsker at behandle i programmet. Anden parameter er dlmChar, som er en delimiter på et tegn (CHAR(1)) i de records, jeg indlæser. Tredie parameter er fmtMethod, som er en tegnstreng (CHAR(8) VAR), som styrer formateringen af de indlæste records afhængig af værdi. Bemærk, at de nævnte parametre er erklæret i selve programmet (som ikke er en del af tippet). Selve input til de enkelte parametre er variablen parm som selvfølgelig er erklæret som en CHAR(100) VAR. Og her er så den simple scanner:

readParm: PROC;

DCL nextChar CHAR(1);
DCL nextPic PIC'9' DEF nextChar;
DCL invalidChar CHAR(1);
DCL posNo FIXED BIN(15);
DCL parmNo FIXED BIN(15);
DCL digitCount FIXED BIN(15);

maxRecords = 0;
dlmChar = '"';
fmtMethod = '';

digitCount = 0;
invalidChar = 'N';
nextChar = 'N';
parmNo = 1;
posNo = 0;
DO WHILE(posNo < length(parm));
  posNo = posNo + 1;
  nextChar = substr(parm, posNo, 1);
  IF nextChar = ','
  THEN DO;
    parmNo = parmNo + 1;
    invalidChar = 'N';
    digitCount = 0;
  END;
  ELSE
    SELECT(parmNo);
      WHEN(1)
        IF invalidChar = 'N'
        THEN
          IF verify(nextChar, '0123456789') = 0
          & digitCount < 9
          THEN DO;
            maxRecords = maxRecords * 10 + nextPic;
            digitCount = digitCount + 1;
          END;
          ELSE
            invalidChar = 'Y';
      WHEN(2)
        dlmChar = nextChar;
      WHEN(3)
        fmtMethod = fmtMethod !! nextChar;
      OTHERWISE
        ;
    END;
END;

END readParm;

Det mest komplicerede er selvfølgelig fortolkningen af en numerisk variabel. Ved hjælp af variablen digitCount styrer jeg, hvor mange cifre parameteren maksimalt må indeholde. Der er ingen fejlbehandling i scanneren. Når det første ikke-numeriske tegn mødes, så skippes de øvrige tegn bare, indtil der dukker et komma op og skifter til fortolkning af næste parameter. Hvis der er mere end et tegn i anden parameter, så er det det sidste tegn, der anvendes. I sidste parameter forsvinder tegn efter det ottende tegn bare. Hvis der er mere end tre kommaer i parm, så sker der heller ikke noget særligt.

Det gode ved denne simple scanner er, at det er nemt at tilføje fortolkning af ekstra parametre og rykke rundt på fortolkningen af de enkelte parametre. Default-værdier for en CHAR(1) eller en FIXED BIN(n) tildeles før WHILE-loop'et. Jeg vil til gengæld anbefale, at tegnstrenge på mere end et tegn erklæres som CHAR(n) VAR, initialiseres til '' og hvis tegnstrengen efter WHILE-loop'et stadig er '', så kan du tildele den pågældende parameter en default-værdi.

Forrige danske tip        Last tip in english        Tip oversigten