Metody realizacji języków programowania/MRJP Laboratorium

Z Studia Informatyczne
Wersja z dnia 07:52, 30 lip 2006 autorstwa Mbiskup (dyskusja | edycje) (dodana część zadań, szkic kryteriów oceniania, rozszerzenia języka)
Przejdź do nawigacjiPrzejdź do wyszukiwania

Język kotek

Imperatywny, podobny do Pascala język programowania

Cechy:

  • zwykłe konstrukcje: pętle for i while, wyrażenia arytmetyczne, logiczne
  • silne typowanie
  • funkcje
  • tablice, rekordy
  • klasy
  • dynamiczna alokacja obiektów,rekordów i tablic (tylko na stercie)
  • zagnieżdżone deklaracje funkcji
  • zagnieżdżone (w klasach, funkcjach i metodach) deklaracje klas


Etapy pisania kompilatora

  1. podstawowe konstrukcje: for, while, zmienne tylko typu int i string, proste

operacje arytmetyczne, funkcje globalne, rekurencja (też wzajemna)

  1. rekordy, tablice,dynamiczna alokacja, zwalnianie jawne (delete)
  2. lokalne procedury
  3. klasy deklarowane na poziomie globalnym
  4. klasy lokalne
  5. deklaracje zmiennej z podaną wartością do inichalizacji

Możliwe rozszerzenia

  1. zmienne double, boolean
  2. dodatkowe operatory dla wyrażeń ()
  3. odśmiecanie zamiast delete

Gramatyka języka

Będzie skopiowana z LaTeXa


Semantyka języka

Wymagania implementacyjne i ocenianie

Na 3: Podstawowe konstrukcje, rekordy, tablice, dynamiczna alokacja

Na 3+:

Na 4: Lokalne deklaracje procedur.

Na 4+:

Na 5: Obiekty, operator instanceof, rzutowanie (por. zadanie FIXME).

Dodatkowo punktowane zadania.

  • Lokalne deklaracje klas,
  • Odśmiecanie zamiast jawnego delete

Zadania

Zadanie 1: Inicjalizacja zmiennych

Aby język był bardziej bezpieczny chcielibyśmy wyeliminować możliwość użycia niezainicjalizowanych zmiennych. W tym celu modyfikujemy deklaracje zmiennej tak, aby podanie wartości przy deklaracji było obowiązkowe:

var x : int = 5;
var y : int = 3*x+5;

Zastanów się, jakie ograniczenia należy wprowadzić na wyrażenia użyte do inicjalizacji aby język był całkowicie bezpieczny. Na przykład poniższa sekwencja deklaracji prowadzi do błędu:

var x : int = y + 4;
var y : int = x + 4;

Przemyśl następujące możliwości:

  • dopuszczenie tylko wyrażeń stałych
  • dopuszczenie jedynie zmiennych zadeklarowanych wcześniej na tym samym poziomie
  • dopuszczenie jedynie zmiennych i funkcji zadeklarowanych wcześniej na tym samym poziomie
  • dopuszczenie jedynie zmiennych zadeklarowanych wcześniej na tym samym poziomie i wszystkich funkcji z tego poziomu
  • dopuszczenie zmiennych zadeklarowanych wcześniej na tym samym poziomie i wszystkich funkcji
  • dopuszczenie wszystkich zmiennych zadeklarowanych wcześniej na tym poziomie oraz wszystkich zmiennych i funkcji zakeklarowanych wyżej
  • oznaczanie zmiennych niezainicjalizowanych i sprawdzanie bycia zainicjalizowaną przy każdym odwołaniu

Która z możliwości daje największe bezpieczeństwo? Która ma nieakceptowalny narzut czasu wykonania? Która jest najbardziej elastyczna? Czy pewne z nich pozwalają obejść zabezpieczenia? Weź pod uwagę jakie zmienne i funkcje są dostępne z wewnątrz funkcji.

Zadanie 2: Klasy wewnątrz klas

Czy klasa zadeklarowana wewnątrz innej klasy może korzystać ze zmiennych tamtej klasy? Jakie byłoby ograniczenie na możliwość tworzenia instancji klasy wewnętrznej jeśli ta klasa byłaby widoczna na zewnątrz (odp. Aby utworzyć element klasy wewnętrznej trzeba mieć instancję klasy zewnętrznej) Nie jest to wymagane gdy klasa wewnętrzna nie używa zmiennych klasy zewnętrznej - modyfikator static przy deklaracji klasy wewnętrznej w javie

Zadanie 3: Klasy wewnątrze procedur

Rozszerzenia języka

Inicjalizacja zmiennych

Zmień deklaracje zmiennych tak, żeby przy deklaracji w procedurze, rekordzie lub klasie (ale nie jako parametru funkcji) trzeba było (obowiązkowo!) podać wartość inicjalizacji zmiennej. Przykład:

var x : int = 50;


Przyjmij, że inicjalizacja tablic i rekordów następuje w momencie ich tworzenia (new):

y = new int[3*x] of 5;
z = new myRecord { field1 = 4, field2 = "ala ma kota"};

Przy inicjalizacji zmiennej dopuszczalne jest użycie zmiennej zadeklarowanej wyżej na tym samym poziomie, wszystkich funkcji na tym poziomie oraz wszstkich zmiennych i funkcji zadeklarowanych na poziomach wyższych.

Odśmiecanie

Usuń konstrukcję delete i zrób zamiast tego automatyczne odśmiecanie.

Ulepszenie read i write

Język Kotek zawiera bardzo prymitywne mechanizmy wejścia wyjścia. Rozszesz język o:

  • możliwość odczytania wartości do pola rekordu lub klasy oraz do elementu tablicy (obecnie gramatyka dopuszcza czytanie tylko zmiennej atomowej)
read a[5];
read mojRekord.pole1;
  • możliwość czytania i pisania wielu wartości na raz
read a[i], b[i];
write "a[5] = ", a[5];


Rzutowanie i sprawdzanie typu obiektu

Język nie zawiera rzutowania na typy. Jest to konstrukcja bardzo często wykorzystywana w programowaniu obiektowym, gdy trzeba zrzutować obiekt na typ podlkasy. Do tego jest też potrzebne sprawdzanie, czy obiekt jest elementem danej klasy.

Rozszerz język o konstrukcję rzutowania:

(Podklasa) mojObiekt

i sprawdzania typu:

obiekt instance of klasa

Obie konstrukcje są wyrażeniami. Pierwsza daje typ Podklasa a druga typ int (wartosc 0 lub nie-zero)


Typ bool

W języku nie ma typu bool. Dodaj ten typ do języka. Popraw analizę semantyczną tak, aby rozróżniać typy int i bool. Rozszeż wyrażenia logiczne tak, aby

a || b || c
a && b && c
a && b || c

były poprawnymi wyrażeniami. Załóż priorytet && nad ||.

Typ zmiennoprzecinkowy

Dodaj do języka typy zmiennnoprzecinkowe: float (pojedyncza precyzja) i double (podwójna precyzja). Zmień analizę semantyczną tak, aby uwzględniała nowe typy. Dodaj operator rzutowania na nowe typy.


Chronione pola klasy

Dodaj do języka mechanizm ochrony deklaracji klasowych. Deklaracja będzie rozszerzona o modyfikator private, public i protected (obok nazwy typu deklaracji):

var private x : int;
function public f() : bool;
type protected typ = { var x: int; var y : int };

Deklaracje public mają być widoczne zawsze, private tylko wewnątrz klasy a protected wewnątrz klasy i w podklasach.