Institute of Computer Science
  1. Courses
  2. 2017/18 spring
  3. Automata, Languages and Compilers (LTAT.03.006)
ET
Log in

Automata, Languages and Compilers 2017/18 spring

  • Üldinfo
  1. Õppekorraldus
  2. Eksam
  3. Reeglid
  4. Töövahendid
  5. Projekt
  • 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
    1. ANTLRi parsepuu
    2. AST klassid
    3. Kodutöö (Visitor*)
  10. Interpretaator
  11. Semantiline analüüs
  12. Kompilaator
  • Moodle
  • Bitbucket
  • Fleep!

9. kodutöö: AST koostamine

Selles kodutöös tuleb ANTLR-i kaasabil defineerida meetod createAst, mis annab AKTK programmile vastava abstraktse süntaksipuu:

package week9;
import week9.ast.AstNode;

public class AktkAst {
	public static AstNode createAst(String program) {
		// Erindi viskamine tuleb asendada reaalse implementatsiooniga
		throw new UnsupportedOperationException();
	}
}

Selle saavutamiseks on vaja:

  1. genereerida ANTLR-i abil Aktk.g4 grammatikast (võib kasutada meie näidislahendust, aga ka enda lahendust, mida on sobivalt märgendatud) AKTK parser (koos abiklassidega);
  2. kirjutada kood, mis genereeritud parseri abil teisendab sõnena esitatud programmi parse-puuks;
  3. kirjutada kood, mis teisendab parse-puu abstraktseks süntaksipuuks. Abstraktse süntaksipuu esitamiseks anname ülesandega kaasa klassi AstNode koos alamklassidega. See punkt on selle koduülesande tuum.

NB! Loe enne progema hakkamist praktikumimaterjale täielikult läbi -- kui sa hüppad kohe ülesande juurde, siis tõenäoliselt lihtsalt raiskad aega ja närve.

Toome siinkohal ära kärbitud näite AST koostamisest. NB! Lisaks sellele, et siin on nähtavad lüngad, on neis mõned juhtumid ka täiesti käsitlemata -- need tuleb sul üles leida ja ära realiseerida. Selleks soovitame vaadata läbi grammatika reeglid ja otsustada, milliseid reegleid tuleb eraldi käsitleda ja millised saab jätta vaikeimplementatsiooni hooleks.

instanceof-iga variant:

	private static AstNode parseTreeToAst(ParseTree tree) {

		if (tree instanceof ArvuliteraalContext) {
			return new IntegerLiteral(Integer.parseInt(tree.getText()));
		}
		else if (tree instanceof SoneliteraalContext) {
			// arvesta, et sõneliteraalil on ümber jutumärgid, mis ei kuulu sõne sisu hulka
			return __________________;
		}
		else if (tree instanceof SuluavaldisContext) {
			// Selle tipu alluvad on alustav sulg, avaldis ja lõpetav sulg
			// NB! Alluvate nummerdamine algab 0-st

			// töötleme rekursiivselt sulgude sees oleva avaldise ja tagastame selle
			return parseTreeToAst(tree.getChild(1));
		}
		else if (tree instanceof KorrutamineJagamineContext
				|| tree instanceof LiitmineLahutamineContext
				|| tree instanceof VordlemineContext) {
			// kõik binaarsed operatsioonid saan käsitleda korraga
			String operaator = tree.getChild(1).getText();
			Expression vasakArgument = (Expression) parseTreeToAst(tree.getChild(0));
			______________________________;

			return new FunctionCall(operaator, Arrays.asList(vasakArgument, ______________));
		}
		else if (tree instanceof MuutujaDeklaratsioonContext) {
			// Muutuja deklaratsiooni esimene alluv (st. alluv 0) on võtmesõna "var",
			// teine alluv on muutuja nimi

			// Algväärtus võib olla, aga ei pruugi.
			// Kontrolli ANTLRi IntelliJ pluginaga järgi, mitu alluvat
			// on muutuja deklaratsioonil, millel on algväärtus ja mitu 
			// alluvat on sellel, millel algväärtust pole.

			return __________________;
		}
		else if (tree instanceof LauseContext) {
			// grammatikast on näha, et lause võib olla ühe alluvaga,
			// (nt. ifLause, whileLause), mis on käsitletud mujal
			if (tree.getChildCount() == 1) {
				AstNode child = parseTreeToAst(tree.getChild(0)); 
				// ainuke asi mida tuleb jälgida, 
				// on see, et kui lause koosneb avaldisest, siis selleks,
				// et temast saaks ikkagi lause,
				// tuleb ta pakendada ExpressionStatement'i sisse
				if (child instanceof Expression) {
					return new ExpressionStatement((Expression) child);
				} 
				else {
					return child;
				}
			}
			// ... aga lause võib olla ka loogelistes sulgudes olev lausete jada
			else {
				assert tree.getChildCount() == 3;
				return parseTreeToAst(tree.getChild(1));
			}
		}

		else {
			// Järele peaks olema jäänud (kui sa lisasid ülespoole ka puuduvad olulised juhtumid)
			// ainult need tiputüübid, millel on ainult
			// üks alluv ja mis olid olulised vaid parsimise jaoks. 
			// Järelikult meil pole abstraktsesse süntaksipuusse neile vastavaid 
			// tippe tarvis ja me liigume kohe nende alluva juurde
			return parseTreeToAst(tree.getChild(0));
		}
	}

Huvilistele

  • Kui sulle ei meeldi instanceof, siis uuri, kuidas saaks ülesannet lahendada visitor disainimustri abil.
  • Kui sulle ei meeldi parse-puus liikumine getChild indeksite järgi, siis uuri, milliseid kasulikke meetodeid on konkreetetel Context klassidel ja kuidas alamtippe saab ise nimetada.

Soovitused

  • Vaata üle ka AST klasside kirjeldused (dokumentatsiooni leiad klasside ja meetodite päistest). Uuri ka klassihierarhiat (IntelliJ, Eclipse).
  • AstNode.toString() näitab puu struktuuri tekstilisel kujul.

Lahenduse esitamine

  • Esitada tuleb vähemalt järgmised failid:
    • AktkAst.java
      • klassis AktkAst peab olema meetod signatuuriga public static AstNode createAst(String program)
    • AktkLexer.java
    • AktkParser.java
    • AktkListener.java
    • AktkVisitor.java
  • Ja kui kasutad ANTLRi genereeritud BaseVisitor või BaseListener, siis tuleks neid ka ülesse laadida.
  • Kokku võib esitada kuni 9 faili.
  • Kõik esitatud failid peavad olema UTF-8 kodeeringus (ANTLR-i poolt genereeritud failide puhul ei pea selle pärast muretsema).
  • Esitada ei ole vaja:
    • grammatikat (Aktk.g4)
    • .token ja .interp laiendiga genereeritud faile (Aktk.interp, Aktk.tokens, AktkLexer.interp ja AktkLexer.tokens)
  • 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