SPOS (LP-I) Practicals
Pass1 Macro Processor Implementation
Design suitable data structures and implement Pass-I of a two pass macro processor using OOP features in Java/C++. The output of Pass-I (MNT, MDT, ALA & Intermediate code file without any macro definitions) should be input for Pass-II.
Java Program: Macro Processor Pass 1
To implement Macro Processor Pass 1 we need two classes:
- MNTEntry
- Macroprocessor1
MNTEntry Class:
public class MNTEntry {
int index;
String name;
int mdtIndex;
MNTEntry(int index, String name, int mdtIndex) {
this.index = index;
this.name = name;
this.mdtIndex = mdtIndex;
}
}
Macroprocessor1 Class:
public class Macroprocessor1 {
static List<MNTEntry> MNT = new ArrayList<>(); // Macro Name Table
static List<String> MDT = new ArrayList<>(); // Macro Definition Table
static Map<String, List<String>> ALA = new LinkedHashMap<>(); // MacroName -> Actual Args
public static void main(String[] args) {
// Example program with two macros
String[] program = {
"MACRO",
"INCR &A,&B",
"ADD AREG,&A",
"SUB BREG,&B",
"MEND",
"MACRO",
"DECR &X,&Y",
"SUB AREG,&X",
"SUB BREG,&Y",
"MEND",
"START 100",
"INCR A,B",
"DECR 5,10",
"END"
};
pass1(program);
// Print results
printMNT();
printMDT();
printALA();
}
// ---------------- PASS 1 -----------------
static void pass1(String[] program) {
boolean inMacroDef = false;
String macroName = "";
int mntIndex = 0;
List<String> formals = new ArrayList<>();
for (int lineNo = 0; lineNo < program.length; lineNo++) {
String line = program[lineNo].trim();
if (line.isEmpty()) continue;
String[] parts = line.split("[ ,]+"); //"ADD AREG,&A",
if (line.equals("MACRO")) {
inMacroDef = true;
macroName = "";
formals.clear();
continue;
}
if (inMacroDef) {
if (line.equals("MEND")) {
MDT.add("MEND");
inMacroDef = false;
continue;
}
if (macroName.equals("")) {
// Macro prototype
macroName = parts[0];
int mdtStart = MDT.size();
MNT.add(new MNTEntry(mntIndex++, macroName, mdtStart));
// Store formals
for (int i = 1; i < parts.length; i++) {
formals.add(parts[i]);
}
} else {
// Replace formals with positional notations (#0, #1…)
StringBuilder mdtLine = new StringBuilder();
for (String word : parts) {
if (formals.contains(word)) {
int index = formals.indexOf(word);
mdtLine.append("#").append(index).append(" ");
} else {
mdtLine.append(word).append(" ");
}
}
MDT.add(mdtLine.toString().trim());
}
} else {
MNTEntry found = null;
for (MNTEntry e : MNT) {
if (e.name.equals(parts[0])) {
found = e;
break;
}
}
if (found != null) {
List<String> actuals = new ArrayList<>();
for (int i = 1; i < parts.length; i++) {
actuals.add(parts[i]);
}
ALA.put(parts[0], actuals);
}
}
}
}
// ---------------- PRINT TABLES -----------------
static void printMNT() {
System.out.println("MNT (Macro Name Table):");
System.out.println("Index\tName\tMDT Index");
for (MNTEntry entry : MNT) {
System.out.println(entry.index + "\t" + entry.name + "\t" + entry.mdtIndex);
}
System.out.println();
}
static void printMDT() {
System.out.println("MDT (Macro Definition Table):");
System.out.println("Index\tDefinition");
for (int i = 0; i < MDT.size(); i++) {
System.out.println(i + "\t" + MDT.get(i));
}
System.out.println();
}
static void printALA() {
System.out.println("ALA (Actual Argument List Array):");
for (Map.Entry<String, List<String>> entry : ALA.entrySet()) {
System.out.println("Macro: " + entry.getKey());
List<String> args = entry.getValue();
for (int i = 0; i < args.size(); i++) {
System.out.println(" #" + i + " -> " + args.get(i));
}
}
}
}
Output:
MNT (Macro Name Table):
Index Name MDT Index
0 INCR 0
1 DECR 3
MDT (Macro Definition Table):
Index Definition
0 ADD AREG #0
1 SUB BREG #1
2 MEND
3 SUB AREG #0
4 SUB BREG #1
5 MEND
ALA (Actual Argument List Array):
Macro: INCR
#0 -> A
#1 -> B
Macro: DECR
#0 -> 5
#1 -> 10