cobol-parser 3.1.1__tar.gz → 3.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cobol_parser-3.3.0/PKG-INFO +301 -0
- cobol_parser-3.3.0/README.md +251 -0
- cobol_parser-3.3.0/cobol_parser.egg-info/PKG-INFO +301 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobol_parser.egg-info/SOURCES.txt +20 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobol_parser.egg-info/requires.txt +6 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/__init__.py +1 -1
- cobol_parser-3.3.0/cobolparser/_facts_cache.py +132 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/_sql_flow.py +74 -10
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/_sql_whenever.py +7 -1
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/boundary_inventory.py +9 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/business_rules.py +4 -0
- cobol_parser-3.3.0/cobolparser/analysis/call_interface.py +803 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/codebase.py +141 -45
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/const_fold.py +410 -29
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/constraints.py +783 -16
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/dead_code.py +126 -5
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/field_lineage.py +234 -22
- cobol_parser-3.3.0/cobolparser/analysis/field_widening.py +974 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/io_sequence.py +74 -10
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/language_env_analyzer.py +25 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/lineage_graph.py +205 -22
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/lineage_jcl.py +28 -8
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/lint.py +10 -2
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/program_signature.py +10 -1
- cobol_parser-3.3.0/cobolparser/analysis/sarif.py +255 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/value_tracker.py +321 -4
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/cli/_project_config.py +1 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/cli/parse.py +561 -54
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/config/project.py +9 -2
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/core/token_stream.py +6 -0
- cobol_parser-3.3.0/cobolparser/definitions/__init__.py +134 -0
- cobol_parser-3.3.0/cobolparser/definitions/_asm.py +269 -0
- cobol_parser-3.3.0/cobolparser/definitions/bms.py +269 -0
- cobol_parser-3.3.0/cobolparser/definitions/csd.py +484 -0
- cobol_parser-3.3.0/cobolparser/definitions/ddl.py +759 -0
- cobol_parser-3.3.0/cobolparser/definitions/ims.py +407 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/program_layout.py +84 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/program_fixtures.py +86 -16
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/scenarios.py +443 -21
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/verification.py +73 -2
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/jcl/models.py +5 -1
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/jcl/parser.py +150 -19
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/lexer.py +181 -2
- cobol_parser-3.3.0/cobolparser/mcp/claims.py +708 -0
- cobol_parser-3.3.0/cobolparser/mcp/codebase_index.py +736 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/mcp/envelope.py +62 -0
- cobol_parser-3.3.0/cobolparser/mcp/facts.py +699 -0
- cobol_parser-3.3.0/cobolparser/mcp/hints.py +202 -0
- cobol_parser-3.3.0/cobolparser/mcp/jcl_tools.py +2547 -0
- cobol_parser-3.3.0/cobolparser/mcp/languages.py +491 -0
- cobol_parser-3.3.0/cobolparser/mcp/link_decks.py +184 -0
- cobol_parser-3.3.0/cobolparser/mcp/navigation.py +693 -0
- cobol_parser-3.3.0/cobolparser/mcp/prompts.py +147 -0
- cobol_parser-3.3.0/cobolparser/mcp/server.py +902 -0
- cobol_parser-3.3.0/cobolparser/mcp/slicing.py +419 -0
- cobol_parser-3.3.0/cobolparser/mcp/sort_layout.py +536 -0
- cobol_parser-3.3.0/cobolparser/mcp/tools.py +4330 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/mcp/workspace.py +156 -3
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/program.py +24 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/sql_statements.py +1 -1
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parser.py +10 -6
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/base.py +1 -1
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/environment.py +1 -1
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/environment_sections.py +88 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/identification.py +53 -4
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/procedure.py +5 -1
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/_conditions.py +26 -2
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/_utils.py +1 -1
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/arithmetic_parsers.py +58 -38
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/evaluate_parser.py +5 -5
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/ibm_exec_statements.py +9 -1
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/read_parser.py +5 -1
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/preprocess/copybook_expander.py +6 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/preprocess/source_format.py +17 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/scan.py +136 -1
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/pyproject.toml +13 -1
- cobol_parser-3.1.1/PKG-INFO +0 -190
- cobol_parser-3.1.1/README.md +0 -144
- cobol_parser-3.1.1/cobol_parser.egg-info/PKG-INFO +0 -190
- cobol_parser-3.1.1/cobolparser/mcp/codebase_index.py +0 -496
- cobol_parser-3.1.1/cobolparser/mcp/server.py +0 -320
- cobol_parser-3.1.1/cobolparser/mcp/tools.py +0 -2128
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/LICENSE +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/MANIFEST.in +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobol_parser.egg-info/dependency_links.txt +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobol_parser.egg-info/entry_points.txt +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobol_parser.egg-info/top_level.txt +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/__main__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/_accel.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/_data_fast.c +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/_data_fast.pyx +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/_errors.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/_lexer_fast.c +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/_lexer_fast.pyx +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/_lines.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/_literals.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/_preprocess_fast.c +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/_preprocess_fast.pyx +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/_source_directive.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/_storage.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/_cics.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/_files.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/_names.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/_procedures.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/ast_diff.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/complexity.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/crud_matrix.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/dclgen_check.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/domains.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/host_var_resolver.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/ims_segment_analyzer.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/invocation_counts.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/io_coverage_reporter.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/io_diagnostics.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/io_logger.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/linkage_checker.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/move_type_checker.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/program_flow/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/program_flow/analyzer.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/program_flow/condition_text.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/program_flow/cycles.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/program_flow/edges.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/program_flow/graph.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/program_flow/models.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/program_flow/scanner.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/program_flow/statement_text.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/recursion_risk.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/redundancy.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/sql_cics_lint.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/technical_debt.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/unused_variables.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/analysis/xref.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/batch.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/cli/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/cli/coverage.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/config/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/config/_yaml.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/core/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/core/ast_factory.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/core/exceptions.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/core/interfaces.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/core/registry.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/dialects/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/dialects/ibm_enterprise.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/dialects/le_signatures.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/copybook_data.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/bundle.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/compare.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/copybook.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/dataset.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/decoding.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/editing.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/encoding.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/errors.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/layout.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/layout_offsets.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/options.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/storage.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/values.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/data/views.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/generators/flowchart.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/jcl/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/jcl/bindings.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/jcl/programs.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/mcp/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/ast_base.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/data_items.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/statements/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/statements/arithmetic.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/statements/base.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/statements/call.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/statements/communication.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/statements/control.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/statements/data.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/statements/io.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/statements/legacy.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/statements/misc.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/models/statements/report_writer.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/data.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/data_clauses.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/data_file_description.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/data_report_description.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/data_special_entries.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/environment_select.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/factory.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/procedure_boundaries.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/procedure_recovery.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/divisions/procedure_registry.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/accept_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/allocate_free_parsers.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/call_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/close_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/communication_parsers.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/delete_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/display_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/entry_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/exception_parsers.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/go_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/if_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/initialize_inspect_parsers.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/invoke_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/legacy_verb_parsers.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/move_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/open_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/perform_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/report_writer_parsers.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/rewrite_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/search_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/set_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/simple_statement_parsers.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/sort_merge_parsers.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/start_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/stop_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/string_unstring_parsers.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/unlock_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/write_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/parsers/statements/xml_json_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/plugins/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/plugins/core.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/preprocess/__init__.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/preprocess/_normalize.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/preprocess/copy_statement_parser.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/preprocess/models.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/preprocess/path_resolver.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/preprocess/replace_statement.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/profiling.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/cobolparser/py.typed +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/setup.cfg +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/setup.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/tests/test_all_samples.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/tests/test_okf_claims.py +0 -0
- {cobol_parser-3.1.1 → cobol_parser-3.3.0}/tests/test_okf_staleness_map.py +0 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cobol-parser
|
|
3
|
+
Version: 3.3.0
|
|
4
|
+
Summary: A comprehensive COBOL parser for Python with IBM Enterprise COBOL focus
|
|
5
|
+
Author-email: Samuel Dion <sam94dion@gmail.com>
|
|
6
|
+
License: AGPL-3.0-or-later
|
|
7
|
+
Project-URL: Homepage, https://github.com/Landparty/cobol-parser
|
|
8
|
+
Project-URL: Repository, https://github.com/Landparty/cobol-parser
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/Landparty/cobol-parser/issues
|
|
10
|
+
Keywords: cobol,parser,mainframe,ibm,enterprise,legacy
|
|
11
|
+
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Topic :: Software Development :: Compilers
|
|
20
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Provides-Extra: fast
|
|
25
|
+
Requires-Dist: cython>=3.0; extra == "fast"
|
|
26
|
+
Provides-Extra: jcl
|
|
27
|
+
Requires-Dist: jcl-parser>=2.0.0; extra == "jcl"
|
|
28
|
+
Provides-Extra: pl1
|
|
29
|
+
Requires-Dist: landparty-pl1-parser>=2.0.0; extra == "pl1"
|
|
30
|
+
Provides-Extra: hlasm
|
|
31
|
+
Requires-Dist: hlasm-parser>=0.2.2; extra == "hlasm"
|
|
32
|
+
Provides-Extra: mcp
|
|
33
|
+
Requires-Dist: mcp<2,>=1.10; extra == "mcp"
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: jcl-parser>=2.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: mcp<2,>=1.10; extra == "dev"
|
|
37
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
38
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
39
|
+
Requires-Dist: pytest-xdist>=3.0.0; extra == "dev"
|
|
40
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
41
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
42
|
+
Requires-Dist: mypy>=1.5.0; extra == "dev"
|
|
43
|
+
Requires-Dist: cython>=3.0; extra == "dev"
|
|
44
|
+
Provides-Extra: docs
|
|
45
|
+
Requires-Dist: sphinx>=7.0.0; extra == "docs"
|
|
46
|
+
Requires-Dist: sphinx-rtd-theme>=1.3.0; extra == "docs"
|
|
47
|
+
Provides-Extra: profiling
|
|
48
|
+
Requires-Dist: psutil>=5.9; extra == "profiling"
|
|
49
|
+
Dynamic: license-file
|
|
50
|
+
|
|
51
|
+
# cobol-parser
|
|
52
|
+
|
|
53
|
+
A COBOL parser for Python with an IBM Enterprise COBOL focus. It turns COBOL
|
|
54
|
+
source into a traversable AST (JSON export, error recovery, copybook
|
|
55
|
+
expansion with a source map back to the original lines), and builds static
|
|
56
|
+
analyzers, test-data generators, a z/OS JCL front end and an MCP server for AI
|
|
57
|
+
agents on top of it.
|
|
58
|
+
|
|
59
|
+
458 of the 459 NIST COBOL-85 programs in `examples/cobol/` parse cleanly (the
|
|
60
|
+
one that does not, SM101A, needs its copybooks expanded first).
|
|
61
|
+
|
|
62
|
+
[](https://www.python.org/downloads/)
|
|
63
|
+
[](https://pypi.org/project/cobol-parser/)
|
|
64
|
+
[](.okf/tests.md)
|
|
65
|
+
[](LICENSE)
|
|
66
|
+
|
|
67
|
+
## Install
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pip install cobol-parser # the library and the cobol-parser CLI
|
|
71
|
+
pip install 'cobol-parser[mcp]' # plus the MCP server
|
|
72
|
+
pip install 'cobol-parser[jcl]' # plus JCL (through jcl-parser)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Requires Python 3.11, 3.12 or 3.13. The core library has no runtime
|
|
76
|
+
dependencies. Optional extras:
|
|
77
|
+
|
|
78
|
+
| Extra | Adds |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `mcp` | `cobol-parser mcp`, the MCP server ([docs/mcp-server.md](docs/mcp-server.md)) |
|
|
81
|
+
| `jcl` | `cobol-parser jcl`, and the JCL joins in `field-impact`, `widen-check` and the MCP server |
|
|
82
|
+
| `pl1`, `hlasm` | PL/I and assembler programs in the MCP server's call graph |
|
|
83
|
+
| `fast` | Cython, to build the optional accelerators from source |
|
|
84
|
+
| `dev`, `docs` | the test, lint and docs toolchain for working on this repo |
|
|
85
|
+
|
|
86
|
+
To get the CLI on your `PATH` without a project virtualenv:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
uv tool install cobol-parser
|
|
90
|
+
uv tool install --editable . # from a clone, picking up code changes
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The install is pure Python by default. The PyPI wheels also carry three
|
|
94
|
+
compiled Cython accelerators (about 3x lexer throughput), used only when
|
|
95
|
+
`COBOLPARSER_ACCEL=1` is set at run time. From a clone, the same variable at
|
|
96
|
+
build time compiles them:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
pip install -e ".[fast]"
|
|
100
|
+
COBOLPARSER_ACCEL=1 python setup.py build_ext --inplace
|
|
101
|
+
export COBOLPARSER_ACCEL=1
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Quick start
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from cobolparser import parse_cobol
|
|
108
|
+
|
|
109
|
+
result = parse_cobol(source, filename="prog.cbl")
|
|
110
|
+
if result.success:
|
|
111
|
+
print(result.ast.program_name)
|
|
112
|
+
print(result.ast.to_json())
|
|
113
|
+
for error in result.errors:
|
|
114
|
+
print(error)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`parse_cobol` stops at the first error by default. To collect every error and
|
|
118
|
+
keep going, use `CobolParser(error_recovery=ErrorRecoveryMode.COLLECT_ALL)`.
|
|
119
|
+
To expand `COPY` statements, use `parse_cobol_with_expansion(source,
|
|
120
|
+
"prog.cbl", copybook_paths=["copybooks"])`.
|
|
121
|
+
|
|
122
|
+
Every analyzer has the same shape, `<Analyzer>().analyze(ast)`, and returns a
|
|
123
|
+
report with `to_dict()`:
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from cobolparser import LintAnalyzer, parse_cobol
|
|
127
|
+
|
|
128
|
+
report = LintAnalyzer().analyze(parse_cobol(source, filename="prog.cbl").ast)
|
|
129
|
+
for finding in report.findings:
|
|
130
|
+
print(finding.rule, finding.severity, finding.message)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## What it does
|
|
134
|
+
|
|
135
|
+
The CLI has one subcommand per analyzer or generator. Every subcommand emits
|
|
136
|
+
JSON by default, and takes `--help` with examples and its exit codes. The full
|
|
137
|
+
list, with every flag, is in [.okf/cli.md](.okf/cli.md#subcommand-reference).
|
|
138
|
+
|
|
139
|
+
### Check a program
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
cobol-parser lint prog.cbl --format text
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```text
|
|
146
|
+
prog.cbl:5:8: warning [unused-variables] WORKING-STORAGE item WS-NEVER-USED (level 01) is never referenced in the PROCEDURE DIVISION
|
|
147
|
+
prog.cbl:10:12: error [move-type-check] Illegal MOVE: cannot move NUMERIC item 'WS-COUNTER' to ALPHABETIC item 'WS-ALPHA'
|
|
148
|
+
prog.cbl:12:8: warning [dead-code] paragraph ORPHAN-PARA can never be reached
|
|
149
|
+
3 finding(s): 1 error, 2 warning, 0 info (9 rule(s) ran)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`lint` runs nine analyzers over one parse: dead code, unused variables, MOVE
|
|
153
|
+
type checks, I/O sequencing, LINKAGE checks, recursion risk, complexity,
|
|
154
|
+
DCLGEN and SQL/CICS checks. `--rule` narrows the run, `--min-severity` the
|
|
155
|
+
output, and `--fail-on error` exits 3 when a finding at that severity was
|
|
156
|
+
reported, so it can gate a build. Each analyzer is also its own subcommand
|
|
157
|
+
(`dead-code`, `xref`, `program-flow`, `complexity`, `health`, ...).
|
|
158
|
+
|
|
159
|
+
### Check a whole codebase
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
cobol-parser scan --glob 'src/**/*.cbl' --analyzer health --clones --cache-dir .cache
|
|
163
|
+
cobol-parser call-check src/ --copybook-path copybooks --fail-on error
|
|
164
|
+
cobol-parser codebase-graph src/ --format mermaid
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
- `scan` runs analyzers over many files in one process, with per-file fault
|
|
168
|
+
isolation and cross-file duplicate-paragraph detection. With `--cache-dir`,
|
|
169
|
+
a file whose source, copybooks and copybook directories are unchanged reuses
|
|
170
|
+
its report from the last run.
|
|
171
|
+
- `call-check` checks every `CALL` against the `PROCEDURE DIVISION USING` or
|
|
172
|
+
`ENTRY` it reaches in another file: argument count, passing mode
|
|
173
|
+
(`BY VALUE` / `BY REFERENCE`), byte length, USAGE and `RETURNING`. A
|
|
174
|
+
dynamic `CALL` is checked against every target its variable can hold.
|
|
175
|
+
- `codebase-graph` and `copybook-impact` give the call graph and the programs
|
|
176
|
+
each copybook reaches.
|
|
177
|
+
|
|
178
|
+
### Plan a change
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
cobol-parser lineage prog.cbl --field CUST-BAL
|
|
182
|
+
cobol-parser field-impact CUST-ID src/ --jcl jcl/
|
|
183
|
+
cobol-parser widen-check CUST-ID src/ --to '9(9)'
|
|
184
|
+
cobol-parser diff old/prog.cbl new/prog.cbl
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
- `lineage` follows one field's values through a program, and `field-impact`
|
|
188
|
+
follows them across programs, files, DB2 columns and JCL datasets.
|
|
189
|
+
- `widen-check` answers "what breaks if `CUST-ID` becomes `PIC 9(9)`": every
|
|
190
|
+
field downstream that would truncate the wider value, and, when the byte
|
|
191
|
+
length changes, the records whose later fields shift, the `REDEFINES` that
|
|
192
|
+
overlay it, the files whose LRECL changes (and the other programs reading
|
|
193
|
+
the same dataset), and the CALL / LINKAGE records on both sides.
|
|
194
|
+
- `diff` compares two versions by structure, so reformatting and sequence
|
|
195
|
+
numbers are no change.
|
|
196
|
+
|
|
197
|
+
### SARIF for code scanning
|
|
198
|
+
|
|
199
|
+
`lint`, `call-check` and `scan` take `--format sarif` and write a SARIF 2.1.0
|
|
200
|
+
log, which GitHub code scanning and IDE problem panes read directly:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
cobol-parser lint prog.cbl --format sarif -o lint.sarif
|
|
204
|
+
cobol-parser scan --glob 'src/**/*.cbl' --format sarif -o scan.sarif
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Generate and read test data
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
cobol-parser gen-data CUSTOMER.cpy --rows 100 --seed 7 -o customers.csv
|
|
211
|
+
cobol-parser decode CUSTMAST.dat --copybook CUSTOMER.cpy --charset ebcdic
|
|
212
|
+
cobol-parser compare expected.dat actual.dat --copybook CUSTOMER.cpy --key CUST-ID
|
|
213
|
+
cobol-parser gen-fixtures prog.cbl --scenarios all -o bundle.json
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
`gen-data` writes synthetic records that fit each field's PICTURE, USAGE and
|
|
217
|
+
level-88 values (a `seed` makes the output byte-identical across runs).
|
|
218
|
+
`decode` and `compare` read record images, ASCII or EBCDIC, fixed or
|
|
219
|
+
variable-length. `gen-fixtures` builds a test bundle for a whole program: one
|
|
220
|
+
scenario per reachable branch, the values each mocked file, CALL, SQL or CICS
|
|
221
|
+
boundary supplies, and the expectations to assert. Its schema is in
|
|
222
|
+
[docs/fixture-bundle-schema.md](docs/fixture-bundle-schema.md).
|
|
223
|
+
|
|
224
|
+
### Give an AI agent exact answers
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
pip install 'cobol-parser[mcp]'
|
|
228
|
+
claude mcp add cobol -- cobol-parser mcp --root /path/to/checkout
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
`cobol-parser mcp` is a read-only Model Context Protocol server. Its tools
|
|
232
|
+
answer "what is this program", "what is this field and where is it used",
|
|
233
|
+
"who calls this", "what does a change to this copybook reach" and "show me
|
|
234
|
+
this paragraph", with a `file:line` for every fact and a list of what they
|
|
235
|
+
could not check. See [docs/mcp-server.md](docs/mcp-server.md).
|
|
236
|
+
|
|
237
|
+
The repo also ships a `cobol-analysis` agent skill
|
|
238
|
+
([.claude/skills/cobol-analysis/SKILL.md](.claude/skills/cobol-analysis/SKILL.md))
|
|
239
|
+
that teaches an agent which subcommand answers which question.
|
|
240
|
+
|
|
241
|
+
### Project config
|
|
242
|
+
|
|
243
|
+
A `cobol.yml` at the project root sets copybook directories, source format,
|
|
244
|
+
`>>DEFINE` symbols, data encodings and lint defaults once, for every
|
|
245
|
+
subcommand. `cobol-parser config` shows which file is in effect. See
|
|
246
|
+
[docs/project-config.md](docs/project-config.md).
|
|
247
|
+
|
|
248
|
+
## Language coverage
|
|
249
|
+
|
|
250
|
+
IBM Enterprise COBOL through 6.4: fixed and free format, `COPY ... REPLACING`
|
|
251
|
+
and `REPLACE`, conditional compilation (`>>DEFINE`, `>>IF`, `>>EVALUATE`),
|
|
252
|
+
nested and contained programs, object-oriented `CLASS-ID` / `METHOD-ID`,
|
|
253
|
+
user-defined functions (`FUNCTION-ID`), DECLARATIVES, Report Writer, XML and
|
|
254
|
+
JSON statements, and `EXEC SQL`, `EXEC CICS` and `EXEC DLI` blocks. One
|
|
255
|
+
program per IBM program type (batch, VSAM, CICS, IMS, DB2, MQ, ...) runs
|
|
256
|
+
through the whole stack in the test suite; the matrix is in
|
|
257
|
+
[docs/enterprise-program-types.md](docs/enterprise-program-types.md).
|
|
258
|
+
|
|
259
|
+
## Documentation
|
|
260
|
+
|
|
261
|
+
| For | Read |
|
|
262
|
+
|---|---|
|
|
263
|
+
| Using the MCP server | [docs/mcp-server.md](docs/mcp-server.md) |
|
|
264
|
+
| The `cobol.yml` project config | [docs/project-config.md](docs/project-config.md) |
|
|
265
|
+
| The `gen-fixtures` bundle format | [docs/fixture-bundle-schema.md](docs/fixture-bundle-schema.md) |
|
|
266
|
+
| Every subcommand and flag | [.okf/cli.md](.okf/cli.md) |
|
|
267
|
+
| How the library works, area by area | [.okf/index.md](.okf/index.md) |
|
|
268
|
+
| What the backend and mocky-mock rely on | [interface-contract.md](interface-contract.md) |
|
|
269
|
+
| What changed in each release | [CHANGELOG.md](CHANGELOG.md) |
|
|
270
|
+
| Everything under `docs/`, including design plans | [docs/README.md](docs/README.md) |
|
|
271
|
+
|
|
272
|
+
The `.okf/` folder is the reference documentation: one topic file per area
|
|
273
|
+
(lexer, parser, analyzers, generators, CLI, MCP, tests), written so that a
|
|
274
|
+
person or an AI agent loads only the file for the task at hand.
|
|
275
|
+
`scripts/okf_check.py` checks what those files claim against the code.
|
|
276
|
+
|
|
277
|
+
## Development
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
pip install -e ".[dev,docs]"
|
|
281
|
+
git config core.hooksPath .githooks # the OKF pre-commit check
|
|
282
|
+
|
|
283
|
+
python -m pytest tests/ -q -n 4 --no-cov # fast full run
|
|
284
|
+
python -m pytest tests/ # with the 90% coverage floor
|
|
285
|
+
COBOLPARSER_PERF=1 python -m pytest tests/performance/test_large_program.py # 40k-line perf lane
|
|
286
|
+
|
|
287
|
+
python -m ruff check .
|
|
288
|
+
python -m black .
|
|
289
|
+
python -m mypy cobolparser/
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
CI runs only on manual dispatch (`.github/workflows/ci.yml` has no push or PR
|
|
293
|
+
trigger), so run lint, types and the full suite locally before pushing. Measure coverage on
|
|
294
|
+
the pure-Python build: with `COBOLPARSER_ACCEL=1`, coverage.py cannot see the
|
|
295
|
+
code the compiled modules replace. Test layout and markers:
|
|
296
|
+
[.okf/tests.md](.okf/tests.md).
|
|
297
|
+
|
|
298
|
+
## License
|
|
299
|
+
|
|
300
|
+
GNU Affero General Public License v3.0 or later. Copyright © 2026 Samuel Dion.
|
|
301
|
+
See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# cobol-parser
|
|
2
|
+
|
|
3
|
+
A COBOL parser for Python with an IBM Enterprise COBOL focus. It turns COBOL
|
|
4
|
+
source into a traversable AST (JSON export, error recovery, copybook
|
|
5
|
+
expansion with a source map back to the original lines), and builds static
|
|
6
|
+
analyzers, test-data generators, a z/OS JCL front end and an MCP server for AI
|
|
7
|
+
agents on top of it.
|
|
8
|
+
|
|
9
|
+
458 of the 459 NIST COBOL-85 programs in `examples/cobol/` parse cleanly (the
|
|
10
|
+
one that does not, SM101A, needs its copybooks expanded first).
|
|
11
|
+
|
|
12
|
+
[](https://www.python.org/downloads/)
|
|
13
|
+
[](https://pypi.org/project/cobol-parser/)
|
|
14
|
+
[](.okf/tests.md)
|
|
15
|
+
[](LICENSE)
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install cobol-parser # the library and the cobol-parser CLI
|
|
21
|
+
pip install 'cobol-parser[mcp]' # plus the MCP server
|
|
22
|
+
pip install 'cobol-parser[jcl]' # plus JCL (through jcl-parser)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Requires Python 3.11, 3.12 or 3.13. The core library has no runtime
|
|
26
|
+
dependencies. Optional extras:
|
|
27
|
+
|
|
28
|
+
| Extra | Adds |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `mcp` | `cobol-parser mcp`, the MCP server ([docs/mcp-server.md](docs/mcp-server.md)) |
|
|
31
|
+
| `jcl` | `cobol-parser jcl`, and the JCL joins in `field-impact`, `widen-check` and the MCP server |
|
|
32
|
+
| `pl1`, `hlasm` | PL/I and assembler programs in the MCP server's call graph |
|
|
33
|
+
| `fast` | Cython, to build the optional accelerators from source |
|
|
34
|
+
| `dev`, `docs` | the test, lint and docs toolchain for working on this repo |
|
|
35
|
+
|
|
36
|
+
To get the CLI on your `PATH` without a project virtualenv:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
uv tool install cobol-parser
|
|
40
|
+
uv tool install --editable . # from a clone, picking up code changes
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The install is pure Python by default. The PyPI wheels also carry three
|
|
44
|
+
compiled Cython accelerators (about 3x lexer throughput), used only when
|
|
45
|
+
`COBOLPARSER_ACCEL=1` is set at run time. From a clone, the same variable at
|
|
46
|
+
build time compiles them:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install -e ".[fast]"
|
|
50
|
+
COBOLPARSER_ACCEL=1 python setup.py build_ext --inplace
|
|
51
|
+
export COBOLPARSER_ACCEL=1
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Quick start
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from cobolparser import parse_cobol
|
|
58
|
+
|
|
59
|
+
result = parse_cobol(source, filename="prog.cbl")
|
|
60
|
+
if result.success:
|
|
61
|
+
print(result.ast.program_name)
|
|
62
|
+
print(result.ast.to_json())
|
|
63
|
+
for error in result.errors:
|
|
64
|
+
print(error)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`parse_cobol` stops at the first error by default. To collect every error and
|
|
68
|
+
keep going, use `CobolParser(error_recovery=ErrorRecoveryMode.COLLECT_ALL)`.
|
|
69
|
+
To expand `COPY` statements, use `parse_cobol_with_expansion(source,
|
|
70
|
+
"prog.cbl", copybook_paths=["copybooks"])`.
|
|
71
|
+
|
|
72
|
+
Every analyzer has the same shape, `<Analyzer>().analyze(ast)`, and returns a
|
|
73
|
+
report with `to_dict()`:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from cobolparser import LintAnalyzer, parse_cobol
|
|
77
|
+
|
|
78
|
+
report = LintAnalyzer().analyze(parse_cobol(source, filename="prog.cbl").ast)
|
|
79
|
+
for finding in report.findings:
|
|
80
|
+
print(finding.rule, finding.severity, finding.message)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## What it does
|
|
84
|
+
|
|
85
|
+
The CLI has one subcommand per analyzer or generator. Every subcommand emits
|
|
86
|
+
JSON by default, and takes `--help` with examples and its exit codes. The full
|
|
87
|
+
list, with every flag, is in [.okf/cli.md](.okf/cli.md#subcommand-reference).
|
|
88
|
+
|
|
89
|
+
### Check a program
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
cobol-parser lint prog.cbl --format text
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
prog.cbl:5:8: warning [unused-variables] WORKING-STORAGE item WS-NEVER-USED (level 01) is never referenced in the PROCEDURE DIVISION
|
|
97
|
+
prog.cbl:10:12: error [move-type-check] Illegal MOVE: cannot move NUMERIC item 'WS-COUNTER' to ALPHABETIC item 'WS-ALPHA'
|
|
98
|
+
prog.cbl:12:8: warning [dead-code] paragraph ORPHAN-PARA can never be reached
|
|
99
|
+
3 finding(s): 1 error, 2 warning, 0 info (9 rule(s) ran)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`lint` runs nine analyzers over one parse: dead code, unused variables, MOVE
|
|
103
|
+
type checks, I/O sequencing, LINKAGE checks, recursion risk, complexity,
|
|
104
|
+
DCLGEN and SQL/CICS checks. `--rule` narrows the run, `--min-severity` the
|
|
105
|
+
output, and `--fail-on error` exits 3 when a finding at that severity was
|
|
106
|
+
reported, so it can gate a build. Each analyzer is also its own subcommand
|
|
107
|
+
(`dead-code`, `xref`, `program-flow`, `complexity`, `health`, ...).
|
|
108
|
+
|
|
109
|
+
### Check a whole codebase
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
cobol-parser scan --glob 'src/**/*.cbl' --analyzer health --clones --cache-dir .cache
|
|
113
|
+
cobol-parser call-check src/ --copybook-path copybooks --fail-on error
|
|
114
|
+
cobol-parser codebase-graph src/ --format mermaid
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- `scan` runs analyzers over many files in one process, with per-file fault
|
|
118
|
+
isolation and cross-file duplicate-paragraph detection. With `--cache-dir`,
|
|
119
|
+
a file whose source, copybooks and copybook directories are unchanged reuses
|
|
120
|
+
its report from the last run.
|
|
121
|
+
- `call-check` checks every `CALL` against the `PROCEDURE DIVISION USING` or
|
|
122
|
+
`ENTRY` it reaches in another file: argument count, passing mode
|
|
123
|
+
(`BY VALUE` / `BY REFERENCE`), byte length, USAGE and `RETURNING`. A
|
|
124
|
+
dynamic `CALL` is checked against every target its variable can hold.
|
|
125
|
+
- `codebase-graph` and `copybook-impact` give the call graph and the programs
|
|
126
|
+
each copybook reaches.
|
|
127
|
+
|
|
128
|
+
### Plan a change
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
cobol-parser lineage prog.cbl --field CUST-BAL
|
|
132
|
+
cobol-parser field-impact CUST-ID src/ --jcl jcl/
|
|
133
|
+
cobol-parser widen-check CUST-ID src/ --to '9(9)'
|
|
134
|
+
cobol-parser diff old/prog.cbl new/prog.cbl
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
- `lineage` follows one field's values through a program, and `field-impact`
|
|
138
|
+
follows them across programs, files, DB2 columns and JCL datasets.
|
|
139
|
+
- `widen-check` answers "what breaks if `CUST-ID` becomes `PIC 9(9)`": every
|
|
140
|
+
field downstream that would truncate the wider value, and, when the byte
|
|
141
|
+
length changes, the records whose later fields shift, the `REDEFINES` that
|
|
142
|
+
overlay it, the files whose LRECL changes (and the other programs reading
|
|
143
|
+
the same dataset), and the CALL / LINKAGE records on both sides.
|
|
144
|
+
- `diff` compares two versions by structure, so reformatting and sequence
|
|
145
|
+
numbers are no change.
|
|
146
|
+
|
|
147
|
+
### SARIF for code scanning
|
|
148
|
+
|
|
149
|
+
`lint`, `call-check` and `scan` take `--format sarif` and write a SARIF 2.1.0
|
|
150
|
+
log, which GitHub code scanning and IDE problem panes read directly:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
cobol-parser lint prog.cbl --format sarif -o lint.sarif
|
|
154
|
+
cobol-parser scan --glob 'src/**/*.cbl' --format sarif -o scan.sarif
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Generate and read test data
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
cobol-parser gen-data CUSTOMER.cpy --rows 100 --seed 7 -o customers.csv
|
|
161
|
+
cobol-parser decode CUSTMAST.dat --copybook CUSTOMER.cpy --charset ebcdic
|
|
162
|
+
cobol-parser compare expected.dat actual.dat --copybook CUSTOMER.cpy --key CUST-ID
|
|
163
|
+
cobol-parser gen-fixtures prog.cbl --scenarios all -o bundle.json
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
`gen-data` writes synthetic records that fit each field's PICTURE, USAGE and
|
|
167
|
+
level-88 values (a `seed` makes the output byte-identical across runs).
|
|
168
|
+
`decode` and `compare` read record images, ASCII or EBCDIC, fixed or
|
|
169
|
+
variable-length. `gen-fixtures` builds a test bundle for a whole program: one
|
|
170
|
+
scenario per reachable branch, the values each mocked file, CALL, SQL or CICS
|
|
171
|
+
boundary supplies, and the expectations to assert. Its schema is in
|
|
172
|
+
[docs/fixture-bundle-schema.md](docs/fixture-bundle-schema.md).
|
|
173
|
+
|
|
174
|
+
### Give an AI agent exact answers
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
pip install 'cobol-parser[mcp]'
|
|
178
|
+
claude mcp add cobol -- cobol-parser mcp --root /path/to/checkout
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`cobol-parser mcp` is a read-only Model Context Protocol server. Its tools
|
|
182
|
+
answer "what is this program", "what is this field and where is it used",
|
|
183
|
+
"who calls this", "what does a change to this copybook reach" and "show me
|
|
184
|
+
this paragraph", with a `file:line` for every fact and a list of what they
|
|
185
|
+
could not check. See [docs/mcp-server.md](docs/mcp-server.md).
|
|
186
|
+
|
|
187
|
+
The repo also ships a `cobol-analysis` agent skill
|
|
188
|
+
([.claude/skills/cobol-analysis/SKILL.md](.claude/skills/cobol-analysis/SKILL.md))
|
|
189
|
+
that teaches an agent which subcommand answers which question.
|
|
190
|
+
|
|
191
|
+
### Project config
|
|
192
|
+
|
|
193
|
+
A `cobol.yml` at the project root sets copybook directories, source format,
|
|
194
|
+
`>>DEFINE` symbols, data encodings and lint defaults once, for every
|
|
195
|
+
subcommand. `cobol-parser config` shows which file is in effect. See
|
|
196
|
+
[docs/project-config.md](docs/project-config.md).
|
|
197
|
+
|
|
198
|
+
## Language coverage
|
|
199
|
+
|
|
200
|
+
IBM Enterprise COBOL through 6.4: fixed and free format, `COPY ... REPLACING`
|
|
201
|
+
and `REPLACE`, conditional compilation (`>>DEFINE`, `>>IF`, `>>EVALUATE`),
|
|
202
|
+
nested and contained programs, object-oriented `CLASS-ID` / `METHOD-ID`,
|
|
203
|
+
user-defined functions (`FUNCTION-ID`), DECLARATIVES, Report Writer, XML and
|
|
204
|
+
JSON statements, and `EXEC SQL`, `EXEC CICS` and `EXEC DLI` blocks. One
|
|
205
|
+
program per IBM program type (batch, VSAM, CICS, IMS, DB2, MQ, ...) runs
|
|
206
|
+
through the whole stack in the test suite; the matrix is in
|
|
207
|
+
[docs/enterprise-program-types.md](docs/enterprise-program-types.md).
|
|
208
|
+
|
|
209
|
+
## Documentation
|
|
210
|
+
|
|
211
|
+
| For | Read |
|
|
212
|
+
|---|---|
|
|
213
|
+
| Using the MCP server | [docs/mcp-server.md](docs/mcp-server.md) |
|
|
214
|
+
| The `cobol.yml` project config | [docs/project-config.md](docs/project-config.md) |
|
|
215
|
+
| The `gen-fixtures` bundle format | [docs/fixture-bundle-schema.md](docs/fixture-bundle-schema.md) |
|
|
216
|
+
| Every subcommand and flag | [.okf/cli.md](.okf/cli.md) |
|
|
217
|
+
| How the library works, area by area | [.okf/index.md](.okf/index.md) |
|
|
218
|
+
| What the backend and mocky-mock rely on | [interface-contract.md](interface-contract.md) |
|
|
219
|
+
| What changed in each release | [CHANGELOG.md](CHANGELOG.md) |
|
|
220
|
+
| Everything under `docs/`, including design plans | [docs/README.md](docs/README.md) |
|
|
221
|
+
|
|
222
|
+
The `.okf/` folder is the reference documentation: one topic file per area
|
|
223
|
+
(lexer, parser, analyzers, generators, CLI, MCP, tests), written so that a
|
|
224
|
+
person or an AI agent loads only the file for the task at hand.
|
|
225
|
+
`scripts/okf_check.py` checks what those files claim against the code.
|
|
226
|
+
|
|
227
|
+
## Development
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
pip install -e ".[dev,docs]"
|
|
231
|
+
git config core.hooksPath .githooks # the OKF pre-commit check
|
|
232
|
+
|
|
233
|
+
python -m pytest tests/ -q -n 4 --no-cov # fast full run
|
|
234
|
+
python -m pytest tests/ # with the 90% coverage floor
|
|
235
|
+
COBOLPARSER_PERF=1 python -m pytest tests/performance/test_large_program.py # 40k-line perf lane
|
|
236
|
+
|
|
237
|
+
python -m ruff check .
|
|
238
|
+
python -m black .
|
|
239
|
+
python -m mypy cobolparser/
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
CI runs only on manual dispatch (`.github/workflows/ci.yml` has no push or PR
|
|
243
|
+
trigger), so run lint, types and the full suite locally before pushing. Measure coverage on
|
|
244
|
+
the pure-Python build: with `COBOLPARSER_ACCEL=1`, coverage.py cannot see the
|
|
245
|
+
code the compiled modules replace. Test layout and markers:
|
|
246
|
+
[.okf/tests.md](.okf/tests.md).
|
|
247
|
+
|
|
248
|
+
## License
|
|
249
|
+
|
|
250
|
+
GNU Affero General Public License v3.0 or later. Copyright © 2026 Samuel Dion.
|
|
251
|
+
See [LICENSE](LICENSE).
|