Files
jcl-cobol-data-create/agent/rule_loader.py
T
2026-07-12 14:54:50 +08:00

126 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import re
from typing import List, Tuple, Optional
from agent.models import ProgramMeta
PGM_PATTERN_MAP = {
'マッチング(1:1)': 'マッチング(1-1).md',
'マッチング(1:N)': 'マッチング(1-N).md',
'マッチング(N:1)': 'マッチング(N-1).md',
'マッチング(M:N)': 'マッチング(M-N).md',
'レイアウト編集のみ(GETPUT)': 'レイアウト編集のみ(GETPUT).md',
'レイアウト編集のみ(GETPUT': 'レイアウト編集のみ(GETPUT).md',
'レイアウト編集のみ': 'レイアウト編集のみ(GETPUT).md',
'GETPUT(編集出力)': 'GETPUT(編集出力).md',
'項目チェック': '項目チェック.md',
'項目チェック(重複なし)': '項目チェック.md',
'振り分け': '振り分け.md',
'振り分け(IF文、EVALUATE文)': '振り分け.md',
'キーブレイク': 'キーブレイク(集計).md',
'キーブレイク(集計)': 'キーブレイク(集計).md',
'キーブレイク(集約)': 'キーブレイク(集約).md',
'キーブレイク(集約)': 'キーブレイク(集約).md',
'キーブレイク(集計、集約)': 'キーブレイク(集計、集約).md',
'キーブレイク(集計、集約の以外)': 'キーブレイク(集計).md',
'1:Nキーブレイク(同キー集約)': 'キーブレイク(集計、集約).md',
'1:N+キーブレイク(同キー)': 'キーブレイク(集計、集約).md',
'DB更新': 'DB更新.md',
'DB更新 + SYSIN読込(P28)': 'DB更新.md',
'SELECT処理': 'SELECT処理.md',
'SELECT条件': 'SELECT処理.md',
'50分割': '50分割.md',
'MERGE(複数ファイル結合)': 'MERGE.md',
'CSV→FB変換(改行あり)': 'CSV→FB変換.md',
}
SPECIAL_FEATURE_CHECKS = [
(['場合', 'EVALUATE', 'IF'], '条件分支.md'),
]
class RuleLoader:
"""根据程序特征加载对应的数据生成规则。"""
def __init__(self, rules_dir: str):
self.pgm_pattern_dir = os.path.join(rules_dir, 'pgm_pattern')
self.special_feature_dir = os.path.join(rules_dir, 'special_feature')
def load(self, meta: ProgramMeta) -> Tuple[str, List[str], int]:
"""加载所有相关规则,返回 (合并后的规则文本, 组描述列表, 组数)。"""
pgm_rule = self._load_pgm_pattern_rule(meta.pgm_pattern)
if pgm_rule is None:
raise FileNotFoundError(
f"PGM模式 '{meta.pgm_pattern}' の規則ファイルが見つかりません。"
f"{self.pgm_pattern_dir} に .md ファイルを追加してください。"
)
group_descriptions, group_count = self._parse_group_info(pgm_rule)
parts = [pgm_rule]
for keywords, rule_file in SPECIAL_FEATURE_CHECKS:
if self._detect_feature(meta.process_detail, keywords):
feature_rule = self._read_rule_file(
os.path.join(self.special_feature_dir, rule_file)
)
if feature_rule:
parts.append(feature_rule)
combined = '\n\n---\n\n'.join(parts)
return combined, group_descriptions, group_count
def _load_pgm_pattern_rule(self, pgm_pattern: str) -> Optional[str]:
"""根据 PGMパターン 加载对应的规则文件。"""
filename = PGM_PATTERN_MAP.get(pgm_pattern)
if filename:
path = os.path.join(self.pgm_pattern_dir, filename)
if os.path.exists(path):
return self._read_rule_file(path)
if os.path.isdir(self.pgm_pattern_dir):
available = sorted(os.listdir(self.pgm_pattern_dir))
# 对每个规则文件名(去掉.md),检查它是否出现在 PGMパターン 中
pgm_lower = pgm_pattern.lower()
for fname in available:
if fname.endswith('.md'):
rule_name = fname[:-3].lower()
if rule_name in pgm_lower:
return self._read_rule_file(os.path.join(self.pgm_pattern_dir, fname))
return None
@staticmethod
def _read_rule_file(path: str) -> str:
with open(path, 'r', encoding='utf-8') as f:
return f.read()
@staticmethod
def _parse_group_info(rule_text: str) -> Tuple[List[str], int]:
"""从规则文本中解析组信息。"""
descriptions = []
group_count = 0
for line in rule_text.split('\n'):
line = line.strip()
if line.startswith('|') and not re.match(r'^\|[\s\-:]+\|', line):
cells = [c.strip() for c in line.split('|')[1:-1]]
if len(cells) >= 2:
try:
group_num = int(cells[0])
if group_num > group_count:
group_count = group_num
descriptions.append(cells[1])
except ValueError:
pass
return descriptions, group_count
@staticmethod
def _detect_feature(process_detail: str, keywords: List[str]) -> bool:
"""检测処理詳細中是否包含特定关键词。"""
for kw in keywords:
if kw in process_detail:
return True
return False