Institute of Computer Science
Courses.cs.ut.ee Institute of Computer Science University of Tartu
  1. Main page
  2. Automata, Languages and Compilers
ET
Log in
Attention! Courses webpage might experience technical difficulties on 19.05.2026 between 18.00 and 18.30. Please don't submit any homeworks and modify any pages during this time. Sorry for the inconvenience.

Automata, Languages and Compilers

  • Üldinfo
  • Ajakava
  • Eksami näidised
  • Teemad
    • 1. Soojendus
    • 2. Regulaaravaldised
    • 3. Automaadid
    • 4. Avaldise struktuur
    • 5. Grammatikad ja lekser
    • 6. Käsitsi parsimine
    • 7. ANTLRiga töötamine
    • 8. Interpretaator
    • 9. Kompilaator
    • 10. Edasi!
  • Süvendus
  • GitHub
  • Moodle
  • Zulip
  • Zoom

Kompilaatori kodutöö, vihje 1

package week10;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import week7.AktkAst;
import week7.ast.*;
import week9.AktkBinding;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.objectweb.asm.Opcodes.*;


public class AktkCompiler {

    static void main(String[] args) throws IOException {
        // lihtsam viis "käsurea parameetrite andmiseks":
        //args = new String[] {"inputs/yks_pluss_yks.aktk"};

        if (args.length != 1) {
            throw new IllegalArgumentException("Sellele programmile tuleb anda parameetriks kompileeritava AKTK faili nimi");
        }

        Path sourceFile = Paths.get(args[0]);
        if (!Files.isRegularFile(sourceFile)) {
            throw new IllegalArgumentException("Ei leia faili nimega '" + sourceFile + "'");
        }

        String className = sourceFile.getFileName().toString().replace(".aktk", "");
        Path classFile = sourceFile.toAbsolutePath().getParent().resolve(className + ".class");

        createClassFile(sourceFile, className, classFile);
    }

    private static void createClassFile(Path sourceFile, String className, Path classFile) throws IOException {
        // loen faili sisu muutujasse
        String source = Files.readString(sourceFile);

        // parsin ja moodustan AST'i
        Statement ast = AktkAst.createAst(source);

        // seon muutujad
        AktkBinding.bind(ast);

        // kompileerin
        byte[] bytes = createClass(ast, className);
        Files.write(classFile, bytes);
    }

    public static byte[] createClass(Statement statement, String className) {
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);

        // Klassi attribuudid
        cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, className, null, "java/lang/Object", null);
        cw.visitSource(null, null);

        // main meetod
        MethodVisitor mv = cw.visitMethod(
                ACC_PUBLIC + ACC_STATIC,                     // modifikaatorid
                "main",                                        // meetodi nimi
                "([Ljava/lang/String;)V",                    // meetodi kirjeldaja
                null,                                         // geneerikute info
                new String[] { "java/io/IOException" });
        mv.visitCode();
        // terve AKTK programm tuleb kompileerida main meetodi sisse
        new AktkCompiler(mv).compileStatement(statement);

        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();

        // klassi lõpetamine
        cw.visitEnd();

        // klassi baidijada genereerimine
        return cw.toByteArray();
    }


    private final MethodVisitor mv;
    private final Map<VariableBinding, Integer> variableIndices = new HashMap<>();

    public AktkCompiler(MethodVisitor mv) {
        this.mv = mv;
    }

    private int getVariableIndex(VariableBinding binding) {
        // Kasuta teadaolevat indeksit, kui see on olemas,
        // või leia järgmine vaba indeks ja salvesta see.
        // Esimene muutuja saab indeksi 1, sest indeksil 0 on main meetodi parameeter (String args[]).
        return variableIndices.computeIfAbsent(binding, ignoreBinding -> variableIndices.size() + 1);
    }

    private void compileStatement(Statement statement) {
        switch (statement) {
            case Assignment assignment -> {

            }
            case Block(List<Statement> statements) -> {

            }
            case ExpressionStatement(Expression expression) -> {

            }
            case FunctionDefinition functionDefinition -> {

            }
            case IfStatement(Expression condition, Block thenBranch, Block elseBranch) -> {

            }
            case ReturnStatement returnStatement -> {

            }
            case VariableDeclaration variableDeclaration -> {

            }
            case WhileStatement(Expression condition, Block body) -> {

            }
        }
    }

    private void compileExpression(Expression expression) {
        switch (expression) {
            case FunctionCall functionCall -> {

            }
            case IntegerLiteral(Integer value) -> {

            }
            case StringLiteral(String value) -> {

            }
            case Variable variable -> {

            }
        }
    }
}
  • Institute of Computer Science
  • Faculty of Science and Technology
  • University of Tartu
In case of technical problems or questions write to:

Contact the course organizers with the organizational and course content questions.
The proprietary copyrights of educational materials belong to the University of Tartu. The use of educational materials is permitted for the purposes and under the conditions provided for in the copyright law for the free use of a work. When using educational materials, the user is obligated to give credit to the author of the educational materials.
The use of educational materials for other purposes is allowed only with the prior written consent of the University of Tartu.
Terms of use for the Courses environment