COBOL copybook compiler: fixed-length EBCDIC/COMP-3 record decoding into typed rows, with layout maps and round-trip encoding.
01 CUSTOMER-RECORD.
05 CUST-ID PIC 9(8).
05 CUST-NAME PIC X(30).
05 BALANCE PIC S9(7)V99 COMP-3.
05 OPEN-DATE PIC 9(8).moon add NekoYume517/copybook// 解析 copybook → 编译布局 → 解码 EBCDIC 记录
let specs = @copybook.parse_copybook(cpy_text)
let layout = @copybook.compile_layout(specs)
let row = @copybook.decode_record(layout, record_bytes)moon check
moon test
moon run cmd/copybook -- layout --copybook examples/customer.cpy# 看字节布局(最容易出错的地方,先看这个)
copybook layout --copybook examples/customer.cpy
# 解码成 JSONL
copybook decode --copybook examples/customer.cpy --data examples/customer.dat --format jsonl
# 解码成定宽文本表格
copybook decode --copybook examples/customer.cpy --data examples/customer.dat --format table
# 自检:解码再编码,逐字节比对(纯内存路径)
copybook verify --copybook examples/customer.cpy --data examples/customer.dat
# 完整的「解码 → 编辑 → 编码」工作流(经过 JSON 文本)
copybook decode --copybook examples/customer.cpy --data examples/customer.dat --format jsonl > out.jsonl
copybook encode --copybook examples/customer.cpy --json out.jsonl --out roundtrip.dat
# roundtrip.dat 与 examples/customer.dat 逐字节相同
# 数据源是 GnuCOBOL / Micro Focus 时,浮点要显式声明为 IEEE 754
copybook decode --copybook app.cpy --data app.dat --float-mode ieeeverify 走的是内存内 decode→encode,不经过 JSON。要验证「导出成 JSON 再导回」 这条真实工作流,用上面最后两条命令,然后比较文件。这两条路径不同,都测过。
注意 decode --format jsonl 把定点小数写成 JSON 数字(1234567.89)。 JSON 没有定点类型,5.00 会序列化成 5;编码器按字段声明的 scale (PIC S9(7)V99 → 2 位小数)还原,因此 5 仍被正确写成 500 分。 这一点有专门的回归测试(src/json_roundtrip_test.mbt)。
RECORD: CUSTOMER-RECORD LENGTH: 54 bytes
OFFSET LENGTH OCCURS TYPE NAME
0 8 1 9(8) DISPLAY CUSTOMER-RECORD.CUST-ID
8 30 1 X(30) DISPLAY CUSTOMER-RECORD.CUST-NAME
38 5 1 S9(7)V99 COMP-3 CUSTOMER-RECORD.BALANCE
43 8 1 9(8) DISPLAY CUSTOMER-RECORD.OPEN-DATE
51 1 1 X(1) DISPLAY CUSTOMER-RECORD.FLAGS.ACTIVE
52 2 1 9(2) DISPLAY CUSTOMER-RECORD.FLAGS.TIER| 维度 | 本项目采用 | 依据 |
|---|---|---|
| 字符编码 | EBCDIC cp037(US/Canada) | 主機记录的实际编码;ASCII 不是候选 |
| 记录形态 | 定长,无 RDW/BDW,记录间无填充 | 主机批量文件的标准形态 |
| 数值表示 | zoned decimal / COMP-3 打包十进制 / COMP 二进制补码 | COBOL 主机端标准数值格式 |
| 浮点表示 | IBM HFP 十六进制浮点(base-16 指数) | z/OS 的 COMP-1 / COMP-2 原生格式 |
| 语言子集 | COBOL-85 数据描述子集 + IBM Enterprise COBOL 常用扩展 | 见下方「支持的 COBOL 子集」 |
| 实现 | COMP-1 存 1.5 的字节 | 格式 | 指数 |
|---|---|---|---|
| IBM z/OS 主机 | 41 18 00 00 | HFP(十六进制浮点) | base-16,excess-64 |
| GnuCOBOL / Micro Focus / x86 | 3F C0 00 00 | IEEE 754 binary32 | base-2,excess-127 |
| 属性 | IBM HFP | IEEE 754 |
|---|---|---|
| 指数基数 | 16 | 2 |
| 指数偏置 | 64(7 位) | 127 / 1023(8 / 11 位) |
| COMP-1 尾数 | 24 位(6 个十六进制数字) | 24 位(隐含前导 1) |
| COMP-2 尾数 | 56 位(14 个十六进制数字) | 53 位(隐含前导 1) |
| NaN / ±Infinity | 没有 | 有 |
| 渐进下溢 | 没有(小于 2^-260 直接下溢) | 有非规格化数 |
| ±0 | 尾数为 0,符号位保留 | 有专门的 ±0 编码 |
# 默认:IBM 主机 HFP(本项目目标平台)
copybook decode --copybook app.cpy --data app.dat
# GnuCOBOL / Micro Focus 产生的数据:显式指定 IEEE 754
copybook decode --copybook app.cpy --data app.dat --float-mode ieee| 数据来源 | 能否用本项目 | 需要的选项 |
|---|---|---|
| IBM z/OS 批量导出(EBCDIC + COMP-3 + HFP) | ✅ 完整支持 | 默认 |
| 同上但含 IEEE 浮点字段(ARITH(IEEE) 编译) | ⚠️ 浮点需声明 | --float-mode ieee |
| GnuCOBOL 生成的测试数据 | ⚠️ 浮点需声明 | --float-mode ieee |
| Micro Focus 生成的数据 | ⚠️ 浮点需声明 | --float-mode ieee |
| ASCII 编码的 COBOL 文件 | ❌ 不支持 | 本项目只解 EBCDIC |
| 变长记录(RDW/BDW 头) | ❌ 不支持 | 需先剥离头部再喂进来 |
| 多个 01 层级混排的记录型态 | ⚠️ 有简化 | 见「已声明的简化」 |
| 特性 | 状态 |
|---|---|
| PIC 9(n) 数字(zoned decimal) | ✅ |
| PIC S9(n) 带符号 | ✅ |
| PIC X(n) / A(n) 字符 | ✅ |
| PIC N(n) 国家字符 | ✅ UTF-16BE;n 是 UTF-16 码元数(不是字符数),空位补 U+0020 |
| PIC S9(n)V9(m) 隐含小数 | ✅ |
| COMP / COMP-4 二进制 | ✅ |
| COMP-3 打包十进制 | ✅ |
| COMP-1 / COMP-2 浮点 | ✅ 默认 IBM HFP;--float-mode ieee 切 IEEE 754 |
| OCCURS n TIMES | ✅ |
| REDEFINES | ✅ |
| SIGN ... SEPARATE | ✅ |
| 固定格式列 7 - 续行(PIC / VALUE 跨行) | ✅ 仅固定格式;自由格式没有续行符,行首 - 报错 |
| 列 73-80 标识区 | ✅ 固定格式下忽略(行长必须真的写到第 73 列) |
| PIC 66 RENAMES / 88 条件名 | 忽略(记录在 AST) |
| OCCURS DEPENDING ON | 按上界展开(固定长度存储),occurs_depending_on 字段记录依赖名 |
| 多个 01 层级 | 并列拼接为一条记录(见下方说明) |
| 组级 USAGE | ✅ 子项继承 |
05 EMOJI PIC N(1). * 只有 2 码元容量 → 存 emoji 报错(不截断、不替换)
05 EMOJI PIC N(2). * 4 字节,emoji 写成 D8 3D DE 00(U+1F600)src/
ebcdic.mbt cp037 编码表与转换
lexer.mbt copybook 词法
parser.mbt copybook 语法(层级树、PIC 子句)
layout.mbt 字节布局计算
hfp.mbt IBM 十六进制浮点(COMP-1 / COMP-2 主机格式)
decode.mbt 记录 → 类型化值
encode.mbt 类型化值 → 记录
output.mbt JSONL / 表格 / 布局报告
fidelity_test.mbt 字节保真回归(同值不同符号字节)
audit_test.mbt 对抗性审计回归测试
cmd/copybook/
main.mbt CLIInstall
Download zipCOBOL copybook compiler: fixed-length EBCDIC/COMP-3 record decoding into typed rows, with layout maps and round-trip encoding.