Beskrivelse av programmeringsspr�ket Db (D-flat).
Her beskrives syntaksen og den statiske semantikken (hva som skal sjekkes av kompilatoren) til spr�ket Db. Den dynamiske semantikken (alts� hva som skal gj�res under utf�relsen) skulle v�re rimelig opplagt, men eventuelle detaljer som er n�dvendige vil vi komme tilbake til i forbindelse med oblig 2.
Db er med vilje lagt opp til � ha en del likhetstrekk med C (og andre spr�k i samme familien...).
Syntaks
I beskrivelsen under er ikke-terminaler skrevet med store bokstaver, og metasymbolene (i bokas betydning, alts� de som brukes til � beskrive grammatikken) er : ->, |, (, ), {, }, [, ]. Her betyr {...} gjentakelse null eller flere ganger, og [...] betyr at det kan v�re med eller ikke.
Alt annet, som er skrevet som tette sekvenser er terminalsymboler, og de med sm� bokstaver er reserverte (!) n�kkelord. Merk dog at alle terminalsymbolene er skrevet i anf�rselstegn for � skille dem fra de tilsvarende metasymbolene.
Det er noen terminaler som ikke g�r greit fram av syntaksen under, og disse er betegnet NAME, INT_LITERAL, FLOAT_LITERAL og STRING_LITERAL.
NAME
NAME skal starte med bokstav, og deretter v�re en sekvens av siffer, bokstaver og underscore. De kan ikke v�re p� mer enn 16 tegn, og alle er signifikante. Store og sm� bokstaver regnes som forskjellige tegn. Merk alts� at alle n�kkelord skrives med sm� bokstaver, og at de ikke kan brukes som vanlige navn.
INT_LITERAL
INT_LITERAL skal inneholde ett eller flere siffer.
FLOAT_LITERAL
FLOAT_LITERAL skal inneholde ett eller flere siffer, fulgt av et punktum, fulgt av ett eller flere siffer.
STRING_LITERAL
STRING_LITERAL skal best� av en tekststreng innesluttet i anf�rselstegn ("). Strengen kan ikke inneholde linjeskift. Den semantiske "verdien" av en STRING_LITERAL er kun det som er inni anf�rselstegn; selve anf�rselstegnene skal ikke inkluderes.
structs
Db st�tter brukerdefinerte typer kalt "strukter". De tilsvarer struct -konstruksjonen i C og lignende spr�k. I Db defineres de med n�kkelordet "struct" fulgt av en serie variabeldefinisjoner. Variable av strukt-typer kan antas � ha referanse-semantikk, m.a.o, de oppf�rer seg som pekere. Instanser av strukter kan opprettes med n�kkelordet new. Dette gj�r det mulig � ha referanser til strukt-typer som attributter til strukter. Den spesielle verdien "null" betegner "ingen struct", som i Cb eller Java. Merk at, i motsetning til C/C++, skal en struct-deklarasjon ikke avsluttes med semikolon. Operatoren . (punktum) brukes for � aksessere attributter i en struct. Denne operatoren har h�yere presedens enn alle andre operatorene, med unntak av parenteser.
pass-by-reference
Db st�tter s�kalt "pass-by-reference" (selvsagt i tillegg til "vanlig" pass-by-value). Endringer som gj�res i en funksjon med en pass-by-reference parameter vil reflekteres i skopet til den kallende funksjonen (jfr operatoren & i C++ eller "ref" i Cb). pass-by-reference markeres i Db med n�kkelordet "ref", som m� brukes b�de i funksjonssignaturen og i funksjonskallet. Et eksempel:
func swap( ref int a, ref int b ) { int tmp = a; a = b; b = tmp; } func Main() { int x = 42; int y = 84; swap( ref x, ref y ); }
Det er tillatt � sende struct-attributter by ref (m.a.o., kallet func( ref a.b ) er tillatt.
(Syntaksen for ref parametre er i stor grad hentet fra Cb.)
Eksponensiering
Db st�tter en eksponensieringsoperator ** (som i Fortran). Uttrykket 5**2 betyr 5 opph�yd i andre potens. Merk at **, i motsetning til de fleste andre operatorene, er h�yre-assosiativ. Det inneb�rer at 5 ** 2 ** 3 betyr 5 ** (2 ** 3). Uttrykk med ** evaluerer alltid til en float.
Indre deklarasjoner
I en funksjon kommer alle deklarasjonene f�r den f�rste eksekverbare setningene. Disse deklarasjonene kan inkludere alt som kan deklareres p� ytterste niv�, alts� variable, funksjoner og structer. Det sier seg selv at navnene p� disse funksjonene og structene ikke er tilgjengelige utenfor den funksjonen de er deklarert i (men navnene p� medlemmene i structene er naturligvis tilgjengelig fra det omliggende skop).
Short-circuit evaluation
De logiske operatorene && og || benytter s�kalt short-circuit evaluation. Det betyr at dersom det f�rste uttrykket evaluerer til sann, skal ikke det andre uttrykket evalueres i det hele tatt.
Typer og implisitt typekonvertering
Det er tillatt � tilegne uttrykk av typen int til variable av typen float. Det motsatte er ikke tilfelle. Det finnes ingen cast-operator. Dersom et aritmetisk uttrykk inneholder en eller flere subuttrykk av typen float, skal hele uttrykket evalueres med flyttallsaritmetikk.
Merk at dette ogs� gjelder i andre sammenhenger der typekonverteringer kan v�re naturlig - dersom en funksjon er definert til � returnere en float, m� man tillate at uttrykk av typen int brukes.
Det er ingen implisitte konverteringer mellom int og bool - man kan ikke gj�re f.eks if ( 1 ){}.
Standardbibliotek
Programmet har et standardbibliotek med et sett av IO-funksjoner.
func read_int()
Leser en int fra standard inn.
func read_float()
Leser en float fra standard inn.
func read_char()
Leser ett tegn fra standard inn og returnerer ASCII-verdien som en int. Returnerer -1 ved EOF.
func read_string()
Leser en string fra standard inn opp til f�rste whitespace.
func read_line()
Leser en tekstlinje fra standard inn.
func print_int( int i )
Skriver en int til standard ut.
func print_float( float f )
Skriver en float til standard ut.
func print_str( string s )
Skriver en streng til standard ut.
func print_line( string s )
Skriver en streng til standard ut fulgt av et linjeskift.
Kommentarer
Kommentarer i Db starter med // og fortsetter linjen ut(som i C++/Java/Cb). Man trenger ikke � st�tte C's /* */-kommentarer. Merk at det ikke er noen grunn til � gi kommentarer og whitespace videre til parseren - disse kan trygt fjernes i scanneren.
Grammatikk
Grammatikken som egen fil.Presedens
Presedens-rekkef�lge (fra lavest til h�yest):
- ||
- &&
- ! (alts� "!a && b" betyr "(!a) && b")
- Alle relasjonsoperatorene
- + og -
- * og /
- ** (eksponensiering)
- . (punktum, for struct-aksess)
Assosiativitet
- ||, &&, +, -, *, / og . er venstre-assosiative
- ** er h�yre-assosiativ
- Relasjonoperatorene er ikke-assosiative (alts� er f.eks. "a < b+c < d" ulovlig).
- Det er lov � skrive "!!! b", og det betyr: "!( !( !b))).
Merk at spr�ket ikke st�tter un�r minus (og heller ingen un�r pluss, men det er det vel f� som gr�ter over).
Semantikk (ikke viktig i oblig 1)
Bruksforskomster av navn uten punktum foran bindes p� vanlig m�te til en deklarasjon: Let ut gjennom "blokkene" (alts� funksjoner eller program) som omslutter bruksstedet. Se p� deklarasjonene i hver blokk, og velg den deklarasjonen der du f�rst f�r treff. Om man ikke f�r treff er det en feil i programmet. Her regnes en formell parameter med til de lokale variable i prosedyren.
Spr�ket har fire innebygde typer: "float", "int", "string" og "bool". I tillegg utgj�r hver struct-deklarasjon en ny type. N�r man leter etter en strukt leter man ogs� utover, blokk for blokk, som for andre navn. Se ovenfor.
Alle navn m� v�re deklarert (tekstlig) f�r de brukes (og sjekkingen kan derved naturlig gj�res i ett gjennoml�p).
Semantiske regler som m� sjekkes:
Uttrykk
- Det m� sjekkes at uttrykk er typeriktig formet, p� den opplagte m�ten. Hele uttrykket blir derved ogs� tilordnet en type.
- Det m� sjekkes at typen p� begge sider av en tilordning er den samme. MERK: Det er lov b�de � lese og tilordne verdi til en formell parameter inne i funksjonen.
- Det m� sjekkes at typen av uttrykket etter "if" og etter "while" er "bool".
- Det m� sjekkes at det uttrykket som kommer foran et punktum evaluerer til en struct-type.
- Likeledes m� det sjekkes at navnet som kommer etter et punktum er navnet p� et attributt av struct-typen.
Funksjoner
- Funksjoner som kalles inne i et uttrykk m� v�re deklarert med "float", "int", "string" eller "bool" eller med navnet p� en struct-type.
- Navn som brukes som funksjon (i kall) m� v�re deklarert som funksjon, og tilsvarende for variable (heri inkludert parametere).
- Det m� sjekkes at antall og typer p� parametere stemmer overens mellom kallsted og deklarasjon.
- Return-setninger kan bare forekomme inne i funksjons-deklarasjoner, og de angir at funksjonen skal terminere.
- Dersom funksjonen er deklarert uten returtype skal return-setningen ikke ha noe uttrykk, ellers skal den ha et uttrykk av funksjonens type.
- Dersom funksjonen er deklarert med en returtype m� det sjekkes at funksjonen inneholder minst ett return-statement som vil n�s uansett.
Generelt
- Det m� ikke v�re dobbeltdeklarasjoner innen en "blokk" (og her regnes samme navn p� funksjon og variabel som en dobbelt-deklarasjon). Dette gjelder naturligvis ogs� innenfor structer.
- Navnet p� en formell parameter m� (alts�) ikke kollidere med navnet p� noen lokal deklarasjon i funksjonen.
- Det m� sjekkes at alle navn som brukes er deklarerte (se bindingsreglen over).
- Det m� sjekkes at det p� ytterste niv� deklareres en funksjon med signaturen func Main(). Denne blir kalt av kj�retidsmilj�et n�r et Db-program kj�res.
- Det m� sjekkes at n�kkelordet "ref" brukes b�de ved kall og i funksjonssignaturen, eller ingen av stedene.