XTRAN Example — Highlight File & Terminal I/O Code in PL/I, Display as HTML

The following example uses an XTRAN rules file comprising 166 non-comment lines of XTRAN's rules language ("meta-code") to highlight PL/I code involved with either file or terminal I/O, rendering the code as HTML for coloring.

These rules took about four hours to create and debug.  (That's right, four hours!)  They are not very specific to PL/I; they can easily be adapted to do the same for any 3GL language.

The rules use an XTRAN feature called conditional decoration to highlight the code.  XTRAN also provides unconditional decoration and code nesting depth decoration .

Note that the rules infer file or terminal I/O usage of a variable to which a value is assigned that contains any variables of either type.

The following is an English paraphrase of the XTRAN rules used for this example:

        Specify HTML as module rendering "decoration" prefix and suffix
        Specify HTML as statement rendering "decoration" prefix and suffix,
          according to statement's I/O involvement if any
        Specify HTML as expression rendering "decoration" prefix and suffix,
          according to expression's I/O involvement if any
        For each PL/I statement
            If DISPLAY or ACCEPT statement
                Mark statement as "terminal I/O"
                Mark all variables in statement as "terminal I/O"
            Else if CLOSE, OPEN, READ, or WRITE statement
                Mark statement as "file I/O"
                Mark all variables in statement as "file I/O"
        While variables to mark
            For each PL/I statement
                If assignment statement
                    If right side has "file I/O" and/or "terminal I/O" variables
                        If left side not already marked
                            Mark left side as such
        Render code; XTRAN will decorate it as specified       

How can such powerful code visualization be automated in only four hours and 166 lines of rules?  Because there is so much capability already available as part of XTRAN's rules language. The rules used for this example take advantage of the following functionality provided by that rules language:

NOTE that the rendered code shown as XTRAN's output below was done with default conditions; XTRAN provides many options for controlling the way it renders code for output.

The input to and output from XTRAN are untouched.


Process Flowchart

Here is a flowchart for this process, in which the elements are color coded:

data flowchart

Input to XTRAN:

prc:    PROC (dspio1, filio1);
        DCL (dspio1, dspio2) FIXED BIN (31);
        DCL (filio1, filio2, filio3) FIXED BIN (31);
        DCL (bthio1, bthio2) FIXED BIN (31);
        DCL (neither1, neither2) FIXED BIN (31);
        DCL file1 FILE;

        DISPLAY ('First argument is ' || dspio1);
        dspio2 = dspio1;
        OPEN FILE(file1) INPUT TITLE('foo');
        READ FILE(file1) INTO(filio1);
        filio2 = filio1 + 1;
        bthio1 = bthio1 + filio1;
        neither1 = 1;
        neither2 = neither1 + 1;
        IF (filio2 > filio3) THEN
            filio3 = filio2;
        bthio1 = dspio1;
        bthio2 = filio1 + bthio1;
        dspio1 = neither2;
        CLOSE FILE(file1);
        RETURN;
        END prc;


Output from XTRAN (HTML):


PL/I with File and Terminal I/O Highlighted


prc:    PROCEDURE (dspio1, filio1);
        DCL (dspio1, dspio2) FIXED BIN (31);
        DCL (filio1, filio2, filio3) FIXED BIN (31);
        DCL (bthio1, bthio2) FIXED BIN (31);
        DCL (neither1, neither2) FIXED BIN (31);
        DCL file1 FILE;

        DISPLAY ('First argument is ' || dspio1);
        dspio2 = dspio1;
        OPEN FILE(file1) INPUT TITLE('foo');
        READ FILE(file1) INTO(filio1);
        filio2 = filio1 + 1;
        bthio1 = bthio1 + filio1;
        neither1 = 1;
        neither2 = neither1 + 1;
        IF filio2 > filio3
          THEN
            filio3 = filio2;
        bthio1 = dspio1;
        bthio2 = filio1 +
          bthio1;
        dspio1 = neither2;
        CLOSE FILE(file1);
        RETURN;
        END prc;