How to Parse RPG Code
This is the most basic of examples: it shows how to parse some RPG code into a CompilationUnit.
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"
}
Parse a file
Create an RPGKolasuParser from the file extension (or with an explicit RPGFileType), register your license, and call parse. The root of a successful parse is a CompilationUnit.
- Kotlin
- Java
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.model.DataStructure
import com.strumenta.rpgparser.model.StandaloneField
import java.io.File
fun processRPGFile(rpgFile: File, license: File) {
println("== Processing RPG file ${rpgFile.path} ==\n")
if (!rpgFile.exists() || !rpgFile.isFile) {
println("File not found or not a file, skipping")
return
}
LicenseManager.registerLicense(license)
val parser = RPGKolasuParser.parserFromExtension(rpgFile)
val result: ParsingResult<CompilationUnit> = parser.parse(rpgFile)
if (result.issues.isNotEmpty()) {
println("Issues in file: ${result.issues.size}")
for (issue in result.issues) {
println(" - $issue")
}
}
val cu = result.root
if (cu == null) {
println("Compilation unit not built, skipping")
return
}
if (cu.dataDefinitions.isEmpty()) {
println("No data definitions")
} else {
println("Data definitions: ${cu.dataDefinitions.size}")
for (dd in cu.dataDefinitions) {
when (dd) {
is StandaloneField -> println(" - standalone field ${dd.name}")
is DataStructure -> {
val name = dd.name ?: "unnamed @ line ${dd.position?.start?.line}"
println(" - data structure $name")
}
else -> println(" - $dd")
}
}
}
println("Procedures: ${cu.procedures.size}")
cu.procedures.forEach { println(" - ${it.name}") }
println("Subroutines: ${cu.subroutines.size}")
cu.subroutines.forEach { println(" - ${it.name}") }
}
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.model.DataDefinition;
import com.strumenta.rpgparser.model.DataStructure;
import com.strumenta.rpgparser.model.Procedure;
import com.strumenta.rpgparser.model.StandaloneField;
import com.strumenta.rpgparser.model.Subroutine;
import java.io.File;
private static void processRPGFile(File rpgFile, File license) {
System.out.println("== Processing RPG file " + rpgFile.getPath() + " ==\n");
if (!rpgFile.exists() || !rpgFile.isFile()) {
System.out.println("File not found or not a file, skipping");
return;
}
LicenseManager.INSTANCE.registerLicense(license);
RPGKolasuParser parser = RPGKolasuParser.parserFromExtension(rpgFile);
ParsingResult<CompilationUnit> result = parser.parse(rpgFile);
if (!result.getIssues().isEmpty()) {
System.out.println("Issues in file: " + result.getIssues().size());
for (var issue : result.getIssues()) {
System.out.println(" - " + issue);
}
}
CompilationUnit cu = result.getRoot();
if (cu == null) {
System.out.println("Compilation unit not built, skipping");
return;
}
if (cu.getDataDefinitions().isEmpty()) {
System.out.println("No data definitions");
} else {
System.out.println("Data definitions: " + cu.getDataDefinitions().size());
for (DataDefinition dd : cu.getDataDefinitions()) {
if (dd instanceof StandaloneField standaloneField) {
System.out.println(" - standalone field " + standaloneField.getName());
} else if (dd instanceof DataStructure dataStructure) {
String name = dataStructure.getName() != null
? dataStructure.getName()
: "unnamed @ line " + dataStructure.getPosition().getStart().getLine();
System.out.println(" - data structure " + name);
} else {
System.out.println(" - " + dd);
}
}
}
System.out.println("Procedures: " + cu.getProcedures().size());
for (Procedure p : cu.getProcedures()) {
System.out.println(" - " + p.getName());
}
System.out.println("Subroutines: " + cu.getSubroutines().size());
for (Subroutine sr : cu.getSubroutines()) {
System.out.println(" - " + sr.getName());
}
}
You can use the method we just created very easily.
- Kotlin
- Java
fun main() {
processRPGFile(
File("examples/QRPGLESRC/MYPGM.rpgle"),
File("licenses/strumenta.license")
)
}
public static void main(String[] args) {
processRPGFile(
new File("examples/QRPGLESRC/MYPGM.rpgle"),
new File("licenses/strumenta.license"));
}
Choose a file type explicitly
parserFromExtension covers the common case. To parse DDS, SQLRPGLE, or RPG III sources when the extension is ambiguous, construct the parser with an explicit type:
val ddsParser = RPGKolasuParser(RPGFileType.DDS)
val sqlParser = RPGKolasuParser(RPGFileType.SQLRPGLE)
val rpg3Parser = RPGKolasuParser(RPGFileType.RPG3)
Free-format RPGLE is detected automatically when the source starts with **FREE.