PL/I förprocessor

PL /I-förprocessorn är förprocessorn för PL/I - datorprogrammeringsspråket . Förprocessorn tolkar en delmängd av hela PL/I-språket för att utföra källfilinkludering , villkorlig kompilering och makroexpansion .

Preprocessor-språket har en PL/I-liknande syntax med preprocessor-satser och preprocessor-procedurer prefixerade med en procentsymbol ( % ). Listing-control-satser, som tillhandahåller formateringskommandon för kompilatorlistan , betraktas vanligtvis som preprocessor-satser och börjar också med % . Preprocessor-satser är inbäddade i och fungerar på inmatad text. Inmatningstexten är normalt ett PL/I-program, men är agnostisk mot grammatiken för PL/I, så förprocessorn kan också användas oberoende för att bearbeta andra typer av textfiler.

Förprocessorn är inte specificerad som en del av standard PL/I, men de flesta PL/I-implementationer accepterar språket för IBM-förprocessorn.

Inklusive filer

%INCLUDE preprocessor- satsen används för att inkludera texten i en annan fil, som också kan innehålla förbehandlardirektiv. De senaste IBM-kompilatorerna tillhandahåller också ett %XINCLUDE- direktiv, som har effekten att inkludera den angivna filen endast om den inte redan har inkluderats. %INSCAN och %XINSCAN fungerar på liknande sätt, förutom att namnet på filen som ska inkluderas anges av ett förprocessoruttryck.

Listningskontroll

Listningskontrollsatser tillhandahåller instruktioner för att formatera både listningen som genereras av förprocessorn och listningen som genereras av kompilatorn.

  • %SKRIVA UT; gör att utskriften av listor med följande text startas eller återupptas.
  • %NOPRINT; gör att utskriften av listorna för följande text undertrycks.
  • %SIDA; gör att en ny sida startas i listorna.
  • %SKIP [(n)]; gör att n rader hoppas över i listorna. Om n utelämnas är standarden en rad.
  • %PUSH , %POP sparar och återställer den aktuella statusen för %PRINT / %NOPRINT på en pushdown-stack respektive återställer den.

Förprocessordrift

Förprocessorn arbetar genom att skanna inmatad text och känna igen deklarerade förprocessornamn , även kallade förprocessoridentifierare . Texten kopieras till förprocessorns utdata med förprocessornamnen ersatta med deras nuvarande värden. Namnet kan representera ett anrop till en förprocessorprocedur ( makro ). Ersättningstext kan skannas om av förprocessorn för eventuell ytterligare ersättning.

Förbehandlare datatyper

Förbearbetningsdata kan deklareras som CHARACTER , en teckensträng utan maximal längd eller FIXED ett heltal på upp till fem decimalsiffror. En inbyggd förprocessor är en fördefinierad procedur som arbetar på förprocessordata. Ett förprocessoruttryck är ett uttryck som endast består av förprocessornamn, referenser till förprocessorprocedurer eller inbyggda funktioner och decimal- eller teckenkonstanter. Det finns inga BIT- variabler, men ett BIT- resultat kan erhållas genom jämförelse. Uttrycket i %IF utvärderas till BIT . Alla PL/I-operatorer är tillåtna utom exponentiering.

Preprocessor uttalanden

  • %DECLARE upprättar en identifierare som en förprocessorvariabel, antingen CHARACTER eller FIXED .
  • %assignment tilldelar ett värde till en förprocessoridentifierare.
  • %ACTIVATE gör en förprocessoridentifierare aktiv, det vill säga kvalificerad för ersättning när den påträffas i inmatningstexten.
  • %DEACTIVATE gör en förprocessor inte kvalificerad för ersättning.
  • %DO leder en förprocessor DO -grupp, som används för att gruppera satser och eventuellt specificera iteration. En förbehandlare DO -grupp kan innehålla valfri kombination av förbehandlare uttalanden och inmatad text.
  • %PROCEDURE leder en preprocessor-procedur, en uppsättning preprocessor-satser som fungerar som ett makro som returnerar ett värde när dess namn påträffas i inmatningstexten.
  • %SELECT leder en förprocessor SELECT -grupp .
  • %END avslutar en förprocessor DO -grupp, SELECT -grupp eller förprocessorprocedur.
  • %GOTO (eller %GO TO ) får förprocessorn att fortsätta sin scanning vid den angivna förprocessoretiketten, antingen en preprocessor-sats eller en godtycklig punkt i inmatningstexten.
  • %IF styr flödet av förprocessorskanningen enligt värdet av ett förprocessoruttryck.
%IF preprocessor-expression %THEN preprocessor unit1 %ELSE preprocessor-unit2

Förprocessorenheterna kan vara vilken enskild förprocessorsats som helst eller en förprocessor DO -grupp.

  • %ITERATE överför kontrollen till %END av den innehållande förprocessorns DO -grupp, avslutar den aktuella iterationen och börjar nästa om det behövs.
  • %LEAVE avslutar alla återstående iterationer av den innehållande förprocessorn DO -gruppen överför kontrollen till %END .
  • %NOTE genererar ett användarspecificerat diagnostiskt meddelande för förprocessorn.
  • %null är en preprocessor-sats som endast består av en valfri satsetikett och ett semikolon ( ; ). Det gör ingenting, utan fungerar som en platshållare där ett obligatoriskt uttalande inte behövs.
  • %REPLACE tillåter omedelbar ersättning av ett namn med ett tecken eller ett fast uttryck. Namnet behöver inte vara en deklarerad förprocessoridentifierare.

Förberedande förfaranden

En förprocessorprocedur är en subrutin som exekveras av förprocessorn. Proceduren är avgränsad av %PROCEDURE- och %END -satserna och kan endast innehålla förbearbetningssatser, utan den inledande % . Den anropas som en funktionsreferens från öppen kod , utanför någon förbehandlarprocedur, eller från en annan förbehandlarprocedur, och returnerar ett CHARACTER eller FIXED värde. När proceduren anropas från öppen kod skickas argumenten med namn , det vill säga de tolkas som teckensträngar avgränsade med kommatecken eller höger parentes, alla inledande, efterföljande eller inbäddade blanksteg är signifikanta och anses vara en del av argumentet.

Förprocessor inbyggda

Dessa är inbyggda för IBM:s PL/I för MVS och VM- kompilator. Det kan vara avsevärd skillnad i de inbyggda funktionerna mellan förprocessorer för olika PL/I-kompilatorer.

  • COMPILETIME — returnerar datum och tid för kompileringen som en teckensträng som "15 SEP 12 15:30:00" för 15 september 2012 15:30 (lokal tid).
  • COUNTER — returnerar en teckensträng som innehåller ett nummer som är "00001" för det första anropet till COUNTER och ökar med ett för varje efterföljande anrop.
  • INDEX — samma som PL/I inbyggda INDEX .
  • LENGTH — samma som PL/I inbyggd LENGTH .
  • PARMSET PARMSET(p) returnerar '1'b om argumentet p sattes i det aktuella anropet till denna förprocessorprocedur, annars '0'b .
  • SUBSTR — samma som PL/I inbyggd SUBSTR .

Exempel

Följande exempel för IBM PL/I för OS/2 illustrerar användningen av en förprocessorprocedur för att implementera en C-liknande skrivsats för PL/I. Proceduren skulle anropas genom att koda satsen uwrite file(filename) from(variing_string) count(byte_count); Byte_count är valfritt och har som standard längden på varying_string om den utelämnas.

     

       

       
      
    
    

  
               
           

   
  
        
      
                         
                             
                           
                          
   

  %  uwrite  : 
 procedurnycklar  (  File  ,  From  ,  Count  )  ;  _  dcl  (  File  ,  From  ,  Count  ,  Number  ,  Size  )  char  ;  if  parmset  (  File  )  &  parmset  (  From  )  then  ;  annat  gör  ;  note  (  'FILE och FROM måste anges!'  ,  12  )  ;  återvända  ;  slut  ;  om  parmset  (  Count  )  then  Size  =  'min(length('  ||  From  ||  '), '  ||  Count  ||  ')'  ;  else  Size  =  'length('  ||  Från  ||  ')'  ;  Antal  =  Räknare  ()  ;  ans  (  'do;'  )  ;  ans  (  'dcl Count'  ||  Number  ||  ' fixed bin (15);'  )  skip  ;  ans  (  'Count'  ||  Number  ||  ' = filewrite('  ||  Fil  ||  ', ptradd(addr('  ||  Från  ||  '), 2)'  ||  ', '  ||  Storlek  ||  ') ;'  )  skip  ;  ans  (  'slut;'  )  skippa  ;   %  slut  ; 
   %  act  uwrite  ; 

Uttrycket uwrite file(file_name) from(var_str) count(64); genererar följande:

 
     
       
  göra  ;  dcl  Count00001  fast  bin  (  15  )  ;  Count00001  =  filskrivning  (  filnamn  ,  ptradd  (  addr  (  var_str  ),  2  ),  min  (  längd  (  var_str  ),  64  ))  ;  slut  ; 

Evolution

En rapport från 1964 om "NPL", som PL/I kallades på den tiden, förutsatt att makroprocedurer, identifierade med nyckelordet MACRO , kunde använda språkets kompletta faciliteter. Följande kompileringstidssatser var tillåtna i öppen kod:

  • %DECLARE – både fast längd och varierande teckensträngar definierades.
  • % uppdrag
  • % null-sats
  • %IF compile_time_comparison THEN unit [ELSE- enhet ] – detta gör att den ena eller den andra enheten inkluderas i källan.
  • %GÅ TILL

"NPL" enligt definitionen i denna handbok implementerades aldrig.

1965 definierade en uppdatering av IBMs PL/I Language-specifikation ett ännu mindre ambitiöst förprocessorspråk. Allt omnämnande av förbearbetningsförfaranden utelämnades. Följande kompileringstidssatser specificerades:

  • %DEKLARERA
  • % uppdrag
  • % null-sats
  • %IF compile_time_comparison THEN GOTO label – Ingen ELSE- sats definierades.
  • %GÅ TILL

Denna språkspecifikation implementerades aldrig igen, men en 1966 revision av denna handbok återställde förbearbetningsprocedurerna med den nu gällande syntaxen %PROCEDURE ... %END och förde specifikationen nära vad som faktiskt ingick i PL/I(F). Teckenvariabler med fast längd var borta. Nya uttalanden som lades till var:

  • %AKTIVERA
  • %AVAKTIVERA
  • %DO [ preprocessor_variable = preprocessor_expression TO preprocessor_expression [BY preprocessor_expression ]]
  • RETURNERA endast i en kompileringstid.
  • %OMFATTA
  • %IF %IF compile_time_comparison %THEN- enheten [%ELSE- enhet ] återställdes.

En enda inbyggd kompileringstid, SUBSTR , lades till.

Också 1966 publicerade Robert Rosin ett par artiklar som diskuterade utvecklingen av förprocessorn. Denna utveckling baserades på ett " SHARE XXVI Memo" från tidigare samma år och en artikel av Mark Elson. Rosin krediterar MAD som det enda tidigare exemplet på en makroprocessor i ett högnivåspråk.

Se även

externa länkar