This project was developed together with a friend at university. Checkout his profile too Matteo Barbieri
Lexical analysis is the first stage of the compilation process. During this phase, the compiler reads the source code written in the ac language and divides it into tokens. Tokens are the fundamental units of the language, such as keywords, identifiers, operators, and so on.

Token recognition is carried out using the following automaton:

Syntax analysis is the second stage of the compilation process. In this phase, the compiler checks whether the structure of the source code conforms to the grammar of the ac language. If the structure is valid, the compiler builds an Abstract Syntax Tree (AST), which represents the hierarchical structure of the code.
Below are the productions that form part of the grammar:

Semantic analysis is the third stage of the compilation process. In this phase, the compiler verifies that the source code is semantically correct. This stage is divided into two subphases:
Type checking verifies that the data types used in the source code are consistent and correct. For example, if a variable is declared as an integer, the compiler ensures that all operations performed on that variable are compatible with the integer type.
Code generation is the subphase of semantic analysis responsible for producing dc code from the Abstract Syntax Tree (AST) of the ac language. The code generator uses the information contained in the AST to generate dc code that preserves the same structure and semantics as the original source code.
The CodeGenerator class is responsible for generating dc code from the ac AST. The generated dc code can then be executed on a dc virtual machine.
To use the compiler, create a text file containing source code written in the ac language. For example:
int x = 5;
int y = x * 2;
print y;
The result will be:
5 sa
la 2 * sb
lb p P
This documentation was prepared with the support of an LLM and thoroughly reviewed, with adjustments made where appropriate.