Arvutiteaduse instituut
  1. Kursused
  2. 2018/19 kevad
  3. Automaadid, keeled ja translaatorid (LTAT.03.006)
EN
Logi sisse

Automaadid, keeled ja translaatorid 2018/19 kevad

  • Üldinfo
  • Kava
    • 1. Soojendus
    • 2. Regulaaravaldised
    • 3. Olekumasinad
    • 4. Lõplikud automaadid
    • 5. Avaldise struktuur
    • 6. Grammatikad ja lekser
    • 7. Käsitsi parsimine
    • 8. ANTLR intro
    • 9. AST loomine
    • 10. Interpretaator
    • 11. Semantiline analüüs
    • 12. Kompilaator
  • Moodle
  • Bitbucket
  • Fleep!
  • Backlinks

Kompilaatori kodutöö, vihje 2

package week12;

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

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

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


public class AktkCompiler {

	public static void main(String[] args) throws IOException {
		// lihtsam viis "käsurea parameetrite andmiseks":
		//args = new String[] {"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 = new String(Files.readAllBytes(sourceFile), StandardCharsets.UTF_8);

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

		// seon muutujad
        AktkBinding.bind(ast);

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

	public static byte[] createClass(AstNode ast, 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 AktkCompilerVisitor(mv).visit(ast);
		mv.visitInsn(RETURN);
		mv.visitMaxs(0, 0);
		mv.visitEnd();


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

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

	private static class AktkCompilerVisitor extends AstVisitor.VoidVisitor {

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

		private AktkCompilerVisitor(MethodVisitor mv) {
			this.mv = mv;
		}

		private int getVariableIndex(VariableBinding binding) {
			Integer index = variableIndices.get(binding);
			if (index != null) {
				return index;
			}
			else {
				// muutuja 0 on meie main-meetodi parameeter

				index = variableIndices.size()+1;
				variableIndices.put(binding, index);
				return index;
			}
		}

		@Override
		protected void visitVoid(Assignment assignment) {
			// 1) genereeri avaldise väärtustamise kood
			// 2) genereeri väärtuse muutujasse salvestamise kood
		}

		@Override
		protected void visitVoid(Block block) {
			for (Statement stmt : block.getStatements()) {
				visit(stmt);
			}
		}

		@Override
		protected void visitVoid(ExpressionStatement expressionStatement) {
			// NB! Ära unusta, et ExpressionStatement viskab arvutatud väärtuse minema
		}

		@Override
		protected void visitVoid(FunctionCall functionCall) {
			if (functionCall.getFunctionName().equals("-") && functionCall.getArguments().size() == 1) {
				// unaarne miinus
			}
			else if (functionCall.isArithmeticOperation()) {

			}
			else if (functionCall.isComparisonOperation()) {

			}
			else {

			}
		}

		private void generateNormalFunctionCall(FunctionCall call) {

		}

		private void generateArithmeticOrLogicOperation(FunctionCall call) {

		}

		private void generateComparisonOperation(FunctionCall call) {
			// JVM int-ide võrdlusoperatsioonide valikus on kõik operatsioonid seotud jumpidega.
			// Kui sa ei taha avaldise väärtustamise koodi siduda if-lausega
			// siis ma kasuta jumpe lihtsalt selleks, et tekitada stacki tippu
			// kas 0 või 1
		}

		@Override
		protected void visitVoid(FunctionDefinition functionDefinition) {
			throw new UnsupportedOperationException(); // pole vaja
		}

		@Override
		protected void visitVoid(IfStatement ifStatement) {
			Label doneLabel = new Label();
			Label elseLabel = new Label();
			// ...
		}

		@Override
		protected void visitVoid(IntegerLiteral integerLiteral) {

		}

		@Override
		protected void visitVoid(ReturnStatement returnStatement) {
			throw new UnsupportedOperationException(); // pole vaja
		}

		@Override
		protected void visitVoid(StringLiteral stringLiteral) {
			throw new UnsupportedOperationException(); // pole vaja
		}

		@Override
		protected void visitVoid(Variable variable) {

		}

		@Override
		protected void visitVoid(VariableDeclaration variableDeclaration) {

		}

		@Override
		protected void visitVoid(WhileStatement whileStatement) {

		}
	}
}
  • 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