Перейти к основному содержимому

5.16. Основы языка

Разработчику Архитектору

Основы языка Cobol

Основы языка

COBOL (Common Business-Oriented Language) — один из самых ранних высокоуровневых языков программирования, разработанный в конце 1950-х годов для решения задач, связанных с обработкой больших объёмов структурированных данных в коммерческих, финансовых и административных системах. Его появление стало ответом на растущую потребность в стандартизации программного обеспечения для бизнес-приложений, в условиях, когда большинство существовавших ранее решений были написаны на машинных кодах или ассемблерах, затруднявших сопровождение, переносимость и обучение.

Особенностью COBOL является его направленность не на вычислительную эффективность, а на читаемость, надёжность и соответствие бизнес-логике. Он изначально создавался не для математиков или инженеров по вычислительной технике, а для аналитиков, бухгалтеров, экономистов — специалистов, которым нужно было точно описывать операции над данными, не углубляясь в детали архитектуры вычислительных систем. Поэтому язык был спроектирован как англоязычный по своей природе: его синтаксис приближён к естественной речи, что делает программы в определённой степени самодокументируемыми. Такой подход был революционным для своего времени и предвосхитил многие принципы, позже реализованные в предметно-ориентированных языках (DSL) и современных фреймворках для бизнес-логики (например, в BPMN-движках или бизнес-правилах в ELMA365 — хотя, конечно, прямой аналогии здесь проводить некорректно).

Несмотря на возраст, COBOL остаётся критически важным для мировой экономики: по оценкам конца 2020-х годов, в активной эксплуатации находятся сотни миллиардов строк COBOL-кода; значительная часть банковских транзакций, систем пенсионного обеспечения, страхования и государственного учёта по-прежнему опирается на COBOL-приложения, работающие на мейнфреймах IBM z/OS. Это не «устаревший» код в смысле неработоспособности, а устойчивая инфраструктурная прослойка, демонстрирующая свойство долговечности через избыточную строгость — свойство, заложенное в саму архитектуру языка.


Синтаксис: проектирование для ясности, а не для краткости

Синтаксис COBOL принципиально отличается от принятого в большинстве современных языков. Он не стремится к лаконичности или выразительности через символы; напротив, он избыточен, многословен и повторяет одни и те же конструкции с целью исключения неоднозначности. Эта черта является следствием его главного проектного решения: язык должен быть понятен не только программисту, но и лицу, принимающему бизнес-решения.

Рассмотрим простейшую программу, выводящую фразу «Hello, World!»:

       IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO-WORLD.
PROCEDURE DIVISION.
DISPLAY 'Hello, World!'.
STOP RUN.

Уже в этом фрагменте проявляются ключевые синтаксические особенности:

  1. Отступы и зоны в колонках (в классическом COBOL-85 и ранее): исходный код COBOL исторически размещался в фиксированных колонках punched card (перфокарт), где:
    • колонки 1–6 — номера строк (для меток и ссылок);
    • колонка 7 — индикаторная: * — комментарий, / — новая страница, - — продолжение строки;
    • колонки 8–11 — зона A (начало разделов, параграфов, секций);
    • колонки 12–72 — зона B (операторы, описания переменных и т.п.);
    • колонки 73–80 — не использовались (иногда для версий или отметок).

В современных реализациях (COBOL-2002, COBOL-2014 и далее) допускается свободный формат (free format), устраняющий жёсткие требования к колонкам, но даже в свободном формате сохраняется многословность синтаксиса. Например, условный оператор IF требует явного завершения END-IF, в отличие от фигурных скобок в C-подобных языках:

       IF AMOUNT > 1000
DISPLAY 'High-value transaction'
ELSE
DISPLAY 'Standard transaction'
END-IF

Заметно, что ключевые слова (IF, ELSE, END-IF, DISPLAY, STOP RUN) написаны заглавными буквами не по требованию синтаксиса, а по конвенции — в COBOL регистр игнорируется. Тем не менее, преобладание заглавных букв в традиционном коде — это дань унаследованной практике, усиливающая визуальную чёткость структуры.

Также важно: COBOL использует точку (.) как обязательный терминатор для большинства операторов, но её постановка регулируется строгими правилами контекста. Например, точка после STOP RUN завершает параграф, а отсутствие точки после DISPLAY — ошибка. В более поздних стандартах (начиная с COBOL-85) рекомендуется использовать scoped terminators — такие как END-IF, END-PERFORM, END-EVALUATE — для явного ограничения блоков, что значительно снижает риски ошибок, связанных с «потерянной» точкой.


Структурная организация: четыре раздела как фундамент

Любая COBOL-программа строго структурирована и состоит из четырёх обязательных разделов (divisions), расположенных в фиксированном порядке. Эта иерархия — не просто соглашение, а синтаксическое требование: нарушение порядка делает программу недопустимой. Каждый раздел имеет свою семантическую роль и содержит вложенные секции (sections) и параграфы (paragraphs), образуя древовидную структуру документа.

1. IDENTIFICATION DIVISION — идентификация программы

Это самый короткий, но обязательный раздел, содержащий метаданные о программе. Его основная секция — PROGRAM-ID, где указывается уникальное имя программы (до 30 символов в большинстве реализаций), используемое при линковке и вызовах из других программ.

       IDENTIFICATION DIVISION.
PROGRAM-ID. PAYROLL-PROCESSING.
AUTHOR. T. VLADISLAVOVICH.
DATE-WRITTEN. 2025-11-06.
DATE-COMPILED. CURRENT-DATE.

Хотя поля AUTHOR, DATE-WRITTEN и DATE-COMPILED не являются обязательными (и не влияют на выполнение), они традиционно используются для аудита, версионирования и поддержки. В современных системах управления версиями такая информация, конечно, дублируется в метаданных репозитория, но в мире мейнфреймов, где COBOL по-прежнему доминирует, эти поля часто интегрируются в инструменты анализа зависимостей и impact assessment.

2. ENVIRONMENT DIVISION — описание среды исполнения

Этот раздел связывает логику программы с физической средой: файловой системой, устройствами ввода-вывода, конфигурацией оборудования. Он состоит из двух секций:

  • CONFIGURATION SECTION — определяет систему (SOURCE-COMPUTER, OBJECT-COMPUTER), специфические параметры (например, SPECIAL-NAMES для переименования TRUE/FALSE или указания валютного символа).
  • INPUT-OUTPUT SECTION — содержит FILE-CONTROL, где перечисляются все внешние файлы, используемые программой, с указанием их логических имён и соответствия физическим дескрипторам (в z/OS — DD-имёнам в JCL).

Пример:

       ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT EMPLOYEE-FILE ASSIGN TO EMPDD
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS WS-FILE-STATUS.

Здесь EMPLOYEE-FILE — логическое имя файла внутри программы, а EMPDD — физический дескриптор, задаваемый в управляющей задаче (например, в Job Control Language). Это разделение позволяет переносить программу между разными окружениями без изменения исходного кода — важнейшая черта для enterprise-развёртываний.

3. DATA DIVISION — описание данных

Наиболее объёмный и значимый раздел. В нём полностью декларируется структура всех данных, с которыми работает программа: входные/выходные файлы, промежуточные переменные, константы, таблицы. Это — сердце COBOL: язык не допускает необъявленных переменных, а каждое поле данных имеет строгую типизацию, длину, формат и иерархическое положение.

DATA DIVISION состоит из трёх частей (не все обязательны, но обычно присутствуют):

  • FILE SECTION — описывает записи (records) внешних файлов. Каждый FD (File Description) определяет макет записи, вплоть до байтового выравнивания.
  • WORKING-STORAGE SECTION — область для временных переменных, существующих на протяжении всего выполнения программы.
  • LINKAGE SECTION — содержит данные, передаваемые извне (например, при вызове подпрограммы или через CICS-транзакцию).

Структура данных в COBOL иерархическая и описывается через уровни (level numbers). Уровень 01 — корневая запись; уровни 05, 10, 15 и т.д. — подполя. Особое значение имеют уровни 66 (для RENAMES) и 88 (для условных имён — аналогов именованных констант-булевых флагов).

Пример фрагмента WORKING-STORAGE:

       DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-CURRENT-DATE.
05 WS-YEAR PIC 9(4).
05 WS-MONTH PIC 9(2).
05 WS-DAY PIC 9(2).

01 WS-EMPLOYEE-RECORD.
05 EMP-ID PIC X(10).
05 EMP-NAME PIC X(30).
05 EMP-SALARY PIC 9(7)V99.
05 EMP-STATUS PIC X.
88 ACTIVE VALUE 'A'.
88 INACTIVE VALUE 'I'.
88 TERMINATED VALUE 'T'.

Здесь PIC (PICTURE) — спецификатор формата. 9 — цифра, X — любой символ, V — неявная десятичная точка (без физического хранения символа точки). Таким образом, PIC 9(7)V99 означает число до 9 999 999.99, хранящееся как 9-значное целое (в формате packed decimal или zoned decimal — в зависимости от компилятора и USAGE).

Уровень 88 позволяет писать условные выражения вида IF ACTIVE вместо IF EMP-STATUS = 'A', повышая читаемость и снижая риск опечаток.

4. PROCEDURE DIVISION — исполняемая логика

Единственный раздел, содержащий исполняемые операторы. Он организован в виде иерархии параграфов (paragraphs) — именованных блоков кода, которые можно вызывать через PERFORM. Параграфы не имеют параметров и возврата, но могут манипулировать данными из DATA DIVISION.

       PROCEDURE DIVISION.
MAIN-LOGIC.
PERFORM INITIALIZE-PROGRAM
PERFORM READ-EMPLOYEE-FILE UNTIL EOF-FLAG = 'Y'
PERFORM FINALIZE-REPORT
STOP RUN.

INITIALIZE-PROGRAM.
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE
OPEN INPUT EMPLOYEE-FILE
...

Важно: в COBOL нет понятия «функции» в современном смысле (до стандарта 2002 года). Логика строится через композицию параграфов, управляемых потоком PERFORM — явное указание на процедурную, линейную природу языка. Даже циклы реализуются как PERFORM ... VARYING или PERFORM ... UNTIL, а не через for/while.