I was reading about the Golang compiler, and I searched on YouTube, where I found these videos:
- GopherCon 2022: JesĂşs Espino - Hello World, from the Code to the Screen
- GopherCon 2017: Keith Randall - Generating Better Machine Code with SSA
Afterward, I read the ast package documentation, gaining an understanding of the project. Subsequently, I utilized this site to mimic the Golang compiler and implemented my project.
Initially, I attempted to develop the project in Golang. However, upon starting to code with this repo, I discovered that using Python with ANTLR is considered more straightforward.
For the implementation, I used a WalkerState with a StmtStack to help the tree walker to walk the syntax tree and extract a Go-like AST. The code might not be clean, but I have made an effort to add comments, excluding the cfg.py
file, where I used a trial and error method.
Caution
This project is not completed, it's just a Proof Of Concept of my Idea.
- Gain an understanding of code structures at the assembly level.
- Challenge yourself to manually generate assembly or bytecode using the output Control Flow Graph (CFG).
- Dive into the concepts of parsers, lexers, syntax trees, and Abstract Syntax Trees (AST).
- Learn how to utilize the ANTLR parser generator.
- Enhance your automata knowledge by engaging with Java grammar, Regular Grammars, and Context-Free Grammars.
As I have been working with ANTLR for 3 months, I understand that It's power lies in tasks such as syntax checking, learning how compilers work, or extracting names and features from code. If you want to build professional tools, like your homemade compiler, obfuscator, or cryptor,..., you don't need to reinvent the wheel. Instead, you just need to leverage compiler infrastructures like LLVM (https://llvm.org/) or, in the case of Java, use ASM.
Alternatively, you could piggyback on a recognized compiler like the movfuscator project.
- Python3.12
- Install Graphviz
pip install -r requirements.txt
python main.py ./javasamples/Example1.java
public class Example1 {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
}
}
public class Example2 {
public static void main(String[] args) {
for (int i = 1, j = 1; i <= 3; i++, j++) {
for (int k = 1, l = 1; k <= 2; k++, l++) {
System.out.println("i: " + i + ", j: " + j + ", k: " + k + ", l: " + l);
}
}
}
}
public class Example3 {
public static void main(String[] args) {
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
System.out.println(i + " is even");
}
}
}
}
public class Example4 {
public static void main(String[] args) {
int number = 7;
if (number > 0) {
System.out.println("The number is positive");
} else if (number < 0) {
System.out.println("The number is negative");
} else if (number % 2 == 0) {
System.out.println("The number is zero");
System.out.println("The number is also even");
} else if (number % 2 != 0) {
System.out.println("The number is zero");
System.out.println("The number is also odd");
} else {
System.out.println("The number is zero");
System.out.println("The number is also divisible by 2");
}
}
}
public class Example5 {
public static void main(String[] args) {
int i = 1;
while (i <= 5) {
System.out.println(i);
i++;
}
}
}
public class Example6 {
public static void main(String[] args) {
int i = 1;
do {
System.out.println(i);
i++;
} while (i <= 5);
}
}
public class Example7 {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
for (int number : numbers) {
System.out.println(number);
}
}
}
public class Example8 {
public static void main(String[] args) {
int dayOfWeek = 3;
switch (dayOfWeek) {
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
System.out.println("Wednesday");
break;
case 4:
System.out.println("Thursday");
break;
case 5:
System.out.println("Friday");
break;
case 6:
System.out.println("Saturday");
break;
case 7:
System.out.println("Sunday");
break;
default:
System.out.println("Invalid day of the week");
}
}
}
public class Example9 {
public static void main(String[] args) {
int totalIterations = 10;
int whileCounter = 1;
while (whileCounter <= totalIterations) {
System.out.println(whileCounter);
whileCounter++;
}
for (int i = 1; i <= totalIterations; i++) {
System.out.println("test");
}
return;
int doWhileCounter = 1;
do {
if (doWhileCounter % 3 == 0) {
System.out.println("Divisible by 3: " + doWhileCounter);
} else if (doWhileCounter % 5 == 0) {
System.out.println("Divisible by 5: " + doWhileCounter);
} else {
System.out.println("Not divisible by 3 or 5: " + doWhileCounter);
}
doWhileCounter++;
} while (doWhileCounter <= totalIterations);
}
}
public class Example10 {
public static void main(String[] args) {
int totalIterations = 10;
int whileCounter = 1;
while (whileCounter <= totalIterations) {
System.out.println("While loop iteration: " + whileCounter);
whileCounter++;
}
for (int i = 1; i <= totalIterations; i++) {
System.out.println("test");
}
int doWhileCounter = 1;
do {
if (doWhileCounter % 3 == 0) {
System.out.println("Divisible by 3: " + doWhileCounter);
} else if (doWhileCounter % 5 == 0) {
System.out.println("Divisible by 5: " + doWhileCounter);
} else {
System.out.println("Not divisible by 3 or 5: " + doWhileCounter);
}
doWhileCounter++;
} while (doWhileCounter <= totalIterations);
}
}
-
Implement labeled statements.
-
Implement
continue
statements within a loop using labeled statements. -
Implement
break
statements within a loop using labeled statements. -
Implement
try
-catch
(refer to: educative.io). -
Implement modern
switch
case. -
Implement
switch
expressions. -
Implement lambda expressions (W3Schools - Java Lambda).
-
Generics ? (Baeldung - Java Generics).
-
Recursion ? (W3Schools - Java Recursion).