XTRAN Example — Analyze Year 2000 (Y2K) Impact on PL/M
This example shows how XTRAN rules can analyze PL/M code in order to identify symbols and contexts that may be a problem in terms of the Year 2000 (Y2K). The approach is not specific to PL/M; similar XTRAN rules can easily be written for other computer languages, including assemblers, other 3GLs, and 4GLs. Click for an assembler example and for a C / C++ / Java / C# example.
Of course, Y2K has come and gone, but this is an excellent example of XTRAN's analysis power, so we decided to keep it on our Web site.
In order to accommodate the occurrence of duplicate symbol names that are local to different modules or scopes, or occur in different name spaces, the XTRAN rules ("meta-code") are set up to deal with fully qualified symbols, as returned by a built-in XTRAN meta-code primitive. Full qualification includes:
- The module file name if the symbol is not global.
- All levels of lexical scope, such as function,
{}
block, etc. - The symbol's name space (variables, labels, tags, etc.).
We specify, via environment variables, patterns in the form of (case-insensitive) regular expressions for the meta-code to use to identify possible Y2K problem symbols, as well as possible Y2K problems evidenced in the code's text strings and comments. In each case, the meta-code allows us to specify one or more regular expressions, separated by commas. Note that this makes the analysis independent of the human language involved. For this example, we specified the following regular expressions:
- For matching symbol names:
y[ae]*r
- For searching text strings:
y[ae]*r,19
- For searching comments:
y[ae]*r,19
Our meta-code reads text files (named via environment variables) containing symbols, both global and local to the module we are analyzing, that are known to be ("yes"), or not to be ("no"), Y2K problems. The meta-code excludes the latter from its analysis. These files usually start out empty and are then populated with symbols through the review process, as described below.
Our meta-code creates a similar text file ("maybe") in which it puts symbols it finds in the subject module that may be Y2K problems, along with a reason for each one. It does not, however, add to this file any symbols that have already been specified as known Y2K problems. Reasons for a symbol's inclusion in the module's "maybe" file are as follows:
- The symbol matches one of the symbol name patterns specified.
- The symbol's value is assigned to a known problem symbol.
- The symbol has a value assigned to it from a known problem symbol.
- The symbol is compared to a known problem symbol.
Our meta-code also reports, as analysis output, the following:
- Every occurrence in the code of each symbol known to be a Y2K problem.
- Every occurrence of any of the specified text patterns (case-insensitive) in text strings in the module.
- Every occurrence of any of the specified text patterns (case-insensitive) in the first 50 characters of any comment in the module.
Each of these occurrences is noted with the source file name and line number, in a form suitable for the "next error" features of the Vi and Emacs text editors. This allows us to conveniently visit each occurrence in the source code during review.
Note that the analysis report for a given module is only complete and accurate when the run produces no "maybes" for the module. Prior reports for that module should be ignored.
Analysis Sequence of Events:
The typical sequence of events in performing this analysis on a body of PL/M code is as follows:
- Run XTRAN on each PL/M module with the meta-code,
which will read files containing known problem ("yes") and known
non-problem ("no") symbols, both global and specific to this module
(there will be none of the latter on the first run). The run will create
a "maybe" (
.msm
) symbol file for the module. It will also create a.y2k
analysis report for the module. If the resulting "maybe" file has symbols in it, disregard the analysis report, since it didn't take the "maybe" symbols into account. - After running each module, if its "maybe" file has symbols in it, review them, deciding in the case of each symbol whether or not it is a Y2K problem. If it is, add its line to the appropriate "yes" symbol file (global or module-specific). If it isn't, add its line to the appropriate "no" symbol file (global or module-specific). Go to step 1.
- When running the module with the meta-code produces no "maybe" symbols, the module's analysis report is complete and accurate. We can then use the (possibly updated) global "yes" and "no" files for the analysis of subsequent PL/M modules.
When all modules have been analyzed, we have the following:
- The global "yes" and "no" symbol files document all global symbols that are known to be, or not to be, Y2K problems.
- Each module's "yes" and "no" files similarly document symbols local to the module.
- Each module's analysis report documents all occurrences in the module of:
- Y2K problem symbols, both global and local.
- Specified text patterns, in text strings in the code.
- Specified text patterns, in comments in the code.
Environment Variables and Files:
Our XTRAN meta-code retrieves the values of the following environment variables, and assumes the indicated values:
Environment var | Description of value |
---|---|
Y2K_PLM_GBLNAM
|
Name of files containing global symbols that are known to be, or not to be, Y2K
problems. Must be a legal file name. File types .ysm and
.nsm added.
|
Y2K_PLM_MODNAM
|
Name of module we are analyzing. Must be a legal file name. File types
.ysm , .nsm , .msm , and .y2k
added.
|
Y2K_PLM_SYMPAT
|
Symbol name patterns (regular expressions) that mean "maybe", separated by commas (no spaces or TABs). |
Y2K_PLM_TXTPAT
|
Text patterns (regular expressions) in text literals to report, separated by commas (no spaces or TABs). |
Y2K_PLM_COMPAT
|
Text patterns (regular expressions) in comments to report, separated by commas (no spaces or TABs). |
In addition to reading in the "yes" and "no" files named by
Y2K_PLM_GBLNAM
, which must exist (but can be empty), our meta-code
also reads files named <mod>.ysm
and
<mod>.nsm
if they exist, where <mod>
is
the module named by Y2K_PLM_MODNAM
. These files contain
symbols local to the module we're analyzing that are known to be ("yes"), or
not to be ("no"), Y2K problems. They are typically produced by review of
the "maybe" file produced by previous analysis of this module.
Our meta-code produces a file named <mod>.msm
("maybe")
containing symbols occurring in the named module that may be Y2K problems (if
any).
Our meta-code also produces a file named <mod>.y2k
containing analysis output for the named module.
Each line of the "yes", "no", and "maybe" symbol files contains a fully
qualified symbol, optionally followed by ?
and an explanation of
why we are interested in the symbol (the meta-code always adds such an
explanation). Exception: Our meta-code regards any line starting
with ;
in these files as a comment, and ignores it.
Rules:
XTRAN's rules language, "meta-code", is proprietary and requires a Nondisclosure Agreement. However, the following is an English paraphrase of the meta-code used in this analysis. It is functionally equivalent to the actual meta-code used. NOTE that these rules are COPYRIGHT 2016 by XTRAN, LLC and may not be copied or used in any way without XTRAN, LLC's permission.
Read global "yes" and "no" symbol files Read module-specific "yes" and "no" symbol files if they exist Create an empty "maybe" symbol file for this module Create an analysis report file for this module For each PL/M symbol occurring in the module If it matches any of the given symbol regular expressions If it's not already in the "yes", "no", or "maybe" symbol lists Add it to "maybe" list, with explanation For each PL/M statement in the module (recursively) For each expression in the statement (recursively) If this is a text string If it matches any of the given text string regular expressions Report it to module's report file, with file name & line Else if this is a symbol If it is a known Y2K problem (in "yes" list) Report its occurrence to report file, with file name & line For each higher-level expression the symbol is in If higher-level expression is assignment or comparison For each term of higher-level expression (recursively) If term is assignment or comparison Ignore it; it's already been done on the way up Else if term is a symbol If symbol not in "yes", "no", "maybe" lists Add symbol to "maybe" list, with explanation For each of statement's comments If it matches any of the given comment regular expressions Report it to module's report file, with file name & line Close report file Write out "maybes" to module's "maybe" file Close "maybe" file
Example Procedure:
For this demonstration, we ran the analysis four times, until it produced no "maybe" symbols. After the 1st, 2nd, and 3rd runs, we reviewed the "maybes" and moved them to the appropriate "yes" and "no" symbol files.
Process Flowchart
Here is a flowchart for this process, in which the elements are color coded:
- BLUE for XTRAN versions (runnable programs)
- ORANGE for XTRAN rules (text files)
- RED for
code - PURPLE for text data files
Input and Output Files, by Run:
The following files were input to, or generated by, our XTRAN meta-code in the course of this example. See listings below for their contents if not empty.
File name | I/O? | Description |
---|---|---|
Run 1 | ||
demy2k-a.plm |
I | Code to be analyzed |
y2k-gbl.nsm |
I | Global symbol "no" file — empty |
y2k-gbl.ysm |
I | Global symbol "yes" file — empty |
demy2k-a.msm |
O | "Maybe" file |
demy2k-a.y2k |
O | Analysis report — ignored |
Run 2 | ||
demy2k-a.plm |
I | Code to be analyzed |
y2k-gbl.nsm |
I | Global symbol "no" file — still empty |
y2k-gbl.ysm |
I | Global symbol "yes" file — still empty |
demy2k-a.nsm |
I | Local symbol "no" file — edited from Run 1 "maybe" file |
demy2k-a.ysm |
I | Local symbol "yes" file — edited from Run 1 "maybe" file |
demy2k-a.msm |
O | Updated "maybe" file |
demy2k-a.y2k |
O | Analysis report — ignored |
Run 3 | ||
demy2k-a.plm |
I | Code to be analyzed |
y2k-gbl.nsm |
I | Global symbol "no" file — still empty |
y2k-gbl.ysm |
I | Global symbol "yes" file — edited from Run 2 "maybe" file |
demy2k-a.nsm |
I | Local symbol "no" file — updated from Run 2 "maybe" file |
demy2k-a.ysm |
I | Local symbol "yes" file — updated from Run 2 "maybe" file |
demy2k-a.msm |
O | Updated "maybe" file |
demy2k-a.y2k |
O | Analysis report — ignored |
Run 4 | ||
demy2k-a.plm |
I | Code to be analyzed |
y2k-gbl.nsm |
I | Global symbol "no" file — still empty |
y2k-gbl.ysm |
I | Global symbol "yes" file — edited from Run 3 "maybe" file |
demy2k-a.nsm |
I | Local symbol "no" file — updated from Run 3 "maybe" file |
demy2k-a.ysm |
I | Local symbol "yes" file — updated from Run 3 "maybe" file |
demy2k-a.msm |
O | Updated "maybe" file — empty! |
demy2k-a.y2k |
O | Analysis report — good! |
Final Results:
The file y2k-gbl.ysm
documents all global symbols so far that
are known to be Y2K problems.
The file y2k-gbl.nsm
documents all global symbols so far that
are known not to be Y2K problems.
The file demy2k-a.ysm
documents all symbols local to
demy2k-a.plm
that are known to be Y2K problems.
The file demy2k-a.nsm
documents all symbols local to
demy2k-a.plm
that are known not to be Y2K problems.
The file demy2k-a.y2k
documents all occurrences in
demy2k-a.plm
of:
- Y2K problem symbols, both global and local.
- Specified text patterns, in both text strings and comments.
Questions?
For any questions or comments concerning this example, please .
File listings:
demy2k-a.plm — PL/M code to be analyzed; line numbers added for reference
1 DECLARE base INTEGER EXTERNAL; /*base year (2 digits)*/ 2 3 func1: PROCEDURE (p_year_txt, yr_num, yr_no); 4 DECLARE p_year_txt POINTER; /*1st-rnd "maybe", 2nd-rnd "yes"*/ 5 DECLARE yr_num INTEGER; /*1st-rnd "maybe", 2nd-rnd "yes"*/ 6 DECLARE yr_no INTEGER; /*1st-rnd "maybe", 2nd-rnd "no"*/ 7 8 DECLARE p_txt POINTER; /*text pointer*/ 9 DECLARE (i, j, k, m) INTEGER; /*util vars*/ 10 11 i = yr_num; /*makes i a 2nd-rnd "maybe"*/ 12 p_txt = p_year_txt; /*makes p_txt a 2nd-rnd "maybe"*/ 13 IF yr_num > base THEN /*makes base a 2nd-rnd "maybe"*/ 14 j = i; 15 m = yr_no; /*asnmt, but from 2nd-rnd "no"*/ 16 END FUNC1;
demy2k-a.msm — "Maybe" file produced by run 1
; demy2k-a.msm -- Symbols that may be Year 2000 problems ; Created 1999-01-01.0726 ; module(demy2k-a.plm), proc(func1), space(vars): p_year_txt?Matched pattern "y[ae]*r" module(demy2k-a.plm), proc(func1), space(vars): yr_no?Matched pattern "y[ae]*r" module(demy2k-a.plm), proc(func1), space(vars): yr_num?Matched pattern "y[ae]*r"
demy2k-a.y2k — Analysis report produced by run 1; ignored
demy2k-a.y2k -- Year 2000 analysis of demy2k-a.plm Created 1999-01-01.0726 demy2k-a.plm(1): Comment may be about year: "base year (2 digits)"
demy2k-a.nsm — Local symbol "no" file input to run 2, from run 1's demy2k-a.msm
; demy2k-a.nsm -- Symbols that are known NOT to be Year 2000 problems ; Revised 1999-02-17.1252 by S. F. Heffner (Win95 on TP770ED @ (mobile)) ; ; This file contains symbols that were moved here from demy2k-a.msm when they ; were determined NOT to be Y2K problems. ; module(demy2k-a.plm), proc(func1), space(vars): yr_no?Matched pattern "y[ae]*r"
demy2k-a.ysm — Local symbol "yes" file input to run 2, from run 1's demy2k-a.msm
; demy2k-a.ysm -- Symbols that are known to be Year 2000 problems ; Revised 1999-01-01.0727 by S. F. Heffner (Win95 on TP770ED @ (mobile)) ; ; This file contains symbols that were moved here from demy2k-a.msm when they ; were determined to be Y2K problems. ; module(demy2k-a.plm), proc(func1), space(vars): p_year_txt?Matched pattern "y[ae]*r" module(demy2k-a.plm), proc(func1), space(vars): yr_num?Matched pattern "y[ae]*r"
demy2k-a.msm — "Maybe" file produced by run 2
; demy2k-a.msm -- Symbols that may be Year 2000 problems ; Created 1999-01-01.0729 ; module(demy2k-a.plm), proc(func1), space(vars): i?assigned in "i = yr_num" at demy2k-a.plm(11) module(demy2k-a.plm), proc(func1), space(vars): p_txt?assigned in "p_txt = p_year_txt" at demy2k-a.plm(12) space(vars): base?compared in "yr_num > base" at demy2k-a.plm(13)
demy2k-a.y2k — Analysis report produced by run 2; ignored
demy2k-a.y2k -- Year 2000 analysis of demy2k-a.plm Created 1999-01-01.0729 demy2k-a.plm(1): Comment may be about year: "base year (2 digits)" demy2k-a.plm(11): Problem symbol "yr_num" occurred demy2k-a.plm(12): Problem symbol "p_year_txt" occurred demy2k-a.plm(13): Problem symbol "yr_num" occurred
y2k-gbl.ysm — Global symbol "yes" file input to run 3; updated from run 2's demy2k-a.msm
; y2k-gbl.ysm -- Global "yes" symbols for analysis of demy2k-a.plm ; Revised 1999-01-01.0731 by S. F. Heffner (Win95 on TP770ED @ (mobile)) ; Written 1998-03-20 by S. F. Heffner (Win95 on TP760CD @ (Mobile)) ; ; COPYRIGHT 2016 by PENNINGTON SYSTEMS INCORPORATED; reproduction or use ; prohibited without permission. ; ; This file was originally empty. The current entries were transferred here ; after review of the "maybe" file produced by analysis of demy2k-a.plm. ; space(vars): base?compared in "yr_num > base" at demy2k-a.plm(13)
demy2k-a.nsm — Local symbol "no" file input to run 3; updated from run 2's demy2k-a.msm
; demy2k-a.nsm -- Symbols that are known NOT to be Year 2000 problems ; Revised 1999-01-01.0728 by S. F. Heffner (Win95 on TP770ED @ (mobile)) ; ; This file contains symbols that were moved here from demy2k-a.msm when they ; were determined NOT to be Y2K problems. ; module(demy2k-a.plm), proc(func1), space(vars): yr_no?Matched pattern "y[ae]*r"
demy2k-a.ysm — Local symbol "yes" file input to run 3; updated from run 2's demy2k-a.msm
; demy2k-a.ysm -- Symbols that are known to be Year 2000 problems ; Revised 1999-01-01.0730 by S. F. Heffner (Win95 on TP770ED @ (mobile)) ; ; This file contains symbols that were moved here from demy2k-a.msm when they ; were determined to be Y2K problems. ; module(demy2k-a.plm), proc(func1), space(vars): p_year_txt?Matched pattern "y[ae]*r" module(demy2k-a.plm), proc(func1), space(vars): yr_num?Matched pattern "y[ae]*r" module(demy2k-a.plm), proc(func1), space(vars): i?assigned in "i = yr_num" at demy2k-a.plm(11) module(demy2k-a.plm), proc(func1), space(vars): p_txt?assigned in "p_txt = p_year_txt" at demy2k-a.plm(12)
demy2k-a.msm — "Maybe" file produced by run32
; demy2k-a.msm -- Symbols that may be Year 2000 problems ; Created 1999-01-01.0731 ; module(demy2k-a.plm), proc(func1), space(vars): j?assigned in "j = i" at demy2k-a.plm(14)
demy2k-a.y2k — Analysis report produced by run 3; ignored
demy2k-a.y2k -- Year 2000 analysis of demy2k-a.plm Created 1999-01-01.0731 demy2k-a.plm(1): Comment may be about year: "base year (2 digits)" demy2k-a.plm(11): Problem symbol "i" occurred demy2k-a.plm(11): Problem symbol "yr_num" occurred demy2k-a.plm(12): Problem symbol "p_txt" occurred demy2k-a.plm(12): Problem symbol "p_year_txt" occurred demy2k-a.plm(13): Problem symbol "yr_num" occurred demy2k-a.plm(13): Problem symbol "base" occurred demy2k-a.plm(14): Problem symbol "i" occurred
y2k-gbl.ysm — Global symbol "yes" file input to run 4; updated from run 3's demy2k-a.msm
; y2k-gbl.ysm -- Global "yes" symbols for analysis of demy2k-a.plm ; Revised 1999-01-01.0731 by S. F. Heffner (Win95 on TP770ED @ (mobile)) ; Written 1998-03-20 by S. F. Heffner (Win95 on TP760CD @ (Mobile)) ; ; COPYRIGHT 2016 by PENNINGTON SYSTEMS INCORPORATED; reproduction or use ; prohibited without permission. ; ; This file was originally empty. The current entries were transferred here ; after review of the "maybe" file produced by analysis of demy2k-a.plm. ; space(vars): base?compared in "yr_num > base" at demy2k-a.plm(13)
demy2k-a.nsm — Local symbol "no" file input to run 4; updated from run 3's demy2k-a.msm
; demy2k-a.nsm -- Symbols that are known NOT to be Year 2000 problems ; Revised 1999-01-01.0728 by S. F. Heffner (Win95 on TP770ED @ (mobile)) ; ; This file contains symbols that were moved here from demy2k-a.msm when they ; were determined NOT to be Y2K problems. ; module(demy2k-a.plm), proc(func1), space(vars): yr_no?Matched pattern "y[ae]*r"
demy2k-a.ysm — Local symbol "yes" file input to run4; updated from run 3's demy2k-a.msm
; demy2k-a.ysm -- Symbols that are known to be Year 2000 problems ; Revised 1999-01-01.0732 by S. F. Heffner (Win95 on TP770ED @ (mobile)) ; ; This file contains symbols that were moved here from demy2k-a.msm when they ; were determined to be Y2K problems. ; module(demy2k-a.plm), proc(func1), space(vars): p_year_txt?Matched pattern "y[ae]*r" module(demy2k-a.plm), proc(func1), space(vars): yr_num?Matched pattern "y[ae]*r" module(demy2k-a.plm), proc(func1), space(vars): i?assigned in "i = yr_num" at demy2k-a.plm(11) module(demy2k-a.plm), proc(func1), space(vars): p_txt?assigned in "p_txt = p_year_txt" at demy2k-a.plm(12) module(demy2k-a.plm), proc(func1), space(vars): j?assigned in "j = i" at demy2k-a.plm(14)
demy2k-a.y2k — Analysis report produced by run 4; good!
demy2k-a.y2k -- Year 2000 analysis of demy2k-a.plm Created 1999-01-01.0733 demy2k-a.plm(1): Comment may be about year: "base year (2 digits)" demy2k-a.plm(11): Problem symbol "i" occurred demy2k-a.plm(11): Problem symbol "yr_num" occurred demy2k-a.plm(12): Problem symbol "p_txt" occurred demy2k-a.plm(12): Problem symbol "p_year_txt" occurred demy2k-a.plm(13): Problem symbol "yr_num" occurred demy2k-a.plm(13): Problem symbol "base" occurred demy2k-a.plm(14): Problem symbol "j" occurred demy2k-a.plm(14): Problem symbol "i" occurred