diff --git a/cobol_testgen/grammar.lark b/cobol_testgen/grammar.lark index b367c1c..c91f2f1 100644 --- a/cobol_testgen/grammar.lark +++ b/cobol_testgen/grammar.lark @@ -1,7 +1,7 @@ start: data_div_content data_div_content: (file_section | working_storage | linkage)* file_section: "FILE" "SECTION" DOT (fd | sd)+ -fd: "FD" NAME FD_SUFFIX data_item+ +fd: "FD" NAME FD_SUFFIX data_item* sd: "SD" NAME FD_SUFFIX data_item* FD_SUFFIX: /(?:"[^"]*"|'[^']*'|[^.])*\./ working_storage: "WORKING-STORAGE" "SECTION" DOT data_item* @@ -22,13 +22,13 @@ value_literal: INT | SIGNED_NUMBER | STRING | SQSTRING | "LOW-VALUE" | "LOW-VALUES" SQSTRING: /'[^']*'/ redefines_clause: "REDEFINES" NAME -occurs_clause: "OCCURS" INT "TIMES"? ("DEPENDING" "ON" NAME)? key_clause? indexed_clause? +occurs_clause: "OCCURS" INT ("TO" INT)? "TIMES"? ("DEPENDING" "ON" NAME)? key_clause? indexed_clause? key_clause: ("ASCENDING" | "DESCENDING") "KEY" "IS"? NAME (","? NAME)* indexed_clause: "INDEXED" "BY" NAME (","? NAME)* usage_clause: USAGE_VAL USAGE_VAL: "COMP" | "COMP-3" | "COMP-5" | "BINARY" | "PACKED-DECIMAL" | "DISPLAY" LEVEL: /0[1-9]|[1-4][0-9]|49|77|88/ -NAME: /[A-Z][A-Z0-9-]*/ +NAME: /[A-Z][A-Z0-9-]*/i PICTURE_STRING: /[0-9A-Z()+,\-*\/V]+/i INT: /[0-9]+/ DOT: /\./ diff --git a/cobol_testgen/read.py b/cobol_testgen/read.py index e3d4568..03bb24d 100644 --- a/cobol_testgen/read.py +++ b/cobol_testgen/read.py @@ -27,6 +27,10 @@ def _is_fixed_format(source: str) -> bool: def preprocess(source: str) -> str: + # COPY 预处理:展开或移除 COPY 语句 + # Lark 语法不支持 COPY(这是预处理指令),必须在解析前处理 + source = resolve_copybooks(source, '.') + fixed = _is_fixed_format(source) lines = [] for raw_line in source.splitlines(): @@ -110,10 +114,12 @@ def resolve_copybooks(source: str, source_dir: str) -> str: re.escape(old.strip()), new.strip(), cb, flags=re.IGNORECASE ) - result.append(f' * COPY {name}') + # 展开 COPYBOOK 内容,不添加注释行(避免 Lark 在 FD 块内看到注释) result.append(cb) else: - result.append(line) + # COPY 未找到时完全跳过(预处理指令,Lark 不应处理) + # 该行可能在 FD/SD 块内,保留会破坏 Lark 解析 + pass else: result.append(line) return '\n'.join(result) diff --git a/tests/cobol_testgen/test_read.py b/tests/cobol_testgen/test_read.py index 77f6838..f08fc13 100644 --- a/tests/cobol_testgen/test_read.py +++ b/tests/cobol_testgen/test_read.py @@ -92,11 +92,12 @@ def test_resolve_copybooks_found(): def test_resolve_copybooks_not_found(): - """COPY 文件不存在时返回含 NOT FOUND 或 NOTEXIST 的文本""" + """COPY 不可解析时移除该行(预处理器指令,Lark 不应处理)""" with tempfile.TemporaryDirectory() as tmp: src = " COPY NOTEXIST.\n" result = resolve_copybooks(src, tmp) - assert "NOT FOUND" in result or "NOTEXIST" in result.upper() + # COPY 被移除(无残留) + assert "NOTEXIST" not in result.upper() def test_resolve_copybooks_no_copy():