COBOL Migration to Java or .NET

Migrating COBOL to new languages such as Java or .Net promises three nice properties: 1) removing the stranglehold of the legacy hardware and the cost of the lease/licensing costs, 2) making the application more maintainable, and 3) providing the organization with access to more easily found software engineers.

The first concern is, What will translated code look like? Weak translators convert code blindly line-by-line, with virtually no understanding of how the context of the code should shape its translation. Such translated code preserves the properties of the original COBOL, sometime the point of even preserving the syntax. Even if such code works, it not be maintainable and will ultimately cost the organization sorely. (You can see here the results of weak translator, not from SD, to compare to the results you see on this page).

Semantic Designs translators parse the original code with tools that have the same understanding as the original compilers; (for example, see our COBOL Front End). SD tools know the types of variables, where and how they are used ("the context"), and can thus produce extremely good translations. Because SD also customizes the tools to the specific needs of the customer, the code reflects those needs properly.

A COBOL to C# translation

Here we show you a small sample of COBOL translated by SD's tools to C#. (We can do the same for Java.)

A simple COBOL program

We have chosen to provide a small COBOL program to prevent the reader from being overwhelmed with an 8000 line example.

	IDENTIFICATION DIVISION.
	PROGRAM-ID. EXAMPLE.

	DATA DIVISION.
	WORKING-STORAGE SECTION.
	01 COMPANY.
	   05 COMPANY-NAME PIC X(60) VALUE "Semantic Designs".
	   05 COMPANY-ADDRESS.
	      10 STREET PIC X(80) VALUE "13171 Pond Springs Rd.".
	      10 CITY.
		 15 CITY-NAME PIC X(40) VALUE "Austin".
		 15 FILLER PIC XX VALUE ", ".
		 15 CITY-STATE PIC XX VALUE "TX".
	         15 ZIP.
	            20 ZIP-5  PIC 9(5) VALUE 78729.
	            20 FILLER PIC X    VALUE "-".
	            20 ZIP-E4 PIC 9(4) VALUE 7102.
	01 LINE-ITEM.
	   05 ITEM PIC X(20)     VALUE "Item Description".
	   05 AMOUNT PIC 999     VALUE 217.
	   05 PRICE  PIC 9999V99 VALUE 24.95.

	77 TOTAL-AMOUNT PIC 999999V99.
	77 DISCOUNT-THRESHOLD PIC 999999V99 VALUE 1111.11.
	77 DISCOUNT-PERCENT   PIC 99 VALUE 20.
	77 DISCOUNT-AMOUNT    PIC 99999999V99.

	PROCEDURE DIVISION.
	PERFORM-TASK.
	  PERFORM COMPUTE-TOTAL.
	  PERFORM DISPLAY-TOTAL.
	  STOP RUN.
	COMPUTE-TOTAL.
	  MULTIPLY AMOUNT BY PRICE GIVING TOTAL-AMOUNT.
	  IF TOTAL-AMOUNT > DISCOUNT-THRESHOLD
	    MULTIPLY TOTAL-AMOUNT BY DISCOUNT-PERCENT
	      GIVING DISCOUNT-AMOUNT
	    DIVIDE 100 INTO DISCOUNT-AMOUNT
	    SUBTRACT DISCOUNT-AMOUNT FROM TOTAL-AMOUNT.
	DISPLAY-TOTAL.
	  DISPLAY COMPANY-NAME.
	  DISPLAY "Total: ", TOTAL-AMOUNT.

COBOL program automatically translated to C#

One should note that the translator has chosen data types compatible with their declaration in the original program, but with a different representation better suited for C#. Note that paragraphs have been converted to methods, which provides a clean way to translate PERFORM A THRU B.

This output is reproduced exactly as the translator generated it.

class Example
{
    public class CompanyType
    {
        public char[] CompanyName = "Semantic Designs".PadRight(60).ToCharArray();

        public class CompanyAddressType
        {
            public char[] Street = "13171 Pond Springs Rd.".PadRight(80).ToCharArray();

            public class CityType
            {
                public char[] CityName = "Austin".PadRight(40).ToCharArray();

                public char[] CityState = "TX".ToCharArray();

                public class ZipType
                {
                    public uint Zip5 = 78729;

                    public ushort ZipE4 = 7102;

                }

                public ZipType Zip = new ZipType();

            }

            public CityType City = new CityType();

        }

        public CompanyAddressType CompanyAddress = new CompanyAddressType();

    }

    public CompanyType Company = new CompanyType();

    public class LineItemType
    {
        public char[] Item = "Item Description".PadRight(20).ToCharArray();

        public ushort Amount = 217;

        public decimal Price = 24.95M;

    }

    public LineItemType LineItem = new LineItemType();

    public decimal TotalAmount;

    public decimal DiscountThreshold = 1111.11M;

    public byte DiscountPercent = 20;

    public decimal DiscountAmount;

    void PerformTask()
    {
        ComputeTotal();
        DisplayTotal();
        System.Environment.Exit(0);
    }

    void ComputeTotal()
    {
        TotalAmount = LineItem.Amount * LineItem.Price;
        if (TotalAmount > DiscountThreshold)
        {
            DiscountAmount = TotalAmount * DiscountPercent;
            DiscountAmount /= 100;
            TotalAmount -= DiscountAmount;
        }
    }

    void DisplayTotal()
    {
        System.Console.WriteLine(Company.CompanyName);
        System.Console.Write("Total: ");
        System.Console.Write(TotalAmount);
        System.Console.WriteLine();
    }

    static void Main()
    {
        new Example().PerformTask();
    }

}

So one can get good code from a translator, if one has the right foundation technology such as SD's DMS Software Reengineering Tookit®. As a practical matter, you can't get it off the shelf, because every application system has unique properties: languages, OS features, scripting languages, screens, databases, and a correspondingly unique target as decided by the client. So it takes some effort to configure DMS for the client's particular source and target software configurations.

Semantic Designs can provide that configuration, providing customized tools and migration support to your organization, providing high quality, maintainable code translations.

For more information: Info@semanticdesigns.com    Follow us at Twitter: @SemanticDesigns

COBOL
Migration