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
- Kotlin
- Java
repositories {
mavenLocal()
mavenCentral()
flatDir {
dirs("deps")
}
}
dependencies {
implementation(files("deps/rpgparser-2.2.0-all.jar"))
}
repositories {
mavenLocal()
mavenCentral()
flatDir {
dirs("deps")
}
}
dependencies {
implementation(files("deps/rpgparser-2.2.0-all.jar"))
implementation "com.strumenta.kolasu:kolasu-javalib:1.5.107"
}
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.
- Kotlin
- Java
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}")
}
import com.strumenta.kolasu.commercial.LicenseManager;
import com.strumenta.kolasu.parsing.ParsingResult;
import com.strumenta.rpgparser.RPGKolasuParser;
import com.strumenta.rpgparser.model.CompilationUnit;
import com.strumenta.rpgparser.serialization.CustomSerializationKt;
import java.io.File;
import java.nio.file.Files;
public class ExportJson {
public static void exportJson(File rpgFile, File license, File outputJson) throws Exception {
LicenseManager.INSTANCE.registerLicense(license);
ParsingResult<CompilationUnit> result =
RPGKolasuParser.parserFromExtension(rpgFile).parse(rpgFile);
CompilationUnit root = result.getRoot();
if (root == null) {
throw new IllegalStateException("No AST for " + rpgFile.getName());
}
String json = CustomSerializationKt.createRPGJsonGenerator().generateString(root, null);
Files.writeString(outputJson.toPath(), json);
System.out.println("Wrote " + outputJson.getAbsolutePath());
}
}
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:
- Kotlin
- Java
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))
}
import com.strumenta.kolasu.model.Node;
import com.strumenta.kolasu.serialization.XMLGenerator;
import com.strumenta.rpgparser.model.CompilationUnit;
import java.io.File;
import java.nio.file.Files;
public class ExportXml {
public static void exportXml(CompilationUnit root, File outputXml) throws Exception {
Node focus = root.getFileDescriptions().isEmpty()
? (root.getDataDefinitions().isEmpty() ? root : root.getDataDefinitions().get(0))
: root.getFileDescriptions().get(0);
Files.writeString(outputXml.toPath(), new XMLGenerator().generateString(focus));
}
}
Debug a single node
When exploring the AST interactively, print simpleNodeType / getSimpleNodeType() and inspect node properties without serializing the whole subtree:
- Kotlin
- Java
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>")
}
}
}
import com.strumenta.kolasu.model.Node;
import com.strumenta.kolasu.model.Processing;
public class DebugNode {
public static void debugNode(Node node) {
System.out.println(node.getSimpleNodeType());
Processing.processProperties(node, property -> {
if (!property.getProvideNodes()) {
System.out.println(" " + property.getName() + " = " + property.getValue());
} else {
System.out.println(" " + property.getName() + " = <Nodes>");
}
return null;
});
}
}
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.