Arvutiteaduse instituut
Courses.cs.ut.ee Arvutiteaduse instituut Tartu Ülikool
  1. Esileht
  2. Automaadid, keeled ja translaatorid
EN
Logi sisse

Automaadid, keeled ja translaatorid

  • Ü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 -> {

            }
        }
    }
}
  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Õppematerjalide varalised autoriõigused kuuluvad Tartu Ülikoolile. Õppematerjalide kasutamine on lubatud autoriõiguse seaduses ettenähtud teose vaba kasutamise eesmärkidel ja tingimustel. Õppematerjalide kasutamisel on kasutaja kohustatud viitama õppematerjalide autorile.
Õppematerjalide kasutamine muudel eesmärkidel on lubatud ainult Tartu Ülikooli eelneval kirjalikul nõusolekul.
Courses’i keskkonna kasutustingimused