VX/COBOL - OpenVMS COBOL to ANSI COBOL
Overview
VX/COBOL is a source-to-source translator that rewrites VMS and OpenVMS COBOL into ANSI-compliant COBOL, so existing applications compile and run on x86 Linux with no manual code changes. The translation happens at compile time: VX/COBOL emits standard COBOL text, which the target compiler then builds. Both Fujitsu NetCOBOL and Micro Focus COBOL are supported, and the original program logic and structure are preserved.
VX/COBOL is built for continuous integration. Teams keep developing in VMS and OpenVMS COBOL while each release is migrated to Linux automatically, so there is no code freeze during a long project. File handling is covered end to end by VX/RMS, and a companion runtime library supplies the callable helpers the emitted code depends on, so record access, descriptors, and OpenVMS system service calls behave the same on Linux as they did on OpenVMS.
<!-- Webflow embed (min). Source: cobol-page-technical/cobol-tech-body-embed-dark.html → python3 website/embeds/minify_webflow_embed.py … -->
<div class="s7-tech-embed" data-vxcobold-body-embed="1" data-technical-mega-embed="1" lang="en"><h2 id="architecture">Translation model and pipeline</h2><p>
VX/COBOL is a compiler front end and emitter, plus a linked runtime library. It is not a
runtime emulator: the translation is done at compile time, so VX/COBOL reads OpenVMS COBOL
and writes ordinary ANSI COBOL text, which Fujitsu NetCOBOL or Micro Focus COBOL then
compiles into a Linux executable. Source moves through a fixed set of stages, each building
on a typed model of the program rather than doing text substitution.
</p><div class="table-wrapper"><table><thead><tr><th>Stage</th><th>Role</th></tr></thead><tbody><tr><td>Source format</td><td>Handles terminal and ANSI reference formats, column stripping, comment lifting, and conditional-compilation directives.</td></tr><tr><td>Lexer</td><td>Tokenises the source stream, including VSI hexadecimal literals with their permitted whitespace.</td></tr><tr><td>Parser</td><td>Recursive-descent parser with a Pratt expression parser that builds a typed abstract syntax tree.</td></tr><tr><td>PICTURE analysis</td><td>Categorises every PIC clause: numeric, edited, or alphanumeric, with scale and sign.</td></tr><tr><td>COPY and CDD</td><td>Expands COPY and REPLACING pseudo-text and resolves <code>COPY ... FROM DICTIONARY</code> against a Common Data Dictionary.</td></tr><tr><td>EXEC scan</td><td>Surfaces EXEC SQL, ACMS, and CICS verbs and their host-variable references.</td></tr><tr><td>Resolver</td><td>Builds the symbol table and resolves qualification, subscripts, and REDEFINES.</td></tr><tr><td>Emitter</td><td>Pretty-prints the abstract syntax tree as ANSI COBOL and applies the transformation rules.</td></tr></tbody></table></div><div class="callout"><strong>Compile-time, not runtime.</strong> VX/COBOL emits standard COBOL source, so the
output is ordinary code the mainstream NetCOBOL and Micro Focus toolchains build, debug,
and profile. A separate runtime library, together with VX/RMS, supplies the callable
helpers the emitted code links against.
</div><h6>Pipeline</h6><style>.s7-tech-embed .process-flow {margin: 1.5rem 0;padding: 16px;border: 1px solid var(--s7t-border);border-radius: 10px;background: rgba(255, 255, 255, 0.01);}.s7-tech-embed .process-endpoint {display: grid;grid-template-columns: 72px minmax(0, 1fr);gap: 14px;align-items: center;padding: 14px 16px;border-radius: 8px;background: var(--s7t-surface);color: var(--s7t-text);}.s7-tech-embed .process-output {border: 1px solid var(--s7t-note-bd);background: var(--s7t-note-bg);}.s7-tech-embed .process-label,.s7-tech-embed .process-number {font-family: var(--s7t-mono);color: var(--s7t-accent);font-size: 0.76em;font-weight: 700;letter-spacing: 0.08em;text-transform: uppercase;}.s7-tech-embed .process-endpoint div,.s7-tech-embed .process-stage {min-width: 0;}.s7-tech-embed .process-endpoint strong,.s7-tech-embed .process-endpoint span:last-child,.s7-tech-embed .process-stage strong,.s7-tech-embed .process-stage span:last-child {display: block;}.s7-tech-embed .process-endpoint strong,.s7-tech-embed .process-stage strong {margin-bottom: 4px;color: var(--s7t-text);}.s7-tech-embed .process-endpoint span:last-child,.s7-tech-embed .process-stage span:last-child {color: var(--s7t-muted);font-size: 0.9em;line-height: 1.45;}.s7-tech-embed .process-stages {display: grid;grid-template-columns: repeat(3, minmax(0, 1fr));gap: 10px;margin: 10px 0;}.s7-tech-embed .process-stage {padding: 15px;border-top: 3px solid var(--s7t-accent);border-radius: 6px;background: var(--s7t-surface2);color: var(--s7t-text);}.s7-tech-embed .process-stage .process-number {margin-bottom: 10px;}@media (max-width: 800px) {.s7-tech-embed .process-stages {grid-template-columns: 1fr;}.s7-tech-embed .process-endpoint {grid-template-columns: 1fr;gap: 5px;}}</style><div class="process-flow" aria-label="VX/COBOL translation pipeline"><div class="process-endpoint"><span class="process-label">Input</span><div><strong>OpenVMS COBOL</strong><span><code>.cob</code> source or <code>.lib</code> copy library</span></div></div><div class="process-stages" role="list" aria-label="Translation stages"><div class="process-stage" role="listitem"><span class="process-number">01</span><strong>Source format</strong><span>Normalises the OpenVMS COBOL source format for processing.</span></div><div class="process-stage" role="listitem"><span class="process-number">02</span><strong>Lexer</strong><span>Tokenises the normalised source stream.</span></div><div class="process-stage" role="listitem"><span class="process-number">03</span><strong>Parser</strong><span>Builds the typed program model from the token stream.</span></div><div class="process-stage" role="listitem"><span class="process-number">04</span><strong>Resolver</strong><span>Resolves symbols, qualification, subscripts, and data relationships.</span></div><div class="process-stage" role="listitem"><span class="process-number">05</span><strong>Emitter</strong><span>Writes ANSI COBOL as <code>.cob</code> source plus a per-file <code>.log</code>.</span></div><div class="process-stage" role="listitem"><span class="process-number">06</span><strong>Target compiler</strong><span>NetCOBOL or Micro Focus COBOL compiles the emitted ANSI COBOL.</span></div></div><div class="process-endpoint process-output"><span class="process-label">Output</span><div><strong>x86 Linux executable</strong><span>Native binary built from the translated ANSI COBOL</span></div></div></div><h6>Input file types</h6><div class="table-wrapper"><table><thead><tr><th>Extension</th><th>Meaning</th></tr></thead><tbody><tr><td><code>.cob</code></td><td>COBOL source.</td></tr><tr><td><code>.lib</code></td><td>COBOL copy library.</td></tr><tr><td><code>.pco</code></td><td>Oracle Pro*COBOL source; processed by the Pro*COBOL precompiler after VX/COBOL runs.</td></tr><tr><td><code>.flg</code></td><td>FMS form file, compiled to its binary form by the FMS tooling.</td></tr></tbody></table></div><h2 id="dialect-coverage">Source dialect coverage</h2><p>
VX/COBOL parses the OpenVMS and VSI COBOL dialect into a typed model, so it understands the
constructs a real estate uses rather than passing them through as text. The matrix below
tracks coverage against the VSI COBOL reference language and groups each area into a support
bucket. The great majority of the language is fully typed and live; the remaining gaps are
narrow and named.
</p><div class="table-wrapper"><table><thead><tr><th>Language area</th><th>Support</th></tr></thead><tbody><tr><td>IDENTIFICATION and ENVIRONMENT divisions (PROGRAM-ID, COMMON/INITIAL/RECURSIVE, OPTIONS ARITHMETIC)</td><td><span class="ac-live">live</span></td></tr><tr><td>SPECIAL-NAMES (DECIMAL-POINT, CURRENCY, ALPHABET, CLASS, SYMBOLIC, switches, mnemonics)</td><td><span class="ac-live">live</span></td></tr><tr><td>FILE-CONTROL / SELECT (organization, access mode, keys, FILE STATUS, LOCK MODE, RESERVE, CODE-SET)</td><td><span class="ac-live">live</span></td></tr><tr><td>I-O-CONTROL (SAME AREA, MULTIPLE FILE, RERUN, APPLY LOCK-HOLDING)</td><td><span class="ac-live">live</span></td></tr><tr><td>FD and SD clauses (BLOCK/RECORD CONTAINS, LABEL, VALUE OF ID, LINAGE, CODE-SET)</td><td><span class="ac-live">live</span></td></tr><tr><td>Data description (PIC, USAGE, VALUE, OCCURS, REDEFINES, RENAMES, 88-level, SIGN, SYNC, JUST)</td><td><span class="ac-live">live</span></td></tr><tr><td>USAGE variants (DISPLAY, COMP-1 through COMP-6, COMP-X, PACKED-DECIMAL, INDEX, POINTER, POINTER-64, NATIONAL)</td><td><span class="ac-live">live</span></td></tr><tr><td>78-level constants and ANY LENGTH items</td><td><span class="ac-live">live</span></td></tr><tr><td>Report Section and Screen Section descriptions</td><td><span class="ac-live">live</span></td></tr><tr><td>Procedure verbs (the 30 fully typed statements from ACCEPT through WRITE)</td><td><span class="ac-live">live</span></td></tr><tr><td>INSPECT, SET (all forms), and REPLACE</td><td><span class="ac-live">live</span></td></tr><tr><td>Conditions (relation, class, sign, 88-level, combined, VSI SUCCESS/FAILURE)</td><td><span class="ac-live">live</span></td></tr><tr><td>Expressions (intrinsics, reference modification, qualification, subscripts, special registers)</td><td><span class="ac-live">live</span></td></tr><tr><td>COPY, CDD, and REPLACE (including COPY FROM DICTIONARY and SUPPRESS)</td><td><span class="ac-live">live</span></td></tr><tr><td>EXEC SQL, ACMS, and CICS bodies (verb and host variables scanned; body passed through)</td><td><span class="ac-v1">v1 soon</span></td></tr><tr><td>Report descriptor NEXT GROUP and a handful of verb sub-phrases</td><td><span class="ac-v1">v1 soon</span></td></tr><tr><td>TYPEDEF and TYPE (VSI typed-data extension)</td><td><span class="ac-v2">v2</span></td></tr><tr><td>Screen Section ERASE, BLANK REMAINDER, PROMPT, and SIZE clauses</td><td><span class="ac-v2">v2</span></td></tr><tr><td>OOP COBOL structural units (CLASS-ID, METHOD-ID, FACTORY, REPOSITORY)</td><td><span class="ac-no">out of scope</span></td></tr><tr><td>Communication Section and CD entries</td><td><span class="ac-no">out of scope</span></td></tr></tbody></table></div><div class="callout"><strong>Named gaps, not silent ones.</strong> Any construct the translator cannot fully
represent is counted and named in the per-file log rather than dropped. The surviving
structural gaps are OOP COBOL units, structured EXEC SQL prepared statements, the
Communication Section, and the TYPEDEF/TYPE extension.
</div><h2 id="transformations">Transformation rules</h2><p>
The emitter applies a catalogue of transformation rules, grouped by division and phase so
each change is traceable. The families below cover everything from lexical spelling through
system-service calls and an optional directed-changes file. The counts show how much of each
area is handled automatically.
</p><div class="table-wrapper"><table><thead><tr><th>Family</th><th>Focus</th><th>Rules</th></tr></thead><tbody><tr><td>Lexical and identifiers</td><td>Spelling, casing, name length, reserved-word collisions</td><td>10</td></tr><tr><td>Identification</td><td>PROGRAM-ID handling and recursion</td><td>2</td></tr><tr><td>Environment</td><td>Configuration headers, file assignment, locking, sequential organization</td><td>7</td></tr><tr><td>Data division</td><td>Usage, pointers, descriptors, runtime copybooks, RMS registers</td><td>17</td></tr><tr><td>Procedure division</td><td>Statement rewrites, precision, initialisation, file verbs</td><td>29</td></tr><tr><td>CALL and system services</td><td>Argument modes, padding, SYS$ to COB$ remapping</td><td>10</td></tr><tr><td>EXEC SQL and Pro*COBOL</td><td>Embedded SQL name and include rewrites</td><td>10</td></tr><tr><td>Runtime copybooks</td><td>Injected working-storage support modules</td><td>7</td></tr><tr><td>Directed changes</td><td>Optional control-file directives that override heuristics</td><td>16</td></tr></tbody></table></div><h6>Identifiers and lexical</h6><ul><li>Comment indicators (<code>*</code>, <code>/</code>, <code>!</code>) become the inline form <code>*></code>, leaving the comment text untouched.</li><li>Identifiers and reserved words are upper-cased, and a hyphen inside a name becomes an underscore.</li><li>Names longer than 30 characters are truncated to fit the ANSI limit.</li><li>A <code>$</code> inside an identifier becomes <code>x</code> (configurable), but this substitution never applies inside a CALL literal.</li><li>A user name that collides with a NetCOBOL reserved word gets an <code>_R</code> suffix.</li><li><code>VALUE EXTERNAL</code> symbols are resolved to compile-time constants instead of link-time symbols.</li></ul><h6>Environment and file control</h6><ul><li><code>APPLY LOCK-HOLDING</code> in <code>I-O-CONTROL</code> is commented out, and each listed file gains <code>LOCK MODE IS AUTOMATIC</code> on its SELECT.</li><li><code>ORGANIZATION IS SEQUENTIAL</code> becomes <code>LINE SEQUENTIAL</code> for non-indexed, non-relative files.</li><li>Indexed files pick up the external file handler suffix on their <code>ASSIGN TO</code> so record access routes through the runtime.</li><li>Missing <code>CONFIGURATION SECTION</code> and <code>SPECIAL-NAMES</code> headers are inserted where the target compiler requires them.</li></ul><h6>Data division</h6><ul><li><code>COMP</code>, <code>COMP-1</code> through <code>COMP-6</code>, <code>COMP-X</code>, and <code>BINARY</code> are normalised to <code>COMP-5</code>.</li><li><code>POINTER VALUE REFERENCE</code>, which NetCOBOL rejects, becomes <code>POINTER VALUE NULL</code> plus a <code>MOVE FUNCTION ADDR(...)</code> in a generated init section.</li><li>32-bit descriptors are widened for 64-bit builds, and 64-bit pointers stored as <code>PIC S9(9) COMP</code> become <code>POINTER</code>.</li><li>Four runtime support copybooks are injected at the top of WORKING-STORAGE, along with a version marker.</li><li>RMS special-register structures are emitted per file so status and filename registers are available.</li></ul><h6>Procedure division</h6><ul><li><code>PROCEDURE DIVISION ... GIVING</code> becomes <code>... RETURNING</code>, paired with a generated return item.</li><li>A <code>COMPUTE</code> that contains a division gets a precision term appended, preserving VSI intermediate precision.</li><li><code>STOP RUN</code> becomes <code>MOVE 0 TO PROGRAM-STATUS</code> followed by <code>EXIT PROGRAM</code>.</li><li><code>OPEN</code>, <code>READ</code>, <code>WRITE</code>, and <code>START</code> drop <code>ALLOWING</code> and <code>REGARDLESS</code> clauses; <code>REGARDLESS OF LOCK</code> becomes <code>WITH NO LOCK</code>.</li><li><code>SET p TO REFERENCE OF v</code> becomes <code>MOVE FUNCTION ADDR(v) TO p</code>.</li></ul><h6>CALL and system services</h6><ul><li><code>GIVING</code> on a CALL becomes <code>RETURNING</code>, and each <code>OMITTED</code> argument becomes <code>BY VALUE 0</code>.</li><li>The CALL literal name is passed verbatim, so a literal such as <code>CALL "ACMS$SIGN_IN"</code> is left unchanged.</li><li><code>BY DESCRIPTOR</code> arguments are emitted as 64-bit OpenVMS string descriptors.</li><li>Arguments are padded with <code>BY VALUE 0</code> to each callee's expected count, using a built-in routine table.</li><li>Item-list bearing <code>SYS$</code> services are renamed to their <code>COB$</code> counterparts (15 services) so a 64-bit-aware implementation is called.</li></ul><h6>Directed changes</h6><p>
An optional control file lets a migration override the translator's heuristics without
touching source. Directives cover recursive programs, external file handler on and off,
external and pointer definitions, descriptor sizing, the dollar-sign replacement character,
dash preservation in file, procedure, and label names, and database copybook injection.
Unrecognised directives are skipped rather than treated as errors.
</p><h2 id="examples">Before and after</h2><p>
These worked examples show the translator rewriting real OpenVMS COBOL constructs into ANSI
COBOL. The identifiers use a banking demo estate; the syntax is exactly what VX/COBOL emits.
</p><h6>CALL rewrite: RETURNING, BY VALUE, and SYS$ to COB$</h6><p>A system-service call using <code>GIVING</code>, <code>OMITTED</code> arguments, and an item-list service:</p>
<pre><span class="kw">PROCEDURE DIVISION</span>.
MAIN.
<span class="kw">CALL</span> <span class="str">"SYS$GETJPIW"</span> <span class="kw">USING</span>
<span class="kw">BY VALUE</span> EFN
<span class="kw">BY REFERENCE</span> PID
<span class="kw">OMITTED</span>
<span class="kw">BY REFERENCE</span> ITEM-LIST
<span class="kw">BY REFERENCE</span> IO-STATUS
<span class="kw">OMITTED</span>
<span class="kw">OMITTED</span>
<span class="kw">GIVING</span> RET-STATUS
<span class="kw">STOP RUN</span>.</pre>
<p>becomes:</p>
<pre><span class="kw">PROCEDURE DIVISION</span>.
MAIN.
<span class="kw">CALL</span> <span class="str">"COB$GETJPIW"</span> <span class="kw">USING</span>
<span class="kw">BY VALUE</span> EFN
<span class="kw">BY REFERENCE</span> PID
<span class="kw">BY VALUE</span> 0
<span class="kw">BY REFERENCE</span> ITEM-LIST
<span class="kw">BY REFERENCE</span> IO-STATUS
<span class="kw">BY VALUE</span> 0
<span class="kw">BY VALUE</span> 0
<span class="kw">RETURNING</span> RET-STATUS
<span class="cmt">*> STOP RUN lowered to MOVE 0 TO PROGRAM-STATUS + EXIT PROGRAM</span></pre>
<p>
The item-list service <code>SYS$GETJPIW</code> is remapped to <code>COB$GETJPIW</code>,
<code>GIVING</code> becomes <code>RETURNING</code>, and every <code>OMITTED</code> argument
becomes <code>BY VALUE 0</code> so the argument positions stay correct.
</p><h6>COMPUTE precision on division</h6>
<pre><span class="kw">COMPUTE</span> FEE-PCT <span class="kw">ROUNDED</span> = (FEE-AMT / TOTAL-AMT) * 100
<span class="kw">COMPUTE</span> GROSS-AMT = FEE-AMT + TOTAL-AMT</pre>
<p>becomes:</p>
<pre><span class="kw">COMPUTE</span> FEE-PCT <span class="kw">ROUNDED</span> = (FEE-AMT / TOTAL-AMT) * 100 + S7_PREC
<span class="kw">COMPUTE</span> GROSS-AMT = FEE-AMT + TOTAL-AMT</pre>
<p>
Only the statement that contains a division gets the precision term appended, matching the
VSI intermediate-precision behaviour. The division-free <code>COMPUTE</code> is left as is.
</p><h6>Indexed file assignment</h6>
<pre><span class="kw">SELECT</span> ACCOUNT-FILE <span class="kw">ASSIGN TO</span> <span class="str">"ACCOUNTS.DAT"</span>
<span class="kw">ORGANIZATION IS INDEXED</span>
<span class="kw">ACCESS MODE IS DYNAMIC</span>
<span class="kw">RECORD KEY IS</span> ACCT-ID.
<span class="kw">SELECT</span> AUDIT-FILE <span class="kw">ASSIGN TO</span> <span class="str">"AUDIT.LOG"</span>.</pre>
<p>becomes:</p>
<pre><span class="kw">SELECT</span> ACCOUNT-FILE <span class="kw">ASSIGN TO</span> <span class="str">"ACCOUNTS.DAT,EXFH"</span>
<span class="kw">ORGANIZATION IS INDEXED</span>
<span class="kw">ACCESS MODE IS DYNAMIC</span>
<span class="kw">RECORD KEY IS</span> ACCT-ID.
<span class="kw">SELECT</span> AUDIT-FILE <span class="kw">ASSIGN TO</span> <span class="str">"AUDIT.LOG"</span>.</pre>
<p>
The indexed file routes through the external file handler, so VX/RMS performs the record
access; the non-indexed audit file is left unchanged.
</p><h6>File locking</h6>
<pre><span class="kw">I-O-CONTROL</span>.
<span class="kw">APPLY LOCK-HOLDING ON</span> ACCOUNT-FILE.</pre>
<p>becomes:</p>
<pre><span class="cmt">*> APPLY LOCK-HOLDING ON ACCOUNT-FILE</span>
<span class="cmt">*> relocated as LOCK MODE IS AUTOMATIC on the ACCOUNT-FILE SELECT</span>
<span class="kw">SELECT</span> ACCOUNT-FILE <span class="kw">ASSIGN TO</span> <span class="str">"ACCOUNTS.DAT,EXFH"</span>
<span class="kw">LOCK MODE IS AUTOMATIC</span>
<span class="kw">ORGANIZATION IS INDEXED</span>.</pre>
<p>
Record-locking intent carries over without manual rework: the OpenVMS
<code>APPLY LOCK-HOLDING</code> clause is dropped from <code>I-O-CONTROL</code> and the file
picks up <code>LOCK MODE IS AUTOMATIC</code> in FILE-CONTROL.
</p><h2 id="runtime">Runtime library and copybooks</h2><p>
The emitted ANSI COBOL links against a Sector7 runtime that provides the OpenVMS behaviour
the source relied on. Four support copybooks are injected at the top of WORKING-STORAGE, and
together they form the contract between the migrated program and the runtime.
</p><div class="table-wrapper"><table><thead><tr><th>Copybook</th><th>Contents</th></tr></thead><tbody><tr><td>Data types</td><td>Signed and unsigned 16, 32, and 64-bit type definitions, plus the 64-bit descriptor and item-list layouts.</td></tr><tr><td>Descriptors</td><td>Fixed-capacity literal, descriptor, numeric-descriptor, and pointer arrays used to marshal call arguments.</td></tr><tr><td>Item lists</td><td>The 64-bit item-list array used by remapped item-list system services.</td></tr><tr><td>Constants</td><td>Success and failure constants, the precision constant, display and status helpers, and the external file handler suffix.</td></tr><tr><td>SQLCA</td><td>The Oracle SQLCA layout that replaces the VSI SQLCA include on the embedded-SQL path.</td></tr></tbody></table></div><div class="callout"><strong>Fixed-capacity marshalling.</strong> The descriptor and item-list arrays have set
capacities sized to the constructs seen in production estates. A single call needing more
descriptor slots than the array provides is reported rather than silently truncated.
</div><h6>File I/O and RMS</h6><p>
File operations route through <a href="/technical/vx-rms-sys-routines-for-rms">VX/RMS</a>, so
<code>OPEN</code>, <code>READ</code>, <code>WRITE</code>, <code>REWRITE</code>,
<code>DELETE</code>, <code>START</code>, and <code>CLOSE</code> behave identically to OpenVMS
RMS. The runtime keeps each file's last RMS status so the RMS status special registers work
as before, and record locking follows the <code>LOCK MODE IS AUTOMATIC</code> relocation
applied during translation.
</p><h6>System services</h6><p>
OpenVMS system service and run-time library calls resolve against the runtime rather than
the VMS executive. Item-list services are remapped to their <code>COB$</code> counterparts,
argument descriptors are built in the 64-bit layout, and the run-time library entry points
provide the same signatures and status conventions the original code expects.
</p><h2 id="compatibility">Compilers, targets, and compatibility</h2><p>
VX/COBOL produces ANSI COBOL for the two mainstream COBOL compilers on Linux and preserves
the OpenVMS behaviours that applications depend on. The matrix summarises what is supported
and where each capability stands.
</p><div class="table-wrapper"><table><thead><tr><th>Capability</th><th>Support</th></tr></thead><tbody><tr><td>Target compilers: Fujitsu NetCOBOL and Micro Focus COBOL</td><td><span class="ac-live">live</span></td></tr><tr><td>Target platform: x86 Linux</td><td><span class="ac-live">live</span></td></tr><tr><td>32-bit and 64-bit architecture differences adjusted automatically</td><td><span class="ac-live">live</span></td></tr><tr><td>OpenVMS RMS file handling through VX/RMS</td><td><span class="ac-live">live</span></td></tr><tr><td>OpenVMS system services and run-time library via the COB$ runtime</td><td><span class="ac-live">live</span></td></tr><tr><td>Embedded SQL for Rdb and Oracle through the EXEC SQL and Pro*COBOL path</td><td><span class="ac-v1">v1 soon</span></td></tr></tbody></table></div><h6>Continuous integration without a code freeze</h6><p>
Because conversion is fully automated, a team keeps developing in VMS and OpenVMS COBOL
while each release is translated to Linux on demand. There is no code freeze during a long
migration, and functionality is preserved across the estate. Large applications of several
million lines convert in minutes, so the migrated build can track the OpenVMS source
release by release.
</p><h6>How this differs from an emulator or a rewrite</h6><p>
VX/COBOL is neither a hand rewrite nor a runtime emulator. It is a compile-time translator
that emits ordinary ANSI COBOL, so the result is standard source that NetCOBOL or Micro
Focus builds, and developers can read, debug, and maintain the output with mainstream tools.
Every transformation is recorded in a per-file log, and any construct the translator cannot
represent is named rather than dropped, so the migration is auditable rather than a black
box.
</p><h2 id="quick-reference">Quick reference</h2><h6>Pipeline</h6><p><code>source format → lexer → parser → resolver → emitter</code>, then compile the emitted ANSI COBOL with NetCOBOL or Micro Focus.</p>
<pre><span class="cmt">1. Translate: OpenVMS COBOL in, ANSI COBOL out (plus a per-file .log)</span>
source.cob -> source.cob (ANSI) + source.log
<span class="cmt">2. Compile the emitted ANSI COBOL with NetCOBOL</span>
cobol -dy -i COBOL.OPT -c source.cob</pre>
<h6>Signature transforms to remember</h6><div class="table-wrapper"><table><thead><tr><th>OpenVMS COBOL</th><th>ANSI COBOL</th></tr></thead><tbody><tr><td><code>GIVING</code></td><td><code>RETURNING</code></td></tr><tr><td><code>OMITTED</code></td><td><code>BY VALUE 0</code></td></tr><tr><td><code>COMP</code>, <code>COMP-1..6</code>, <code>COMP-X</code>, <code>BINARY</code></td><td><code>COMP-5</code></td></tr><tr><td><code>ORGANIZATION IS SEQUENTIAL</code></td><td><code>LINE SEQUENTIAL</code></td></tr><tr><td><code>APPLY LOCK-HOLDING</code></td><td><code>LOCK MODE IS AUTOMATIC</code></td></tr><tr><td><code>$</code> in an identifier</td><td><code>x</code> (not inside a CALL literal)</td></tr><tr><td>Item-list <code>SYS$</code> services</td><td><code>COB$</code> counterparts (15 services)</td></tr><tr><td><code>COMPUTE</code> with division</td><td>precision term appended</td></tr></tbody></table></div><h6>Rule families</h6><div class="kw-grid"><div>Lexical: 10</div><div>Identification: 2</div><div>Environment: 7</div><div>Data: 17</div><div>Procedure: 29</div><div>CALL / services: 10</div><div>EXEC SQL: 10</div><div>Copybooks: 7</div><div>Directed changes: 16</div></div></div>