COBOL, PL/I Preprocessor tutorial

The Z Open Editor sampleopen in new window Git repository contains configuration and program files to try the COBOL and PL/I Preprocessor support available in Z Open Editor. It contains examples for custom preprocessors written in Java as well as REXX that you can easily build and execute.

After you complete this tutorial, you can write and use your own preprocessor in a similar way by replacing the command line and parameters in the configuration files shown here.

To use the Z Open Editor Preprocessor feature and these examples, you must have a unexpired trial or activation key listed in the Welcome page.

Review the ZAPP file and create ZAPP user or workspace variables

  1. Open the samples ZAPP file, zapp.yaml and find the local-cobol or local-pli preprocessor profile defined there. It references three variables to execute the preprocessor: ${JAVA_HOME}, ${WORKSPACE}, and ${HLQ}, which is used only for the remote preprocessor examples. You find placeholders for these three in this samples workspace settings file located in .vscode/settings.json.

  2. You must first open the file, and then you can do any of the following things

    1. replace the three values with your absolute $JAVA_HOME path and the absolute path of this workspace, where you cloned this Git repository on your development machine, or
    2. move these variables to your user settings as these are specific to your local setup, or
    3. just replace the variables in the ZAPP profiles shown below with their concrete values.

Local preprocessor examples

Prepare the sample preprocessor program

  1. To use the sample preprocessor you need to build it using Java. The folder preprocessor/<COBOL|PLI>/local-preprocessor contains a Java Maven project that you can use to build it by running mvn package from that folder.
  2. Alteratively, use the Extension Pack for Javaopen in new window to build it from VS Code (Java and Maven required in your path).

Local COBOL profile sample :

    - name: local-cobol
        language: cobol
        type: preprocessor
        location: local
        settings:
          command: ${JAVA_HOME}/bin/java -jar ${WORKSPACE}/preprocessor/COBOL/local-preprocessor/target/local-cobol-preprocessor-1.0-SNAPSHOT.jar {input_file} ${output_file}
          outputPath: ./preprocessor/output
          fileExtension: cee
          environmentVariables:
            some: var

Local PL1 profile sample :

    - name: local-pli
        language: pl1
        type: preprocessor
        location: local
        settings:
          command: ${JAVA_HOME}/bin/java -jar ${WORKSPACE}/preprocessor/PLI/local-preprocessor/target/local-pl1-preprocessor-1.0-SNAPSHOT.jar ${input_file} ${output_file}
          outputPath: ./preprocessor/output
          fileExtension: pci
          environmentVariables:
            some: var

Note, that if you are using Windows and have a space in the path (for example, Program Files), you must replace the portion of the path that has spaces with the Windows shorthand. Generally, these are the first 6 non-whitespace characters in the path followed by ~1, for example, for Program Files this is Progra~1, for a directory like test files this is testfi~1. If the path is shorter than 6 non-whitespace characters, you can to use cmd to get the shorthand. To do this, open cmd, go above the directory you need the shorthand, for example, C:/ for C:/Program Files. Run dir /x, and the directories are listed with their shorthands.

Also note the location of the outputPath setting in the profile that points to the directory preprocessor/output. This is the folder were the preprocessed programs is generated in.

Running the local preprocessor from Z Open Editor

Now you are ready to run the preprocessor on our sample programs.

  1. Open either the file preprocessor/COBOL/PrintApp.cbl or preprocessor/PLI/PrintApp.cbl. You see that Z Open Editor shows many syntax errors as it contains macros such as +ID, +DD and so on. The sample preprocessor replaced them with valid COBOL or Pl/I code during its execution to enable our COBOL or PL/I language server to parse them.

  2. Right-click inside the editor and select "Execute local preprocessor command".

  3. A progress bar opens and as a result all the syntax errors goes away. If something goes wrong, check the log output for error messages in the VS Code Output view under the Z Open Editor drop-down value.

  4. You can now hover over the preprocessor macros and see the code in a hover that has been created to replace them. For example, the +ID. COBOL statement shows has a hover that show the replacement with IDENTIFICATION DIVISION.. The PL/I +DL statement shows a replacement with DECLARE.

  5. Open the generated output file preprocessor/output/PrintApp.cee in the editor. You see the file generated by the preprocessor, which is a valid COBOL or PL/I program. The Z Open Editor language server uses that program file to parse for errors and overlay the results to the original program.

  6. Go back to preprocessor/COBOL/PrintApp.cbl or preprocessor/PLI/PrintApp.pli and select "Compare preprocessor input and output files" from the context menu. It is presented in VS Code's Diff editor that shows you the two files and their differences side by side.

  7. Open you user settings and find zopeneditor.autoPreprocessor. From the drop-down select all. Switch back to the editor and make changes to the sample program. You might see syntax errors if you use the macros in your statements. However, when you save the program, you can see that the preprocessor is executed automatically and the errors related to the macros go away. Examine the other drop-down values for when the preprocessor should be triggered.

Remote preprocessor example

Review the ZAPP file and prepare your data sets

To run the remote preprocessor example that performs on z/OS®, ensure that you have created a Zowe Explorer profile for RSE API or z/OSMF and made it your default using the zopeneditor.zowe": {"profile-name"} user setting. The profile name should be displayed in the status bar of the editor. Note, that for z/OSMF you must also define a TSO Zowe CLI profile as the REXX preprocessor example is executed using TSO. For RSE API profiles this is not required as RSE API has a TSO interface built-in.

  1. Open the samples ZAPP file, zapp.yaml and find the remote-cobol or remote-pli preprocessor profile defined there. It references several data set names and the ${HLQ} variable.

  2. Either replace the variable with your high-level qualifier or define a ZAPP variable in your user or workspace settings as described above.

Remote COBOL profile sample :

- name: remote-cobol
  language: cobol
  type: preprocessor
  location: mvs
  settings:
    commandDataSet: ${HLQ}.PREPROC(CBLPRPC)
    tempDataHLQ: ${HLQ}
    outputDataSet: ${HLQ}.PREPROC.OUTPUT()
    commandParameters: ""

Remote PL1 profile sample :

- name: remote-pli
  language: pl1
  type: preprocessor
  location: mvs
  settings:
    commandDataSet: ${HLQ}.PREPROC(PLIPRPC)
    tempDataHLQ: ${HLQ}
    outputDataSet: ${HLQ}.PREPROC.OUTPUT()
    commandParameters: ""
  1. Create a PDSE for commandDataSet and outputDataSet. You can use the suggested names from the ZAPP or create them using other names and update the ZAPP profile with these names.

  2. You also need to create or reuse an existing PDSE for the COBOL sample program preprocessor/COBOL/PrintApp.cbl, such as ${HLQ}.PREPROC.COBOL and the equivalent for PL/I. It must have the words COBOL or CBL (PLI or PL1) in its name, so Z Open Editor uses its default file associations to open the file with the COBOL language server. The sample preprocessor creates a temporal sequential data set using your HLQ and delete it after completion.

  3. Use Zowe Explorer to upload the REXX sample preprocessor program preprocessor/remote-preprocessor/CBLPRPC.rexx to the commandDataSet you created in the previous step.

  4. Upload the preprocessor/COBOL/PrintApp.cbl to the PDSE you have created for it in the previous step, such as ${HLQ}.PREPROC.COBOL. For Pl/I use the equivalent files.

Running the remote preprocessor from Z Open Editor

  1. Open the PRINTAPP program through Zowe Explorer and ensure that it is recognized as a COBOL or PL/I program that shows you syntax highlighting, an outline view, and so on. If your PDSE does not contain the keywords required, then you can click the status bar in VS Code to select COBOL as the language to use for this file. The sample program is not processed yet, so it shows syntax errors.

  2. Right-click inside the editor and select "Execute remote preprocessor command". A progress bar opens and as a result all the syntax errors go away. If the result is not as expected, check the log output for error messages in the VS Code Output view under the Z Open Editor drop-down value.

  3. You can now hover over the preprocessor macros and see the code that is used to replace them in a hover. For example the +ID. statement shows in the hover that it is replaced with IDENTIFICATION DIVISION..

  4. Open the generated output file that is created in the outputDataSet in the editor. You see the file generated by the preprocessor, which is a valid COBOL program. The Z Open Editor language server uses that program file to parse for errors and overlay the results to the original program.

  5. Open you user settings and find zopeneditor.autoPreprocessor. From the drop-down select all. Switch back to the editor and make changes to the sample program. You might see syntax errors if you use the macros in your statements. However, when you save the program you can see that the preprocessor is executed automatically and the errors related to the macros go away. Examine the other drop-down values for the preprocessor to be triggered and select the one that fits your needs.

Remote preprocessor for local files example

Review the remote ZAPP profile and prepare your data sets with programDataSet

You can also run a remote preprocessor on files that you edit locally, for example as part of your Git repository. The Z Open Editor uploads the program file you are currently editing to a dedicated PDSE, execute the preprocessor on z/OS and then fetch the output file back to the local file system.

  1. To run the remote preprocessor example on local files, ensure that the Remote preprocessor example works as expected.

  2. Review the ZAPP file and find the profiles remote-cobol or remote-pli.

  3. Uncomment the last line with the programDataSet property with the location where the local file is uploaded.

  4. Create such a PDSE and provide the value for this property. You can use the suggested names from the ZAPP file or create them using other names and update the ZAPP profile with these names.

Remote COBOL profile sample:

- name: remote-cobol
  language: cobol
  type: preprocessor
  location: mvs
  settings:
    commandDataSet: ${HLQ}.PREPROC(CBLPRPC)
    tempDataHLQ: ${HLQ}
    outputDataSet: ${HLQ}.PREPROC.OUTPUT()
    commandParameters: ""
    programDataSet: ${HLQ}.PREPROC.COBOL()

Remote PL1 profile sample:

- name: remote-pli
  language: pl1
  type: preprocessor
  location: mvs
  settings:
    commandDataSet: ${HLQ}.PREPROC(PLIPRPC)
    tempDataHLQ: ${HLQ}
    outputDataSet: ${HLQ}.PREPROC.OUTPUT()
    commandParameters: ""
    programDataSet: ${HLQ}.PREPROC.COBOL()

Running the remote preprocessor for local files from Z Open Editor

  1. Open either the file preprocessor/COBOL/PrintApp.cbl or preprocessor/PLI/PrintApp.cbl. You see that Z Open Editor shows many syntax errors as it contains macros such as +ID, +DD and so on. The sample preprocessor replaced them with valid COBOL or Pl/I code during its execution to enable our COBOL or PL/I language server to parse them.

  2. Right-click inside the editor and select "Execute remote preprocessor command for local file".

  3. A progress bar opens and as a result all the syntax errors go away. You can now hover over the preprocessor macros and see the code that is used to replace them in a hover. For example the +ID. statement shows in the hover that it is replaced with IDENTIFICATION DIVISION..

  4. Open the generated output file that is created in the outputDataSet in the editor. You see the file generated by the preprocessor, which is a valid COBOL program. The Z Open Editor language server uses that program file to parse for errors and overlay the results on the original program with macros in the editor.

Expanding PL/I macros using a remote preprocessor

To expand the PL/I macros using remote preprocessor, ensure that you have created a Zowe Explorer profile for RSE API or z/OSMF and made it your default using the using the zopeneditor.zowe": {"profile-name"} user setting.

  1. Open the samples ZAPP file and find the remote-pli-macro preprocessor profile defined there. As the first preprocessor profile gets picked up on the basis of language and location, make sure the profile you want to run is ordered under the preprocessor section or you can comment out the other preprocessor profiles.

  2. It references several data set names and a HLQ variable. Either replace the variable with your high-level qualifier or define a ZAPP variable in your user or workspace settings.

  3. Also comment out the PL/I property groups that were defined for the PSAM example as these do not work with the preprocessor example.

- name: remote-pli-macro
  language: pl1
  type: preprocessor
  location: mvs
  settings:
    commandDataSet: ${HLQ}.SFELSAMP(FEKRNPLI)
    tempDataHLQ: ${HLQ}
    outputDataSet: ${HLQ}.PREPROC.OUTPUT()
    commandParameters: <SYSPRINT>${HLQ}.LOG.OUTPUT()</SYSPRINT>
  1. Create a PDSE for commandDataSet with PL/I macro preprocessor preprocessor/PLI/remote-preprocessor/FEKRNPLI.rexx as a member in it, and outputDataSet. You can use the suggested names from the ZAPP or create them using other names and update the ZAPP profile with these names.

  2. To append the <SYSPRINT> tag in the XML use commandParameters in the ZAPP profile. To create the SYSPRINT data set ${HLQ}.LOG.OUTPUT() use following data set attributes:

    Record Format (recfm): VBA
    Record Length (lrecl): 137
    Dataset Type (dsntp): LIBRARY
  1. In FEKRNPLI.rexx you need to replace the ".V6R1M0.SIBMZCMP(IBMZPLI)" from compiler = compiler_hlq||".V6R1M0.SIBMZCMP(IBMZPLI)" in line 82 with the PL/I compiler in your current z/OS® system.

  2. You also need to create or reuse an existing PDSE for the PL/I sample program PLI/CITYCODE.pli, such as ${HLQ}.PREPROC.PLI. It must have the words PLI or PL1 in its name, so Z Open Editor uses its default file associations to open the file with the PL/I language server. The sample preprocessor creates a temporal sequential data set using your HLQ and deletes it after completion.

  3. Open the CITYCODE program through Zowe Explorer and ensure that it is recognized as a PL/I program that shows you syntax highlighting, an outline view, and so on. If your PDSE does not contain the keywords required then you can click the status bar in VS Code to select PL/I as the language to use for this file. If the sample program is not processed, it shows syntax errors.

  4. Right-click inside the editor and select "Execute remote preprocessor command".

  5. A progress bar opens and as a result all the syntax errors go away. You can now hover over the preprocessor macros and see the code that is used to replace them in a hover. For example the macro statements including % is resolved and removed. For example in the CITYCODE.pli file from line 14 to 16 which are macros are removed. Similarly, other macro statements get resolved.

 %DCL USE CHAR;
 %USE = 'FUN' /* FOR SUBROUTINE, %USE = 'SUB' */ ;
 %IF USE = 'FUN' %THEN %DO;

Note: Using this sample result in a RC=12 from the PL/I compiler even though it does produce a valid output file. This is expected and it means the preprocessor is successfully finished.

Last Updated:
Contributors: Esther M, PETER HAUMER