Skip to main content

Serialize the AST

The CLI can export JSON or XML via the parse command (see Usage). From library code you can serialize the AST the same way — useful for golden tests, feeding external tools, or caching parse results.

Add Dependencies

repositories {
mavenLocal()
mavenCentral()
flatDir {
dirs("deps")
}
}

dependencies {
implementation(files("deps/rpgparser-2.2.0-all.jar"))
}

Export JSON

RPG provides JsonGenerator to write the full AST tree, including node types and properties discovered by introspection. You should instantiate the generator using createRPGJsonGenerator, which registers RPG-specific custom serializers (for length notations, edit codes, and related types). This is the same mechanism used by the CLI.

import com.strumenta.kolasu.commercial.LicenseManager
import com.strumenta.rpgparser.RPGKolasuParser
import com.strumenta.rpgparser.serialization.createRPGJsonGenerator
import java.io.File

fun exportJson(rpgFile: File, license: File, outputJson: File) {
LicenseManager.registerLicense(license)
val result = RPGKolasuParser.parserFromExtension(rpgFile).parse(rpgFile)
val root = result.root ?: error("No AST for ${rpgFile.name}")

val json = createRPGJsonGenerator().generateString(root, null)
outputJson.writeText(json)
println("Wrote ${outputJson.absolutePath}")
}

The JSON format matches what the CLI writes for -f json. You can load examples into the interactive AST viewer by placing files under static/parser-examples/.

Export XML

For tools that prefer XML, use XMLGenerator with the same API:

import com.strumenta.kolasu.serialization.XMLGenerator
import com.strumenta.rpgparser.model.CompilationUnit
import java.io.File

fun exportXml(root: CompilationUnit, outputXml: File) {
// Prefer a compact node when available — full CompilationUnit XML can be very large.
val focus = root.fileDescriptions.firstOrNull()
?: root.dataDefinitions.firstOrNull()
?: root
outputXml.writeText(XMLGenerator().generateString(focus))
}

Debug a single node

When exploring the AST interactively, print simpleNodeType / getSimpleNodeType() and inspect node properties without serializing the whole subtree:

fun debugNode(node: com.strumenta.kolasu.model.Node) {
println(node.simpleNodeType)
node.properties.forEach { property ->
if (!property.providesNodes) {
println(" ${property.name} = ${property.value}")
} else {
println(" ${property.name} = <Nodes>")
}
}
}

When to serialize vs. walk

Serialize when you need a snapshot for storage, diffing, or non-JVM consumers. Walk when you need structured extraction (inventory, call sites, DDS fields) without persisting the entire tree. For LionWeb-based pipelines, see the analyzer's snapshot export in Analyze an RPG codebase.