Wayback in the Spring Semester of 2006, after I was awarded my Doctor of Philosophy Degree in Computer Science, I partially audited a Compiler Design Course. Due to my mental aberrations, I was unable to complete the course. The instructor was on a Sabbatical from the United States Air Force Academy in Colorado Springs, Colorado. The textbook we used, and I still have a copy, was “Modern Compiler Implementation in Java Second Edition” © 2002 by Andrew W. Appel. Below is a translation from Java to C++ that I just completed.
// Chapter One program translated from Java to C++ by
// James Pate Williams, Jr. (c) Wednesday April 3, 2025
// Reference: "Modern Complier Implementation in Java
// Second Edition" (c) 2002 by Andrew W. Appel
#ifndef _SLPInterpreter_H
#include <iostream>
#include <stack>
#include <string>
#include <vector>
class TableEntry {
public:
std::string symbol, value;
TableEntry(std::string symbol, std::string value) {
this->symbol = symbol;
this->value = value;
}
};
std::stack<std::string> sStack;
std::vector<TableEntry> symbolTable;
class Exp {
public:
Exp() { };
virtual ~Exp() { };
};
std::stack<Exp> eStack;
class ExpList {
public:
ExpList() { };
virtual ~ExpList() { };
};
class Stm {
public:
Stm() { };
virtual ~Stm() { };
};
class CompoundStm : public Stm {
public:
Stm stm1, stm2;
CompoundStm(Stm stm1, Stm stm2) {
this->stm1 = stm1;
this->stm2 = stm2;
};
};
class AssignStm : public Stm {
public:
std::string id;
Exp exp;
AssignStm(std::string id, Exp exp) {
this->id = id;
this->exp = exp;
bool found = false;
for (int i = 0; !found && i < (int)symbolTable.size(); i++) {
if (symbolTable[i].symbol == id) {
found = true;
}
}
if (!found) {
symbolTable.push_back(TableEntry(id, ""));
}
};
void Print() {
std::cout << this->id << ' ';
};
};
class PrintStm : public Stm {
public:
ExpList exps;
PrintStm(ExpList exps) {
this->exps = exps;
};
};
class IdExp : public Exp {
public:
std::string id;
IdExp(std::string id) {
this->id = id;
Print();
TableEntry te(id, "");
};
void Print() {
std::cout << id << ' ';
};
};
class NumExp : public Exp {
public:
int num;
NumExp(int num) {
this->num = num;
Print();
char buffer[128] = { };
_itoa_s(num, buffer, 127, 10);
sStack.push(std::string(buffer));
};
void Print() {
std::cout << num << ' ';
};
};
enum class ArithmeticOp {
Plus, Minus, Times, Div
};
class OpExp : public Exp {
public:
Exp left, right;
ArithmeticOp op;
OpExp(Exp left, ArithmeticOp op, Exp right) {
this->left = left;
this->op = op;
this->right = right;
std::string ops = "";
switch (op) {
case ArithmeticOp::Plus:
ops = "+";
break;
case ArithmeticOp::Minus:
ops = "-";
break;
case ArithmeticOp::Times:
ops = "*";
break;
case ArithmeticOp::Div:
ops = "/";
break;
};
std::cout << ops << std::endl;
eStack.push(left);
eStack.push(right);
sStack.push(ops);
};
};
class EseqExp : public Exp {
public:
Stm stm; Exp exp;
EseqExp(Stm stm, Exp exp) {
this->stm = stm;
this->exp = exp;
};
};
class PairExpList : public ExpList {
public:
Exp head;
ExpList tail;
PairExpList(Exp head, ExpList tail) {
this->head = head;
this->tail = tail;
};
};
class LastExpList : public ExpList {
public:
Exp head;
LastExpList(Exp head) {
this->head = head;
};
};
#endif _SLPInterpreter_H
int main() {
int a = 0, b = 0;
Stm prog(CompoundStm(AssignStm("a",
OpExp(NumExp(5), ArithmeticOp::Plus, NumExp(3))),
CompoundStm(AssignStm("b",
EseqExp(PrintStm(PairExpList(IdExp("a"),
LastExpList(OpExp(IdExp("a"),
ArithmeticOp::Minus, NumExp(1))))),
OpExp(NumExp(10), ArithmeticOp::Times, IdExp("a")))),
PrintStm(LastExpList(IdExp("b"))))));
bool first = true;
int result = 0;
//sStack.push("0");
while (!sStack.empty()) {
std::string lts, ops, rts;
if (first) {
ops = sStack.top();
sStack.pop();
lts = sStack.top();
sStack.pop();
rts = sStack.top();
sStack.pop();
first = false;
}
else {
lts = sStack.top();
sStack.pop();
ops = sStack.top();
sStack.pop();
rts = sStack.top();
sStack.pop();
}
int lvi = std::stoi(lts);
int rvi = std::stoi(rts);
if (ops == "+") {
result = lvi + rvi;
}
else if (ops == "-") {
result = lvi - rvi;
}
else if (ops == "*") {
result = lvi * rvi;
}
else if (ops == "/") {
result = lvi / rvi;
}
char ascii[128] = { };
_itoa_s(result, ascii, 10);
if (sStack.size() != 0) {
sStack.push(std::string(ascii));
}
}
std::cout << "Result = " << result << std::endl;
return 0;
}