This project is a compiler for the MicroJava language. It translates syntactically and semantically correct programs into MicroJava bytecode for execution on MicroJava virtual machines. It includes lexical, syntactic, and semantic analysis, as well as code generation functionalities.
Explore the project »
Report Bug
·
Request Feature
Table of Contents
The aim of the project is to implement a compiler for the MicroJava programming language. The compiler enables the translation of syntactically and semantically correct MicroJava programs into MicroJava bytecode, which runs on the MicroJava virtual machine. Syntactically and semantically correct MicroJava programs are defined by the language specification. The compiler has four basic functionalities: lexical analysis, syntactic analysis, semantic analysis, and code generation.
The lexical analyzer should recognize language lexemes and return a set of tokens extracted from the source code, which are further examined within the syntactic analysis. If a lexical error is detected during lexical analysis, an appropriate message should be printed to the output.
The syntactic analyzer is tasked with determining whether the extracted tokens from the source code of the program can form grammatically correct sentences. After parsing syntactically correct MicroJava programs, it is necessary to inform the user about the success of parsing. If the source code has syntax errors, it is necessary to issue a suitable explanation of the detected syntax error, perform recovery, and continue parsing.
The semantic analyzer is formed based on the abstract syntax tree that resulted from syntactic analysis. Semantic analysis is conducted by implementing methods for visiting nodes of the abstract syntax tree. The tree is formed based on the grammar implemented in the previous phase. If the source code has semantic errors, an appropriate message about the detected semantic error should be displayed.
The code generator translates syntactically and semantically correct programs into executable form for the selected MicroJava VM runtime environment. Code generation is implemented in a similar way to semantic analysis, by implementing methods that visit nodes.
This project considers programs that only contain the main function (method), which do not use loops or branches, nor support the creation of classes.
Examples of programs written in this Java-like language are provided in the files program.mj and test301.mj.
To get a local copy up and running follow these simple steps.
List of things you need to do:
- Download and launch your favorite Java IDE.
Setup & execution:
- Clone the repo:
git clone https://github.com/jovan-vukic/microjava-compiler.git
- Set the Java version in the project to 1.8 for the best compatibility.
- Mark all folders present in this repository (except
docsandlib) as Sources Root folders (for some IDEs this step may not be necessary) - Execute the
compiletarget from thebuild.xmlfile present in the project folder, which performs lexical, syntactic, and semantic analysis. - Run the
Compiler.javaclass, which will perform code generation and create the object filetest/test301.obj. Before creating the object file, pass the following command-line arguments to theCompiler.java:test/test301.mj test/test301.obj
- After creating the object file, execute it by running the
runTest301ordebugTest301targets from thebuild.xml. They utilize the MicroJava VM implementation provided in thelib/mj-runtime-1.1.jarfile. - Consider changing the input value for the program
test/test301.mj, which is located in the filetest/test301_input.txt. By doing so or by modifying the code itself, it is possible to obtain different output values. The same test can be run for the filetest/program.mj.
9 6 6 true b c -28Since the execution of lexical, syntactic, and semantic analysis, as well as code generation, relies on the use of tools in the lib directory, executing the compile target from the build.xml file can also be done via the command line, as shown below.
Parser generation
A parser is generated based on the CUP tool, where for each grammar production, a corresponding class is generated in the ast folder in the src/rs/ac/bg/etf/pp1 folder, enabling traversal of the syntax tree in subsequent compiler phases.
The specification of the language grammar provided as input to this tool is defined in the spec/mjparser.cup file.
java -jar lib/cup_v10k.jar -destdir src/rs/ac/bg/etf/pp1/ -ast src.rs.ac.bg.etf.pp1.ast -parser MJParser -buildtree spec/mjparser.cupAfter this, the MJParser.java class is generated in the src/rs/ac/bg/etf/pp1 folder. It is necessary to change the package name to rs.ac.bg.etf.pp1 in all files in the ast folder, as instructed in the repackage target in the build.xml file.
Lexer generation
By using the JFlex tool with the lexer specification provided in the spec/mjlexer.flex file, a lexer class is generated into the file YYlex.java. Prior execution of the parser generation was necessary because it produces the sym.java class used in the mentioned specification.
java -jar lib/JFlex.jar -d src/rs/ac/bg/etf/pp1/ spec/mjlexer.flexSemantic analysis and code generation
All of this is done through Java code by running the Compiler.java class, with test/program.mj test/program.obj passed to it as command-line arguments.
Program execution
The object file is executed using the MicroJava VM specified in the lib\mj-runtime-1.1.jar file, through the Run class.
java -cp lib\mj-runtime-1.1.jar rs.etf.pp1.mj.runtime.Run test\program.objIt is also possible to disassemble the MicroJava code using the disasm class from the same file.
java -cp lib\mj-runtime-1.1.jar rs.etf.pp1.mj.runtime.disasm test\program.objExpected output
true 3Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Distributed under the MIT License. See LICENSE for more information.
Jovan - @jovan-vukic
Project Link: https://github.com/jovan-vukic/microjava-compiler
This project was done as part of the course 'Compiler Construction 1' (13E114PP1) at the University of Belgrade, Faculty of Electrical Engineering.
Used resources: