fix: 跨文件KEY约束 + PERFORM分支统计 + 平面文件写入

1. 跨文件KEY约束(修复)
   匹配型程的M-KEY与D-KEY值不同导致匹配0条。
   修复: generate_data后处理检测IF KEY比较,
   前半记录对齐KEY值(8条匹配),后半保待差异(9条不匹配).
   实际cobc运行验证: MATCHED=8, PASS.

2. extract_structure PERFORM分支统计(修复)
   _walk函数未添加BrPerform决策点, total_branches缺失.
   修复: 为PERFORM UNTIL/VARYING决策点添加2分支(Enter/Skip).
   之前total_branches=0,现在=2.

3. flatfile.py(新增)
   COBOL固定长平面文件写入器.
   - analyze_fd_layout(): 从COBOL源码自动解析文件布局
   - write_flat_file(): 生成为COBOL可直接读取的二进制格式

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
NB-076
2026-06-22 13:52:56 +08:00
parent 708e8efa33
commit 0e7472598d
2 changed files with 167 additions and 0 deletions
+22
View File
@@ -404,6 +404,13 @@ def extract_structure(cobol_source: str) -> dict:
for child in node.children:
_walk(child, counter)
elif isinstance(node, BrPerform):
if node.condition and node.perf_type in ('until', 'para_until', 'varying', 'para_varying'):
counter[0] += 1
decision_points.append({
"id": counter[0], "kind": "PERFORM",
"label": str(node.condition)[:80], "branches": 2,
})
total_branches += 2
_walk(node.body_seq, counter)
elif isinstance(node, BrSearch):
_walk(node.at_end_seq, counter)
@@ -688,6 +695,21 @@ def generate_data(cobol_source: str, structure: dict = None) -> list[dict]:
branch_paths = [(_filter_stop(c), a) for c, a in branch_paths]
records, kept_paths = generate_records(branch_paths, fields_dict, assignments, file_sec=file_sec)
# Cross-file KEY alignment for matching programs
if records:
import re as _re
proc_upper = (proc_div or "").upper()
for m in _re.finditer(r'IF\s+(\w[\w-]*)\s*[=<>]\s*(\w[\w-]*)', proc_upper):
lhs, rhs = m.group(1), m.group(2)
lhs_in = any(lhs == f['name'] for f in fields_dict)
rhs_in = any(rhs == f['name'] for f in fields_dict)
if lhs_in and rhs_in and any(lhs in r for r in records) and any(rhs in r for r in records):
half = max(1, len(records) // 2)
for i, rec in enumerate(records):
if lhs in rec and rhs in rec and i < half:
rec[rhs] = rec[lhs]
return records