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-5COMP-3、COMPUTATIONAL-3、PACKED-DECIMALCOMP-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": {} } } ] }群组项必须恰好包含两个子字段:
- 第一个子字段必须解码为 64 位整数(
LONG,例如二进制COMP或分区十进制整数字段),用于指定字符串数据的字节长度。 - 第二个子字段必须是未修改的字符串字段(例如
PIC X(n)、PIC N(n)或PIC U(n))。
- 第一个子字段必须解码为 64 位整数(
不需要特定的子字段后缀(例如
-LEN或-TEXT),并且输出架构中的结果列使用组项的名称 (VAR-GRP)。
不受支持的字段和构造
以下部分介绍了 copybook 解析器不支持的字段和构造。
不受支持的 COBOL 构造
Copybook 解析器可以解析以下 COBOL 结构,即使这些结构不受支持。如果您在 copybook 中使用这些结构,Mainframe Connector 会显示错误:
ALIGNEDBLANK WHEN ZEROCOMMON、OWN、LOCALDYNAMIC LENGTH(例如PIC X DYNAMIC LENGTH或PIC U DYNAMIC LENGTH LIMIT n)INTEGER,STRINGJUSTIFIEDOCCURS的ASCENDING/DESCENDING KEYOCCURS的INDEXED BYRECEIVED BYRECORD AREARENAMESSYNCHRONIZED/SYNCTHREAD-LOCALTYPE IS ...TYPEDEFUSING LANGUAGE/CONVENTION
不支持的数据类型
以下 USAGE 类型可以由语法解析,但 copybook 编译器不支持:
BITCONTROL-POINTDATEDOUBLEEVENTFUNCTION-POINTERINDEXKANJILOCKPOINTERPROCEDURE-POINTERREALSQLTASK