从COBOL到Java的方式:每天编写一个编译器

问候,亲爱的朋友们。


我们将继续一系列文章,涵盖非营利组织的(暴风雨)活动。


如所承诺的,我们从简单(记录)到更复杂:元编程。


领带


碰巧我们的母公司(一家大型金融技术公司)需要使用大型机和COBOL与另一个大型组织进行集成。


看起来-困难是什么?它会产生什么影响?


事实是,作为该集成中的从属,我们必须从外部支持数据交换接口。即-二进制数据文件“ COBOL数据文件”。


事实证明(以前我们没有使用过COBOL的经验),其中的数据文件具有非线性结构即:


  • 一个相同的数据块可以解释为不同的“组”(COBOL术语中的数据格式),这是一种数据多态性:伪指令redefines此外,还有所有嵌套组及其字段。
  • 一个块可以重复N次:指令 occurs
  • 块按顺序进行,但是它们的开始从上一个块的结尾开始计数-因此,您必须先读取前一个块,才能读取单独的块。

文件规范表示COBOL可执行源代码“ copybook”(在“数据节”中)以及用于描述数据格式的所有可能的语法选项,这使所有这些情况变得复杂,例如:


PIC X(06)V99

要么


 PIC 9(06).9999999

要么


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

添加到此:


  • 棘手的二进制格式,用于存储IBM计算3数字
  • 不同的编码(EBCDIC,ASCII)-甚至对于一种类型的文件(在Test和Prod上)
  • 各种换行符(CR,LF,CRLF,LFCR,换行符,在N个字节后隐含)
  • 包含400个条目的大量字帖,带有一堆字段
  • Copbooks具有标题,记录,尾部及其组合的结构

而这一切都已经成为一个真正的问题:如何支持它?


我们首先研究现有的解决方案。结果简直是灾难性的:免费解决方案中只有90年代的JRecord。


, — , - . , 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