Proparse-Based Utilities

This project gathers various utilities related to parsing code. This includes tools for viewing or converting Proparse's syntax tree, utilities for find and report, utilities for search and replace, etc.


File References

This little 4gl script (two .p files and one .i file) uses Proparse to build temp-tables of file references (for RUN and for include). What you do with those temp-tables is entirely up to you.

Thanks Greg Wutzke for commissioning this effort. It was built for a project where source files were being moved and renamed as part of a code cleanup effort. For each file being moved or renamed, all code references to the file needed to be examined.

See the comments at the top of filerefs.p for notes about configuring and running the script.


PRO/Dox

PRO/Dox by Gordon Campbell takes AutoDox in two whole new directions. First, it generates XML instead of HTML, so that documentation can more easily be rendered in other formats (Word, PDF, etc). Second, it generates wire-frame diagrams of the frames it finds in your source code!

Download

See "Attachments" below.

Support

Standard disclaimers apply. This product is provided "as is"; there is no warranty expressed or implied. If you intend to run this product on a computer that manages first-strike missile systems, please review the source code first. Many thanks to Gordon Campbell and P2 Energy Solutions making PRO/Dox available. These tools were built for P2's own projects, and contributed in the hopes that you might find them useful. Please keep in mind that "contributed" does not imply "supported".

Revision History

Version 01, 20 Apr 2006: Gordon Campbell's initial release.


Getting Started

Getting Started

You will need to change the appropriate preprocessor (Fly) in prodox.cfg to point to the correct location of the Fly executable. The other preprocessors are basically for allowing control of the colouring and text sizing etc for the widgets. You don't really need to change those but the option is available. Prodox.p - the main input screen which then calls prodox2.p
Prodox2.p - the main procedure parser which also calls prodox3.p
Prodox3.p - the frame parser and image builder routine
Prodox.cfg - include file for preprocessor declaration of configuration options


Motivation

Motivation

I had to ask - why exactly are these images useful? I should have known the answer. How many times have you seen a project launched where, as the first step of the project, someone was told to take a screenshot of every window and write technical documentation for them all? I've seen it happen quite a few times. The worst part of a task like that is: How do you know that you managed to find every window in the system? Many windows and dialogs only appear under certain obscure conditions in the application logic. Gordon wrote: "The idea of the frame data and images is to use it as the start of a base technical document. I'll use the XML file to generate a Word document with all the info contained .. including the images etc ... then a Business Analyst will go through and add business documentation. Basically, we have no documentation to speak of and this is a way of getting a fairly good start ... so not only will it aid the developer but it will also aid the BA. Also, it's useful for those legacy apps where they can't be loaded into AppBuilder --- this makes it way easier to identify which field is actually used in which frame. Should reduce maintenance costs." Judy had a good point too. Users of an application may be familiar with the data on the screen, but unfamiliar with the database schema. If they want to use tools like Crystal for generating reports, they have a tough time matching screen data to database schema. I suspect that Gordon's work could easily be extended to provide exactly what the report-writing application users need.


Pictures

Pictures

Here is a screenshot of a window, along with the PRO/Dox generated wire-frame diagrams.

PRO/Dox Screenshot 1PRO/Dox Screenshot 1

PRO/Dox Wireframe 1PRO/Dox Wireframe 1

PRO/Dox Wireframe 2PRO/Dox Wireframe 2


Requirements

Requirements

 

  • Proparse
  • Progress 4GL Development (v9 or higher)
  • fly for image generation

 


Proparse Browser

This is a nifty utility contributed by Allan Doane for running and visualizing ad-hoc search/queries on a compile unit.

proparsebrowse.w
proparsetokentypes.txt

Proparse Browser screenshot

Revision History
Version 002, 16 Sep 2003: John Green added option for subquery (filter) to be based on either strictly a direct child node, or else on any descendant (grandchildren) nodes.


Proparse To XML

This is another contribution from Allan Doane (QAD). This utility reads from Proparse to generates an XML representation of the syntax tree for the program that was last parsed. Thanks Allan!

proparseToXML.p
runProparseXMLer.p

People using this utility might also be interested in a nice, free XML visualization tool that I found here: Mindfusion XML Viewer.

Revision History
Version 001, July 15, 2004: Contribution from Allan Doane.


Proparse Treeview

Thanks very much to Carl Verbiest for his permission to post this useful tree visualization utility that he built.

treeview.zip

Proparse TreeviewProparse Treeview

Revision History
April 12, 2005: First post.


Retired (historical) pages

Parent page for retired (no longer used) Codeparse pages.


AutoDox

AutoDox is an automated code documentor which uses Proparse to find significant features in your programs and then output details of these features in HTML documents. Some features so far reported in the generated documents are a program's parameters, internal procedures and functions, as well as comments where possible.

For download, see the attachments below.

The zip file named "s2000docs" is example output generated from Progress's "Sports 2000" sample application.

Contact Project Admin

Retired

2010: No longer active. See www.joanju.com for AutoDox2.


AutoDox Readme file

AutoDox Readme

AutoDox is intended to promote code reuse by documenting key programs,
including their parameters, internal procedures, and functions.
One specific purpose is to use this product to generate documentation
for your persistent procedures, so that all developers, particularly those
who are learning your software application, will be able to easily look
up key features of the most important programs to be reused.

AutoDox documents all of the procedures and functions in your programs,
including those found in include files.
Because Proparse does its own preprocessing, AutoDox works as if working
with preprocessed source, rather than with raw, un-preprocessed source.

Future Directions

AutoDox is an open-source project, and as such, contributions are welcome.
This section describes some of the things that we will do...
if nobody else does them first. :-)
Most urgently: AutoDox must be made accessible and customizable.

Accessible

Currently, AutoDox takes a list of programs to document,
and generates detail pages, the table of contents, the index frame, and
the summary page, all in one pass. This does not make it easy to regenerate
the detail page for a single compile unit, nor does it make it easy to
add a single new program to the documentation set.

Customizable

The AutoDox code is mostly one large program file.
It must be restructured so that individual bits of it can be
over-ridden, without making it difficult to accept new versions
of AutoDox.

We recognize that the easiest way to do this would be with V9 features,
but we feel that there are still enough people on 8.3
that it is important to to find another way.
Perhaps we could structure things so that the core code can be
over-ridden, using V9 features, but the core code still works with 8.3?

Methods from Include Files

AutoDox currently shows all methods and all functions,
even those which come from include files.
It would be good to be able to specify include files which are
commonly used, whose methods should only be documented once in a
separate details page.
The include file would then be documented more like a distinct "method library".
The programs which reference that include would then just have a link from
their page to the include's page.


Instructions

  • Unzip autodox.zip into a directory in your propath. It will unzip into a directory
    called "autodox".
  • Build a list of the names of the programs (.w, .p, etc.) that you want to document.
    The filenames that you put into this fileList are the ones that are
    used in the resulting HTML, and should be absolute references.
    Put one program name per line. Lines can be commented out by inserting
    lines containing nothing but open comment (/*) and closing comment (*/).
  • Run AutoDox from somewhere in your propath, for example
    "RUN autodox/autodox.p (INPUT "yourDirectory/yourFileList.txt")."
  • You'll enter your required HTML output directory, and your application's name.
  • Open the resulting HTML file "index.html" in your output directory to view
    your generated documentation.

As needed, identification of other significant code structures can be added
to autodox/autodox2.p and thus to the resulting documentation. These may perhaps
include definition of global variables, external procedure RUN statements, etc.


Generated HTML Files

This program generates the following set of .html files containing the documentation:


  • index.html: main document with links to the summary and a table of contents.

  • toc.html: a table of contents listing all of the program names only.

  • summary.html: a summary page listing all of the programs
    with a one-line description.

  • detail<n>.html: one detail page per program,
    with the significant features listed.






Customizing AutoDox For Your Application

AutoDox may be customized as necessary to tailor the result to your application. The following
sections will help with this. See also the Future Directions section above.


AutoDox HTML Notes

Since autodox/autodox2.p generates HTML which will then be analyzed and displayed by
your web browser, please note the following:

  • to make your HTML appear properly in your web browser, put a ‘<BR>’ in
    your PUT UNFORMATTEDs in this program wherever you want a newline in your web page
    as viewed from your web browser. It is very important that you use the single quotes
    above in the program - see autodox/autodox2.p for examples.
  • to make your HTML more readable, put a ‘~n’ in your PUT UNFORMATTEDs in
    this program wherever you want a newline in your HTML. These won't affect how
    your finished pages look when viewed by your browser. Remember to use the single quotes too.
  • use single quotes around your HTML in your PUT UNFORMATTEDs, but use double
    quotes inside these single quotes wherever you need a double quote to be
    in the resulting HTML.

Working with the Parse Tree

AutoDox uses Proparse to generate a parse tree of your program,
then does various manipulations
through this tree (using the Proparse API)
to gather the data for the HTML documentation.
For more information about working with parse trees and using the Proparse API,
see your Proparse Documentation.

Looking for Comments

Points to note when looking for your program's comments and white space when working with
the Proparse-generated parse tree:

  • comments are stored in hidden tokens with a type of "COMMENT"
  • white space is stored in hidden tokens with a type of "WS", and is contiguous
    (a block of white space may contain line feeds and therefore extend over many
    lines, from one real text node or comment token to the next real text node or
    comment token).
  • depending on your code conventions, you may put the comment for a statement
    before the statement, or after the statement.
    An example:

     
      /* This is a comment BEFORE the x statement. */
      DEFINE VARIABLE x AS INTEGER NO-UNDO. 
    
      DEFINE VARIABLE y AS INTEGER NO-UNDO. /* This is a comment AFTER the y statement. */
      

    If these two statements existed in your code, there would also be a further hidden
    token between them, of type "WS", and containing the line feed after the first
    " NO-UNDO.", plus any spaces and the line feed on the line between the two
    define statements. Therefore, the one hidden WS token would span all of the "empty
    space" between the PERIOD of the first DEFINE statement and the beginning DEFINE of
    the next one.

  • you could find this white space by either looking up the parserHiddenGetAfter() token
    after the . (PERIOD) node at the end of the first statement, or you could find it
    by looking for the parserHiddenGetBefore() token before the second DEFINE node.

autodox/autodox2.p contains two internal procedures for finding comments,
called getCommentBefore and getCommentAfter.

Configuration Parameters

The following configuration parameters in autodox/autodox.p are used to change where
AutoDox will look for your comments. Unfortunately, using a generalization like this
will miss certain comments in your code unless your code is incredibly consistently
commented. For example, it is fairly common that when programmers comment variable
definitions, they will put the comment to the right ("after") the DEFINE statement
if it is a short comment, and put it on the line above ("before") the DEFINE
statement if it is a long comment. Only one of these at a time can be meaningfully picked up
by AutoDox, so it is best to configure AutoDox to aim for the majority of cases
based on your own code.

Internal Procedure Comments

Use setProcCommentLoc = TRUE (before) to look for a comment before the procedure
statement, actually immediately before the PROCEDURE node itself,
for example when your code looks like this:

  /* comment for myProc */
  PROCEDURE myProc:   ...

Use setProcCommentLoc = FALSE (after) to look for a comment after the procedure statement,
more specifically after the COLON (LEXCOLON) or PERIOD terminating your
PROCEDURE statement, for example when your code looks like this:

  PROCEDURE myProc.     /* the comment I'm looking for */ 
    /* rest of myProc */
  END PROCEDURE.
or: 
  PROCEDURE myExtProc EXTERNAL "myProc.dll":   /* the comment I'm looking for */ 
    /* rest of myExtProc */
  END PROCEDURE.

Function Comments

Use setFuncCommentLoc = TRUE (before) to look for a comment before the function
statement, actually immediately before the FUNCTION node itself,
for example when your code looks like this:

  /* comment for myFunc */
  FUNCTION myFunc:   ...

Use setFuncCommentLoc = FALSE (after) to look for a comment after the function statement,
more specifically after the COLON (LEXCOLON) or PERIOD terminating your
FUNCTION statement, for example when your code looks like this:

  FUNCTION myFunc RETURNS LOGICAL FORWARD.   /* the comment I'm looking for */ 
or: 
  FUNCTION myFunc RETURNS LOGICAL:           /* the comment I'm looking for */ 
    /* rest of myFunc */
  END FUNCTION.

Parameter Comments

Use setParamCommentLoc = TRUE (before) to look for a comment before the DEFINE
PARAMETER statement, actually immediately before the DEFINE node itself,
for example when your code looks like this:

  /* comment for myParam */
  DEFINE INPUT PARAMETER myParam AS CHARACTER NO-UNDO. 

Use setParamCommentLoc = FALSE (after) to look for a comment after the DEFINE PARAMETER
statement, more specifically after the PERIOD terminating
your DEFINE statement, for example when your code looks like this:

  DEFINE INPUT PARAMETER myParam AS CHARACTER NO-UNDO.   /* the comment I'm looking for */ 

Note: for parameter comments after the DEFINE statement, it is best to only
accept comments that are on the same line as the DEFINE statement. Otherwise, you may
pick up a comment after your DEFINE and before the next DEFINE statement, but that
belongs to the next DEFINE statement. For example, with this code you could accidentally pick up
the comment for myParam3 when you are really looking for the comment AFTER myParam2,
which doesn't exist:

  DEFINE INPUT PARAMETER myParam1 AS CHARACTER NO-UNDO.   /* the comment for myParam1 */ 
  DEFINE INPUT PARAMETER myParam2 AS CHARACTER NO-UNDO.   

  /* the comment for myParam3, in a BEFORE position. */ 
  DEFINE INPUT PARAMETER myParam3 AS CHARACTER NO-UNDO.   

See autodox/autodox2.p internal procedure getCommentAfter for an example of checking
that your comments are on the same line.

Finding the First Comment in a Program

This is the first step in documenting a program. See autodox/autodox2.p Step 1.
(internal procedure getProcComment).

To find the first comment in a program, (hopefully a description of the program!),
start at the topmost node, the Program_root node. This is a synthetic node (didn't
exist in the original program, but exists for working with the parse tree).
In a loop, do a parserNodeFirstChild of this synthetic Program_root node (and its' children's
children as needed) until you find a real node instead of a synthetic node. Real
nodes are the nodes for which parserGetNodeText() will return true. They have text
because they existed in the original program text.

Then, from this first real node,
work backwards through any hidden tokens linked to it (only real nodes will have
hidden text, i.e. comments and whitespace, linked to them) by doing a
parserHiddenGetBefore(), then as many parserHiddenGetPrevious() calls as necessary
and discarding any hidden nodes that are not parserHiddenGetType() = "COMMENT".
When you run out of hidden nodes linked to the beginning of the real node ("before"
the real node), the last (uppermost) hidden "COMMENT" node you found will be the
first comment appearing in the original program text. You may need more than this
one node depending on the commenting convention in your programs, for example if you
have each comment line as its' own comment (one /* */ pair on each line).

Hidden node examples:

  /* This is all 
   * one hidden comment
   * token, with line 
   * feeds 
   * and all */
  
  /* This is a hidden token on its' own (of parserHiddenGetType() = "COMMENT") */
  /* and this is another separate hidden comment token. */

(These last two hidden comment tokens are actually separated by a line feed, which is
in yet another hidden token, of parserHiddenGetType() = "WS".)


Contributed "V2"

Murray Herman submitted this new version/variant of AutoDox. He did a bunch of work to make the output look more like javadoc, which was a requirement for a project he was working on. I haven't had a chance to have a look at it, but if you are interested in generating output similar to javadoc, his version will probably be useful to you.

autodox_muz.zip


GUI BoM

Gooey bomb?!

This project is for building a Bill of Materials of frames and widgets. Such a BoM may have many uses, but the immediate goal is for assistance in conversion of existing ABL to use new .Net UI.

The GuiBom is composed of lists of frames, fields, and widgets in a given compile unit, as well as their attributes and links to nodes in the syntax tree where the frames and widgets are referenced. A proof of concept script has already accomplished much of this. The BoM goals appear to be straightforward to achieve by using the new version of Proparse.

That sums up the first part of the project, where Proparse plays the key role. The next part of the project, well, I'd better leave that up to Julian to describe. :)


Groovy script download

This Groovy script was the original prototype, proof of concept. It generates lots of useful XML, but we decided rather than go from Proparse+Groovy through XML into ABL programs, it would be better to work on the new Proparse ABL API so that we are working with Proparse+ABL right off the bat.

Download the zip file (attached below), unzipping creates a directory called 'guibom'.

Download proparse.jar and put it in that guibom directory.

Get and configure Groovy (especially the CLASSPATH), see /proparse/scripting.

Then run the script:

groovy src\GuiBom.groovy

IncludePath

2006 by Carl Verbiest, CCE NV

Scans the source, looks for includes and adds the path (relative to src) to the include name.

This is a clever use of Proparse's "scanner" feature combined with the use of the propath SEARCH function, in order to add relative paths to include file names. This is useful for cleaning up code that depended on each include file directory being on the propath. The goal is to reduce the number of entries on the propath. Thanks Carl!

includepath.p

Revision History
19 Mar 2006: First posted.


Proparse Java/SWT tree view

This is an example of using Proparse from Java. It is self contained with Java source and the JNI DLL necessary for loading Proparse from Java.

It contains a "ProparseLdr" class to make it easy to interface with Proparse.dll, and a "Node" class to make it easy to work with nodes in Proparse's syntax tree.

It also contains an SWT example (SWT is the widget toolkit from eclipse.org) of browsing Proparse's syntax tree:

Proparse tree browser in SWTProparse tree browser in SWT

Version 02, 13 Sep 2004: Added the ability to configure Proparse via an optional "proparse.config" file. See TreeView.java and ProparseUtil.java.

See "Attachments" below for download.


ProStyle

The ProStyle project uses various features from Proparse in order to pretty-print P4GL/ABL.

See "Attachments" below for download.

27 Mar 2006: ProStyle 001 zip file made available for download.

Browse with WebSVN

Example Subversion repository access:

svn checkout svn://oehive.org/prostyle/trunk

Examples

This example is from Gordon Campbell, who provided the support for PDF output. Note in the PDF output how the blocks are highlighted. Very nice!

The original code was machine-generated, and difficult to read. The reformatted new .p is easier to read, and the PDF adds the nice block highlighting.

prtm001.p
prtm001new.p
prtm001new.p.pdf