This is a simple compiler for MiniJava, a minimalistic Java-like programming language. The compiler is implemented in JavaCC and was built as part of the "Compilerbau" course at FH Aachen. It can be used to compile MiniJava source code into Java bytecode.
- Ensure you have
Javainstalled on your system. - Open a terminal and navigate to the
compilerdirectory containing theMiniJava.jarfile (or get the release here). - Run the following command to compile a
MiniJavasource file:
$ java -jar MiniJava.jar < mySourceFile.txt
- The compiler will generate a
Javaclass file namedMiniJavaClassFile.class. Run the compiled class file with the following command:
$ java MiniJavaClassFile
- Ensure you have
JavaandJavaCCinstalled on your system. - Open a terminal and navigate to the
srcdirectory. - Run the following command to generate the
Javaparser:
$ javacc MiniJava.jj
- Compile the generated
Javafiles:
$ javac MiniJava.java
- Run the following command to compile a
MiniJavasource file:
$ java MiniJava < mySourceFile.txt
- The compiler will generate a
Javaclass file namedMiniJavaClassFile.class. Run the compiled class file with the following command:
$ java MiniJavaClassFile
Example 1:
final int n = 10;
func fib(int n) {
int result = 0;
if n <= 1 {
result = n;
}
else {
result = fib(n - 1) + fib(n - 2);
}
return (result);
}
static void main() {
print(fib(n));
}Example 2:
final int number = 12345;
func getRightmostDigit(int number) {
int n;
{
n = number;
while n >= 10 {
n = n - 10;
}
}
return (n);
}
func removeRightmostDigit(int number) {
{}
return (number / 10);
}
func reverse(int number) {
int reversedNumber = 0, remainingNumber, digit;
{
remainingNumber = number;
while remainingNumber != 0 {
digit = getRightmostDigit(remainingNumber);
reversedNumber = reversedNumber * 10 + digit;
remainingNumber = removeRightmostDigit(remainingNumber);
}
}
return (reversedNumber);
}
static void main() {
print(reverse(number));
}Example 3:
final int x = 14400;
// Note: The result is rounded down to the nearest integer, and this method works accurately only
// for numbers with integer square roots, because the MiniJavaCompiler only works with integers
func sqrt(int x) {
int start = 1, end, result, mid;
{
if x == 0 result = 0;
else if x == 1 result = 1;
end = x;
while start <= end {
mid = (start + end) / 2;
if mid * mid == x {
result = mid;
}
if mid * mid < x {
start = mid + 1;
result = mid;
}
else {
end = mid - 1;
}
}
}
return (result);
}
static void main() {
print(sqrt(x));
}Example 4:
final int a = 3, b = 2;
int i;
void myPrint(int n) {
print(n);
}
func ack(int a, int b) {
int ret = 0;
if b == 0
{
ret = 1;
}
else
if a == 0
{
if b == 1 ret = 2;
else ret = b + 2;
}
else
{
ret = ack(a - 1, ack(a,b-1));
}
return ret;
}
static void main() {
while i < 10 {
myPrint(ack(a,b));
i = i + 1;
}
}I have also built a calculator for generating first, follow, and lookahead sets to check if a grammar is LL(1). You can find the calculator here.
Feel free to explore and use it in conjunction with the MiniJava compiler. The MiniJava language grammar used by the compiler is also available in this repository.
Please note that the provided grammar is not LL(1) due to the presence of the 'else' keyword in the <optElse> production, which introduces ambiguity. This is because after seeing an if statement, the parser cannot determine whether to expand <optElse> to else <statement> or to epsilon.