XTRAN Example — Analyze Knots in PL/I

Scenario — you know that your development shop's code is rife with "goto"s, and you suspect that they are seriously impeding the readability and maintainability of the code.  You further suspect that their use to create "threaded code" is Byzantine in nature, further damaging the code's maintainability.

You need to analyze the impact of complex code threading with "goto"s across your code, so you can target your cleanup efforts effectively.

XTRAN to the rescue!

The following example uses an XTRAN rules file comprising 139 non-comment lines of XTRAN's rules language ("meta-code") to analyze PL/I code and show any knots it finds.

A knot is the crossing of two "goto"s.  A knot count is an important measure of code quality for two reasons:

Note that the analysis results in the XTRAN run log show not only the number of knots, but also the actual "goto" crossings from which that number was determined.

The XTRAN rules themselves are not specific to PL/I; they are language-independent, and therefore usable without change to analyze any language that has "goto"s.

The code mining rules for this example can easily be enhanced to produce DSV output that can be interactively queried using existing XTRAN rules.

How can such powerful and generalized code analysis be automated in only 139 lines of rules?  Because there is so much capability already available as part of XTRAN's rules language.  These rules take advantage of the following functionality:

The input to and output from XTRAN are untouched, except that line numbers have been added to the PL/I source code for reference.




Process Flowchart

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

process flowchart


Input to XTRAN — demknt-a.pli:

19 prc:    PROCEDURE;
20         DCL i FIXED (31) BIN;
21                                /* Nesting           Range      */
22                                /* ============================ */
23
24 lbl0:   GOTO lbl14;            /* >--------------\  lbl0-lbl14 */
25 lbl1:   i = 1;                 /* <--------\     |             */
26 lbl2:   GOTO lbl10;            /* >-----\  |     |  lbl2-lbl10 */
27 lbl3:   i = 3;                 /*       |  |     |             */
28 lbl4:   GOTO lbl1;             /* >-----x--/     |  lbl1-lbl4  */
29 lbl5:   i = 5;                 /* <-----x-----\  |             */
30 lbl6:   GOTO lbl13;            /* >-----x--\  |  |  lbl6-lbl13 */
31 lbl7:   GOTO lbl9;             /* >--\  |  |  |  |  lbl7-lbl9  */
32 lbl8:   i = 8;                 /*    |  |  |  |  |             */
33 lbl9:   i = 9;                 /* <--/  |  |  |  |             */
34 lbl10:  i = 10;                /* <-----/  |  |  |             */
35 lbl11:  GOTO lbl5;             /* >--------x--/  |  lbl5-lbl11 */
36 lbl12:  i = 12;                /*          |     |             */
37 lbl13:  i = 13;                /* <--------/     |             */
38 lbl14:  i = 14;                /* <--------------/             */
39         END prc;



Excerpt from XTRAN run log:


Knots found in source code:

demknt-a.pli:  GOTO at line 26 crosses GOTO at line 28
demknt-a.pli:  GOTO at line 26 crosses GOTO at line 30
demknt-a.pli:  GOTO at line 26 crosses GOTO at line 35
demknt-a.pli:  GOTO at line 30 crosses GOTO at line 35

demknt-a.pli has 4 knots.