Copybook 解析器参考文档

Mainframe Connector 使用基于 ANTLR4 的解析器,该解析器支持标准 COBOL 副本。

本文档列出了 copybook 解析器执行的预处理任务、支持的数据类型和使用限制,以及如何使用 qsam decode 和 qsam encode 命令通过转码器配置来配置字段修饰符。

预处理

在解析 copybook 之前,copybook 解析器会预处理数据并执行以下步骤:

  • 移除注释行(第 7 列中的 *,或内嵌 *> 和 *>CE 注释)。
  • 解析续行(第 7 列中的 -,后跟带引号的字面量)。
  • 清空序列号区域(第 1-6 列)以及第 73 列及后续列。 代码必须从第 8 列或更靠后的列开始。
  • 保留预处理器专用语句,例如 EJECT、SKIP1、SKIP2、SKIP3 和 TITLE。这些语句会被解析,但会被忽略。Copybook 解析器不支持包含可供 COPY REPLACING 使用的预处理器参数的 Copybook。在这些 copybook 中,标识符用英文冒号 (:) 括起来。

支持的数据类型和限制

以下是 copybook 解析器支持的数据类型及其使用限制:

  • 一个 copybook 中只允许有一个顶级 01 记录,并且 01 记录不能有 OCCURS 子句。
  • 不支持级别 66(RENAMES/别名)和级别 77(独立)字段。系统会解析并忽略第 88 级(条件名称)。
  • 除十六进制浮点字段(COMP-1 和 COMP-2)外,所有基本(非组)字段都必须具有 PICTURE 子句。支持以下 PICTURE 字段:
    • 字母 (PIC A)、字母数字 (PIC X) 和字母数字编辑 (A、X、9、B、0、/)。
    • PIC G(DBCS;需要 USAGE DISPLAY-1)。
    • PIC N(本地或 DBCS)和本地编辑(N、B、0、/)。
    • PIC U (UTF-8),包括 PIC U BYTE-LENGTH n。
    • 数字(9、S、V)和数字编辑($、B、/、V、Z、0、9、,、.、*、+、-、CR、DB)。请注意,不支持 PIC P(伸缩位置)。
    • 精度最高为 18 的区位十进制和压缩十进制字段会被解码为 64 位类型(LONG 或 DECIMAL64),而更高精度的字段会被解码为任意精度类型(BIG_INTEGER 或 BIG_DECIMAL)。当 schema_validation_mode 设置为 BIG_QUERY 时,支持的最大精度为 76 (BIGNUMERIC),最大标度为 38(对于 POSTGRES,最大精度为 147,455,最大标度为 16,383;对于 MYSQL,最大精度为 65,最大标度为 30)。
  • IBM 十六进制浮点 (HFP) 支持使用 COMP-1 / COMPUTATIONAL-1(单精度,4 字节)和 COMP-2 / COMPUTATIONAL-2(双精度,8 字节),或在转码器配置中应用 hfp 字段修饰符。
  • 如果所有重新定义的变体都具有相同的字节大小,则静态大小的字段支持 REDEFINES 子句。重新定义的字段不能作为 OCCURS DEPENDING ON 子句的长度字段或 null_if 修饰符的 target_field 被引用。
  • 固定长度数组 (OCCURS n TIMES)、动态长度数组 (OCCURS min TO max TIMES DEPENDING ON field) 和打包的动态长度数组 (OCCURS UNBOUNDED DEPENDING ON field) 支持 OCCURS 子句。不支持 OCCURS 子句中的 ASCENDING/DESCENDING KEY 和 INDEXED BY 短语,并且 DEPENDING ON 必须引用范围内的字段名称。
  • 仅支持以下 USAGE 子句:
    • DISPLAY(字母数字和区位十进制字段的默认值)
    • DISPLAY-1 (DBCS)
    • NATIONAL(PIC N 字段的默认值;编码为 UTF-16BE)
    • UTF-8(PIC U 字段的默认值)
    • BINARY、COMP、COMPUTATIONAL、COMP-4、COMPUTATIONAL-4、COMP-5、COMPUTATIONAL-5
    • COMP-3、COMPUTATIONAL-3、PACKED-DECIMAL
    • COMP-1、COMPUTATIONAL-1、COMP-2、COMPUTATIONAL-2
  • 使用转码器配置支持 DATE 和 TIMESTAMP。
  • 使用转码器配置支持null 指示器。
  • 支持双字节字符集 (DBCS) 字段 PIC G 和 PIC N。默认情况下,没有 USAGE 子句的 PIC N 字段会被分配 USAGE NATIONAL (UTF-16BE)。如需将 PIC N 字段用作 DBCS,请在 copybook 中指定 USAGE DISPLAY-1,或在转码器配置中替换其字符编码。
  • 使用转码器配置支持可变长度字符串。
  • 支持 SIGN 子句(LEADING、TRAILING、SEPARATE CHARACTER)。
  • 支持评论。

支持日期和时间戳字段

Mainframe Connector 支持在转码器配置 (--transcode-configuration) 中使用 format_date 和 format_timestamp 字段修饰符对日期和时间戳字段进行解码和编码。您可以使用 field_suffixes 将这些修饰符应用于匹配字段,也可以使用 field_overrides 将这些修饰符应用于特定字段:

{
  "field_suffixes": [
    {
      "suffix": "SUFFIX_STRING",
      "modifier": {
        "format_date": {
          "formats": [
            {
              "size": FIELD_SIZE,
              "pattern": "FORMAT_PATTERN"
            }
          ]
        }
      }
    }
  ]
}

以下列表更详细地介绍了这些配置属性:

  • suffix:匹配名称以 -SUFFIX_STRING 或 _SUFFIX_STRING 结尾的任何 copybook 字段(不区分大小写)。确保 suffix 不包含前导连字符或下划线。或者,将 field_overrides 与 "field": "FIELD_NAME" 搭配使用,以定位到单个字段。
  • format_date / format_timestamp:定义用于解析或设置字段格式的修饰符:
    • format_date 可应用于定长字符串字段 (PIC X) 或整数字段(例如 PIC 9(n)、COMP 或 COMP-3,其比例为 0,精度最高为 18,在格式化之前会动态转换为其无符号字符串表示形式)。
    • format_timestamp 可应用于有大小限制的字符串字段 (PIC X)。除非模式中包含时区或偏移量,否则时间戳会以世界协调时间 (UTC) 进行解读。
  • formats:DateTimeFormat 对象列表,每个对象指定:
    • size:模式适用的字段的大小(字符串字段的字节长度,或数值字段的精度)。
    • pattern:日期或时间戳格式。在解码 (qsam decode) 期间,系统会按顺序评估与字段大小匹配的格式,直到找到匹配项。在编码 (qsam encode) 期间,系统只会使用与字段大小匹配的第一个格式。如需详细了解有效格式,请参阅支持的日期和时间戳格式。
  • 移除后缀(可选):如需从输出字段名称中移除 -SUFFIX_STRING 或 _SUFFIX_STRING,请将 rename 转换添加到转码器配置中的 transformations 数组。

示例

  • 如需将以 -DT8 或 _DT8 结尾的 8 字节字段格式化为 DATE(模式为 yyyyMMdd),并将以 -DT 或 _DT 结尾的 10 字节字段格式化为 MM-dd-yyyy 或 MM/dd/yyyy,请运行以下命令:

    {
      "field_suffixes": [
        {
          "suffix": "DT8",
          "modifier": {
            "format_date": {
              "formats": [
                {
                  "size": 8,
                  "pattern": "yyyyMMdd"
                }
              ]
            }
          }
        },
        {
          "suffix": "DT",
          "modifier": {
            "format_date": {
              "formats": [
                {
                  "size": 10,
                  "pattern": "MM-dd-yyyy"
                },
                {
                  "size": 10,
                  "pattern": "MM/dd/yyyy"
                }
              ]
            }
          }
        }
      ]
    }
    
  • 如需将以 -TIMESTAMP、_TIMESTAMP、-TS 或 _TS 结尾的 26 字节字段格式化为 TIMESTAMP(模式为 yyyy-MM-dd HH.mm.ss.SSSSSS),并从输出列名称中去除后缀,请运行以下命令:

    {
      "field_suffixes": [
        {
          "suffix": "TIMESTAMP",
          "modifier": {
            "format_timestamp": {
              "formats": [
                {
                  "size": 26,
                  "pattern": "yyyy-MM-dd HH.mm.ss.SSSSSS"
                }
              ]
            }
          }
        },
        {
          "suffix": "TS",
          "modifier": {
            "format_timestamp": {
              "formats": [
                {
                  "size": 26,
                  "pattern": "yyyy-MM-dd HH.mm.ss.SSSSSS"
                }
              ]
            }
          }
        }
      ],
      "transformations": [
        {
          "rename": {
            "find": "^(.*)[-_](TIMESTAMP|TS)$",
            "replace": "$1"
          }
        }
      ]
    }
    

支持 null 指示符

Mainframe Connector 通过转码器配置 (--transcode-configuration) 中的 null_if 字段修饰符支持 null 指示符。

如需配置基于后缀的 null 指示器(其中 COL1-NID 等字段充当同一记录中 COL1 的 null 指示器),请在 field_suffixes 中使用 "is_inverse": true 和 "target_field": "$self" 定义一个条目:

{
  "field_suffixes": [
    {
      "suffix": "NULL_INDICATOR_NAME",
      "is_inverse": true,
      "modifier": {
        "null_if": {
          "target_field": "$self",
          "null_value": "NULL_VALUE",
          "non_null_value": "NOT_NULL_VALUE"
        }
      }
    }
  ]
}

下表介绍了可用于配置 null 指示符的参数:

  • suffix:对应于标识 copybook 中 null 指示器字段的后缀 -NULL_INDICATORNAME 或 NULL_INDICATOR_NAME。
  • is_inverse:在 FieldSuffix 上设置为 true 时,修饰符会应用于名称与指示器字段匹配(不含后缀)的同级字段(例如,当指示器为 COL1-NID1 时,同级字段为 COL1),而 "$self" 是指指示器字段本身。您还可以使用 field_overrides 将 null_if 直接应用于特定字段,并将 target_field 设置为指示器字段的名称。
  • null_value 或 null_values:指定 target_field 中的单个值 (null_value) 或值列表 (null_values),用于指示所引用的字段为 null。
  • non_null_value 或 non_null_values:(可选)指定 target_field 中的单个值 (non_null_value) 或值列表 (non_null_values),以指示引用的字段不是 null。如果省略,则除 null_value 或 null_values 之外的任何值都会被视为非 null。必须至少指定 null_value(s) 或 non_null_value(s) 其中之一。
  • 排除或保留 null 指示器字段:默认情况下,null 指示器字段会作为输出架构中的一列保留。如需从输出表中省略 null 指示器字段,但在转码期间仍使用该字段,请在 transformations 数组中为指示器字段添加 exclude 转换(请勿将 filler 修饰符应用于 null 指示器字段,因为 filler 会完全跳过对该字段的解码)。
  • 替换指示器字段类型:(可选)如需强制将 null 指示器字段解码为 bytes 或 binary,请为指示器字段添加非逆 field_suffixes(或 field_overrides)规则,并使用 "modifier": { "bytes": {} } 或 "modifier": { "binary": {} }。对于 bytes,请将 null_value 和 non_null_value 表示为十六进制字符串(例如 "FF" 或 "00")。

示例

在以下示例中,COL1-NID1 和 FIELD-NID2 在被评估为 null 指示符后,会从输出表中排除,而 COL2-NULL 会保留在输出架构中。

Copybook 代码段:

01 REC.
   10 COL1-NID1 PIC S9(4) USAGE COMP.
   10 COL1      PIC S9(6) USAGE COMP.
   10 FIELD     PIC X(10).
   10 FIELD-NID2 PIC X(1).
   10 COL2      PIC X(10).
   10 COL2-NULL PIC X(1).

转码器配置 (transcode-configuration.json):

{
  "field_suffixes": [
    {
      "suffix": "NID1",
      "is_inverse": true,
      "modifier": {
        "null_if": {
          "target_field": "$self",
          "null_value": "-1",
          "non_null_value": "0"
        }
      }
    },
    {
      "suffix": "NID2",
      "is_inverse": true,
      "modifier": {
        "null_if": {
          "target_field": "$self",
          "null_value": "?"
        }
      }
    },
    {
      "suffix": "NULL",
      "is_inverse": true,
      "modifier": {
        "null_if": {
          "target_field": "$self",
          "null_value": "?"
        }
      }
    }
  ],
  "transformations": [
    {
      "exclude": {
        "field": "COL1-NID1"
      }
    },
    {
      "exclude": {
        "field": "FIELD-NID2"
      }
    }
  ]
}

支持 DBCS 字段

使用 DBCS 字段(PIC G 或 PIC N 带有 USAGE DISPLAY-1)时,请确保:

  • PIC G 字段必须明确指定 USAGE DISPLAY-1。
  • 没有 USAGE 子句的 PIC N 字段默认为 USAGE NATIONAL (UTF-16BE)。如需将 PIC N 字段视为 DBCS 字段,请在 copybook 中指定 USAGE DISPLAY-1(或在转码器配置中替换其编码)。
  • 默认情况下,USAGE DISPLAY-1 字段使用 cp300 (x-IBM300) DBCS 字符集进行解码和编码,该字符集需要不含移出 (0x0E) 和移入 (0x0F) 控制字符的原始 DBCS 字节。
  • 如需使用其他 DBCS 字符集(例如 Cp834)或使用移出 (0x0E) 和移入 (0x0F) 字节的多字节字符集 (MBCS)(例如 x-IBM930、x-IBM933、x-IBM935、x-IBM937、x-IBM939、x-IBM942、x-IBM942C、x-IBM943、x-IBM943C、x-IBM949、x-IBM949C、x-IBM950、x-IBM964、x-IBM970 或 x-IBM1364),请在转码器配置 (--transcode-configuration) 中配置 string 字段修饰符。

您可以使用 defaults.dbcs 为所有 USAGE DISPLAY-1 字段全局设置 DBCS 编码,也可以使用 field_overrides 或 field_suffixes 为特定字段设置 DBCS 编码:

{
  "defaults": {
    "dbcs": {
      "string": {
        "encoding": "x-IBM930"
      }
    }
  }
}

支持可变长度字符串

Copybook 解析器支持在转码器配置中使用 varlen 字段修饰符的可变长度字符串组字段:

10 VAR-GRP.
   15 VAR-LEN  PIC 9(4) USAGE COMP.
   15 VAR-TEXT PIC X(50).

使用 varlen 字段修饰符时,请确保:

  • 在转码器配置中使用 field_overrides 或 field_suffixes 将 varlen 修饰符应用于组项(例如 VAR-GRP):

    {
      "field_overrides": [
        {
          "field": "VAR-GRP",
          "modifier": {
            "varlen": {}
          }
        }
      ]
    }
    
  • 群组项必须恰好包含两个子字段:

    1. 第一个子字段必须解码为 64 位整数(LONG,例如二进制 COMP 或分区十进制整数字段),用于指定字符串数据的字节长度。
    2. 第二个子字段必须是未修改的字符串字段(例如 PIC X(n)、PIC N(n) 或 PIC U(n))。
  • 不需要特定的子字段后缀(例如 -LEN 或 -TEXT),并且输出架构中的结果列使用组项的名称 (VAR-GRP)。

不受支持的字段和构造

以下部分介绍了 copybook 解析器不支持的字段和构造。

不受支持的 COBOL 构造

Copybook 解析器可以解析以下 COBOL 结构,即使这些结构不受支持。如果您在 copybook 中使用这些结构,Mainframe Connector 会显示错误:

  • ALIGNED
  • BLANK WHEN ZERO
  • COMMON、OWN、LOCAL
  • DYNAMIC LENGTH(例如 PIC X DYNAMIC LENGTH 或 PIC U DYNAMIC LENGTH LIMIT n)
  • INTEGER,STRING
  • JUSTIFIED
  • OCCURS的ASCENDING/DESCENDING KEY
  • OCCURS的INDEXED BY
  • RECEIVED BY
  • RECORD AREA
  • RENAMES
  • SYNCHRONIZED/SYNC
  • THREAD-LOCAL
  • TYPE IS ...
  • TYPEDEF
  • USING LANGUAGE/CONVENTION

不支持的数据类型

以下 USAGE 类型可以由语法解析,但 copybook 编译器不支持:

  • BIT
  • CONTROL-POINT
  • DATE
  • DOUBLE
  • EVENT
  • FUNCTION-POINTER
  • INDEX
  • KANJI
  • LOCK
  • POINTER
  • PROCEDURE-POINTER
  • REAL
  • SQL
  • TASK