Parsers and transpilers that turn source code into something you can query, check and move.
Every serious modernization runs on a parser. We build custom ones for languages nobody else supports, license the engines we have already built, and write the transpilers that carry code from an old platform to a new one.
Three ways in, one foundation underneath: an open AST framework, no proprietary intermediate representation, and tooling you keep.
- Inventory an estate nobody fully knows any more
- Trace one field across programs, files and screens
- Find the dead code before you pay to move it
- Generate documentation from the source, not from memory
- Translate to a modern language, statement by statement
Text search cannot do any of this. It has no idea what a name refers to.
Three ways in
Which one you need depends on a single question: does a parser for your language already exist, and do you want to run it yourself or have us build on top of it?
Custom parsers
For the languages the market has forgotten, and for the in-house dialect that only your company runs. We design the grammar, model the abstract syntax, and hand over a parser your team can build on—with the tests and the coverage measurements that prove what it handles.
License a Language Engine
We have already built parsers for fifteen languages, from RPG and COBOL to SAS, PL/SQL and VB6. You license one, run it in your own product or your own pipeline, and start from a working engine instead of from a grammar file.
Transpilers
A parser reads the old system; a transpiler writes the new one. We build the translation on top of the engine, then tune it against your codebase until the output is code your own developers would have written—not a mechanical transliteration nobody wants to maintain.
Most projects use two of the three. A migration typically starts from an engine we already have, adds the parts of your dialect that are yours alone, and ends in a transpiler. If you already know which platform you are dealing with, start from Legacy Modernization or from RPG & IBM i modernization instead.
A tree, not a text file.
The value is not that the code has been read. It is that every name in it has been resolved to the thing it refers to—so a question about your estate becomes a query instead of a week of reading.
A parser turns each program into a typed tree in which a variable points at its declaration, a field points at the DDS or copybook that defines it, and a call points at the program it reaches. Positions are kept on every node, so you can always get back to the line a finding came from.
That resolved model is what makes the useful work possible: impact analysis, dead-code detection, data lineage, documentation generated from the source—and, when you are ready, translation.
Our engines are built not to throw. Awkward input returns a partial tree plus positioned issues, so a batch run over twenty thousand programs completes and tells you where it struggled, instead of stopping on the first file it dislikes.
* source — ORD200.rpgle, fixed-form C spec
C EVAL TOTAL = QTY * PRICE
* what the engine gives back
AssignmentStatement ORD200.rpgle 118:8
target → DataDefinition TOTAL D spec, line 21
value MultiplicationExpr
left → DataDefinition QTY DDS field ORDLIN.QTY
right → DataDefinition PRICE /COPY PRICING, line 7Strumenta Language Engines
The parsers we have taken furthest are packaged as a product family. Each one is a library you license and run yourself—on a laptop or in CI, with no connection to the machine the code came from.
RPG & DDS Language Engine
RPG IV fixed-form and free-form, embedded SQL, and all four kinds of DDS file. Battle-tested on more than 30 million lines of production RPG code.
CL Language Engine
Modernization programs usually start with RPG and stall on CL. Over 2,100 Control Language commands modeled as typed nodes, with unknown commands parsed rather than skipped.
COBOL Language Engine
COBOL 85 at the core, with COPY and REPLACE expansion, embedded SQL and CICS. Validated against the NIST COBOL-85 test suite on every regression run.
SAS Language Engine
DATA steps, 23 PROCs, the macro language and the whole of PROC SQL, including pass-through. Before you can move SAS, you have to read it.
The whole catalog — T-SQL, PL/SQL, Java, Kotlin, Python, VB6, EGL, Teradata SQL and more →
RPG, DDS and CL share one data model, so an IBM i estate can be analyzed as a single connected graph rather than three disconnected inventories. All four engines emit positions on every node and produce a partial result with positioned issues rather than failing on difficult input.
Parser work, made estimable.
Building a parser for a real legacy language has a reputation for being open-ended. The Chisel Method is how we close it: an objective goal agreed before development starts, measured coverage as it proceeds, and support until the parser is actually in use.
Define the goal
What counts as finished?
A validation set of real example files, chosen before we start, and two checks that have to pass on it. Not open to interpretation, and not decided after the fact.
Frictionless development
Where are we, and what is next?
Coverage is measured statement by statement, so progress is a number both sides can read. Tooling handles the repetitive parts; the engineers spend their time on the hard 5%.
Frictionless adoption
Is it actually being used?
A parser that sits unused has delivered nothing. We support the integration into your pipeline until it is running there, and the documentation describes the AST you will really work with.
Why Strumenta
- Parsers are a product line here, not a side effect. Parsers, transpilers, code generators and DSLs are what we have built and sold since 2015, for clients in 20+ countries—not something assembled once for a consulting engagement and never maintained again.
- Open foundations, no lock-in. Every engine is built on Starlasu, our Apache-2.0 AST framework, with implementations for the JVM, Python, TypeScript and C#. There is no proprietary intermediate representation holding your work hostage.
- Interoperable by design. Every engine supports LionWeb, so the trees can be consumed from Java, Kotlin, Python, TypeScript or C# tooling that we did not write. Strumenta is one of the founding participants in LionWeb, alongside JetBrains and itemis.
- Tested against the awkward cases. The COBOL engine runs the NIST COBOL-85 suite on every change; the RPG engine has been exercised on more than 30 million lines of production code. We would rather tell you where a parser struggles than claim it never does.
- Vendors use our parsers in their own products. Modernization companies license our engines and ship them inside their tools. That is a harder test than a one-off project, and it is why the licensing terms and the documentation exist at all.
You can also read what our clients say in the case studies and the testimonials, or see the full list of languages we cover.
Straight answers
What is the difference between a parser and a transpiler?
A parser reads source code and turns it into a structured, typed model you can analyze. A transpiler takes that model and writes equivalent code in another language. Every transpiler contains a parser; not every parser project needs a transpiler—plenty of them exist to answer questions about an estate nobody wants to move yet.
Do you have a parser for my language?
We license fifteen, and the list is on the catalog page. If yours is not there, or if what you run is a dialect of your own, that is a custom parser project—which is work we do routinely.
Do we have to send you our source code?
Not to run an engine. Most of them are JVM libraries; the Firebird engine and the C# T-SQL component are .NET, and the analytic SQL engine is Node and TypeScript. Whichever it is, the library and its command-line tool run inside your own network, with no connection back to us and none to the machine the code came from—and every engine is consumable from Java, Kotlin, Python, TypeScript and C# through its bindings, so the host application picks the language. For a custom parser we do need representative examples, under whatever agreement you need.
What format is the output in?
Depending on the engine: JSON, XML, EMF/Ecore, or LionWeb. The metamodel is documented and exportable, so you can generate your own bindings rather than working against an opaque structure.
Is the output good enough to migrate from?
That is exactly what it is for. The same engines sit underneath our own migration work—the RPG engine behind our IBM i projects, the SAS engine behind transpilers that have processed tens of millions of lines. If you want the migration rather than the machinery, start from Legacy Modernization.
Tell us what you need to read, and what you need to do with it.
We will tell you whether we already have an engine for it, what a custom parser would take, and whether a transpiler is worth building at all. If we are not the right people for it, we will say so.