The way from COBOL to Java: writing a transpiler per day

Greetings, Dear Friends.


We continue the series of articles covering the activities of the (stormy) of our nonprofit organization.


As promised, we move from simple (logging) to more complex: metaprogramming.


Tie


It so happened that our parent corporation (a large financial tech) needed to integrate with another large organization using mainframes and COBOL.


It would seem - what is the difficulty, and what can it affect?


The fact is that being a slave in this integration, we had to support data exchange interfaces from the outside. Namely - binary data files "COBOL data files".


As it turned out (and we had no experience with COBOL before), the data files in it have a non-linear structure . Namely:


  • One and the same data block can be interpreted as different β€œgroups” (data format in COBOL terminology), a kind of data polymorphism: directive redefines. Moreover, with all nested groups and their fields.
  • A block can be repeated N times: directive occurs
  • Blocks go sequentially, but their beginning is counted from the end of the previous block - accordingly, you cannot read a separate block without reading the previous blocks.

, COBOL: "copybook" ( Data Section Division), , :


PIC X(06)V99


 PIC 9(06).9999999


PIC 9(07)V9(07) COMP-3

:


  • IBM Computational 3
  • (EBCDIC, ASCII) β€” ( )
  • (CR, LF, CRLF, LFCR, Newline, N )
  • 400
  • header, record, trailer

: ?


, . : JRecord 90.


, β€” , - . , data picture comp-3 .


, 2 :


  • hold my coffee

, . β€” β€” :


  • COBOL Java (Groovy)

, ? β€” 1 .



- , :


  • ( )

COBOL β€” Data Section Division. , COBOL.


, -, COBOL ( Java) β€” MIT:
https://github.com/uwol/proleap-cobol-parser


, :


  • Java (Groovy)
  • API, (ETL)

Antlr, meta-API Visitor. -.


visit e , Groovy , (data picture clause):


    @Override
    @CompileDynamic
    Boolean visitDataPictureClause(CobolParser.DataPictureClauseContext ctx) {
        PictureClause entry = (PictureClause) program.getASGElementRegistry().getASGElement(ctx)
        def (length, comp3length, scale) = calculateLengths(entry.pictureString)
        write """    setDataPicture("""
        write """        depth: ${currentFrame.depth},"""
        write """        pictureString: "${entry.pictureString}","""
        write """        length: ${length},"""
        write """        comp3length: ${comp3length},"""
        write """        scale: ${scale},"""
        Boolean result = super.visitDataPictureClause(ctx)
        write """    )"""
        return result
    }

, COBOL Groovy.
, copybook.
Java , .


Closure Groovy β€” Closure COBOL.


, COBOL (copybook):


000010 IDENTIFICATION  DIVISION.                                        XXXXXXXX
       PROGRAM-ID.     UnstringSample.                                  XXXXXXXX
       ENVIRONMENT     DIVISION.                                        XXXXXXXX
       CONFIGURATION SECTION.                                           XXXXXXXX
       SPECIAL-NAMES.   DECIMAL-POINT IS COMMA.                         XXXXXXXX
       INPUT-OUTPUT    SECTION.                                         XXXXXXXX
       DATA            DIVISION.                                        XXXXXXXX
       WORKING-STORAGE SECTION.                                         XXXXXXXX
       01 ABCDE-RECORD.                                                 XXXXXXXX
XXXXXX  02 ABCDE-REC.                                                   XXXXXXXX
        03 ABCDE-COMMON.                                                XXXXXXXX
           05 ABCDE-DETAILS.                                            XXXXXXXX
             10 ABCDE-RECORD-ABC.                                       XXXXXXXX
                15 ABCDE-PRI-ABC.                                       XXXXXXXX
                   20 ABCDE-ABC-AAAAAAAA         PIC X(02).             XXXXXXXX
                   20 ABCDE-ABC-ACCT-ABCS.                              XXXXXXXX
                      25 ABCDE-ABC-ABC-1         PIC X(02).             XXXXXXXX
                      25 ABCDE-ABC-ABC-2         PIC X(03).             XXXXXXXX
                      25 ABCDE-ABC-ABC-3         PIC X(03).             XXXXXXXX
                      25 ABCDE-ABC-ABC-4         PIC X(04).             XXXXXXXX

:


io.infinite.cobol.CobolCompiler|import groovy.transform.CompileStatic
import io.infinite.cobol.CobolRuntime
import io.infinite.cobol.CobolApi
import io.infinite.other.CopybookStructureEnum

@CompileStatic
class CobolClosureRuntime extends CobolRuntime {

    @Override
    void run(Long totalSize, InputStream inputStream, String charsetName, List<Byte> lineBreakBytes, CobolApi cobolApi, CopybookStructureEnum copybookStructure) {
        super.setup(totalSize, inputStream, charsetName, lineBreakBytes, cobolApi, copybookStructure)
readFile() {
    createRecord("ABCDE-RECORD") {
        createGroup(2, "ABCDE-REC") {
            createGroup(3, "ABCDE-COMMON") {
                createGroup(4, "ABCDE-DETAILS") {
                    createGroup(5, "ABCDE-RECORD-ABC") {
                        createGroup(6, "ABCDE-PRI-ABC") {
                            createGroup(7, "ABCDE-ABC-AAAAAAAA") {
                                setDataPicture(
                                    depth: 7,
                                    pictureString: "X(02)",
                                    length: 2,
                                    comp3length: 2,
                                    scale: 0,
                                )
                            }//<(end of group: ABCDE-ABC-AAAAAAAA)
                            createGroup(7, "ABCDE-ABC-ACCT-ABCS") {
                                createGroup(8, "ABCDE-ABC-ABC-1") {
                                    setDataPicture(
                                        depth: 8,
                                        pictureString: "X(02)",
                                        length: 2,
                                        comp3length: 2,
                                        scale: 0,
                                    )
                                }//<(end of group: ABCDE-ABC-ABC-1)
                                createGroup(8, "ABCDE-ABC-ABC-2") {
                                    setDataPicture(
                                        depth: 8,
                                        pictureString: "X(03)",
                                        length: 3,
                                        comp3length: 2,
                                        scale: 0,
                                    )
                                }//<(end of group: ABCDE-ABC-ABC-2)
                                createGroup(8, "ABCDE-ABC-ABC-3") {
                                    setDataPicture(
                                        depth: 8,
                                        pictureString: "X(03)",
                                        length: 3,
                                        comp3length: 2,
                                        scale: 0,
                                    )
                                }//<(end of group: ABCDE-ABC-ABC-3)
                                createGroup(8, "ABCDE-ABC-ABC-4") {
                                    setDataPicture(
                                        depth: 8,
                                        pictureString: "X(04)",
                                        length: 4,
                                        comp3length: 3,
                                        scale: 0,
                                    )
                                }//<<<<(end of group: ABCDE-ABC-ABC-4)
                            }//<<<<(end of group: ABCDE-ABC-ACCT-ABCS)
                        }//<<<<(end of group: ABCDE-PRI-ABC)
                    }//<<<<(end of group: ABCDE-RECORD-ABC)
                }//<<<<(end of group: ABCDE-DETAILS)
            }//<<<<(end of group: ABCDE-COMMON)
        }//<<<<(end of group: ABCDE-REC)
    }//<<<<(end of group: ABCDE-RECORD)
}//<<<<<

    }

}


, Production .


β€” , . β€” copybook β€” .


.
$.


:


  • Open Source COBOL Java (Groovy)
  • COBOL (proleap.io)
  • COMP-3
  • Data Section Division
  • redefines
  • occurs
  • API, XML ( )
  • (EBCDIC, ASCII )


1)
2) β€” , . .
3) , " ". 2020 .


https://i-t.io , . -, .


.


!


:
https://github.com/INFINITE-TECHNOLOGY/COBOL


All Articles