Pass I Macro Processor Implementation

SPOS (LP-I) Practical - Java Code Solution

Home > SPOS > Pass I Macro Processor

Problem Statement

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 Code Implementation

1. 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;
    }
}

2. Macroprocessor1 Class

import java.util.*;

public class Macroprocessor1 {
    static List MNT = new ArrayList<>(); // Macro Name Table
    static List MDT = new ArrayList<>();   // Macro Definition Table
    static Map> 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 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 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> entry : ALA.entrySet()) {
            System.out.println("Macro: " + entry.getKey());
            List 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

🎓 Important Points for SPPU Exams (Oral/Practical)

5 University Exam Questions & Answers

Q1. Define Macro and Macro Expansion.

Ans: A macro is a single line of code that represents a block of instructions. Macro expansion is the process of replacing the macro call with its corresponding body.

Q2. What is the purpose of the MNT (Macro Name Table)?

Ans: MNT stores the names of all macros defined in the program along with a pointer to their definition in the MDT.

Q3. What represents the end of a macro definition in MDT?

Ans: The MEND (Macro End) directive signifies the end of a macro definition.

Q4. What is ALA (Argument List Array)?

Ans: ALA is used during macro expansion to substitute formal parameters with actual arguments provided during the macro call.

Q5. Explain the difference between a Macro and a Subroutine.

Ans: Macros are expanded at compile-time (faster execution, more memory), while Subroutines are called at run-time (slower execution, less memory).

Summary for Quick Revision

Pass I of a Macro Processor focuses on identifying macro definitions, storing their names in MNT, and their bodies in MDT. It also prepares the ALA for parameter substitution, ensuring the system is ready for the expansion phase in Pass II.