Merk: Dette er en tidlig utgave. Det kan komme presiseringer.
Dette er den f?rste av to oppgaver v?ren 2005. Oblig 2 vil
bygge videre p? det som gj?res i oblig 1.
Hensikten med oppgaven
Tanken bak denne oppgaven er at man skal f? litt "hands on" erfaring med
f?lgende ting:
-
Omarbeide en grammatikk fra ?n form (utvidet BNF) til en annen (BNF som passer
til Yacc).
-
Bruke Lex og Yacc (eller lignende, f.eks. Flex og Bison).
-
Kunne kontrollere presedens og assosiativitet p? to m?ter:
(1) Ved ? lage en entydig grammatikk som gir riktig presedens/assosiativitet,
og
(2) gi en flertydig grammatikk og styre presedens og assosiativitet ved
passelige kommandoer i Yacc.
-
Designe noder til et passelig abstrakt syntaks-tre, og komme i inngrep med
Lex/Yacc slik at man f?r bygget opp disse tr?rne.
-
Gj?re noe passelig med tr?rne som blir bygget. Vi skal skrive det abstrakte
syntakstreet til standard ut i et gitt format. I tillegg skal uttrykk
dumpes i en parentetisk form med korrekt presedens og assosiativitet.
Implementasjonsspr?k
Det er lagt opp til at man implementerer kompilatoren i C eller C++. Dersom man
?nsker ? utf?re oppgaven i C# eller Java vil dette ogs? bli godtatt, men man er
da i st?rre grad p? egen h?nd. Man m? da f.eks finne alternativer til yacc/lex
p? disse platformene (de finnes). Implementasjoner i mer obskure spr?k vil ikke
bli rettet (ingen kompilatorer i SML, Prolog eller lisp, takk). Hvis i tvil,
sp?r gruppel?rer.
Selve oppgaven
Oppgaven g?r ut p? ? lage et program, ved hjelp av Lex og Yacc (eller
tilsvarende), som skal sjekke at programmer i spr?ket Diss er syntaktisk
korrekte. Spr?ket er definert i et eget notat som kan hentes
her . Merk at det i oblig 1 ikke er n?dvendig ? sjekke at
program er semantisk korrekt. Man kan trygt ignorere alt som st?r i notatet
vedr?rende sjekking av semantikk og/eller har med kj?retidsforhold ? gj?re.
Glupe hoder vil muligens komme til den slutning ut fra dette at semantisk
sjekking blir en del av oblig 2, og man ser ingen grunn til ? avkrefte slike
spekulasjoner.
Det ville v?rt naturlig med en del 3 der man laget en kodegenerator for spr?ket,
men vi avst?r fra dette.
Syntaks-tre
Man skal under parseringen av spr?ket bygge opp et abstrakt syntaks-tre. Man
skal designe noder (og implementere dem) for dette treet. Man m? holde greie p?
subtr?r til treet mens parseringen av uttrykk foreg?r. Dette gj?res greiest med
Yacc's $-variable p? stakken, som dermed m? defineres til ? v?re pekere til
tre-noder.
Legg merke til at bare det abstrakte syntaks-treet skal lages og
skrives ut. For produksjoner av typen "if_stmt ->stmt" skal det alts?
ikke lages noen ny node.
Utskrift av syntaks-tre
N?r man har bygget opp et abstrakt syntaks-tre, skal dette skrives ut i
prefiks-form. Hver node i det abstrakte treet skal representeres med ett par av
parenteser, og hvert "barn" av denne noden skal inng? i mellom disse
parentesene. Rett etter f?rste parentes kommer navnet p? noden (som angitt i
grammatikken), fulgt av attributtene (barna) til noden. Dette illustreres best
ved et eksempel:
Eksempelet kan anses som definitivt. Whitespace er valgfritt. Dog, for ?
bevare egen og andres mentale helse, vil vi p? det sterkeste anbefale en
layout tilsvarende den i eksempelet.
Oppgaven skal l?ses med to forskjellige uttrykks-grammatikker
-
Det skal brukes en grammatikk for hele Diss, der man lager en egen entydig
syntaks for uttrykk. Denne skal alts? uttrykke alt om presedens og
assosiativitet. Man m? da alts? innf?re en egen ikke-terminal for hvert
presedens-niv?, og gjennom grammatikken s?rger for riktig presedens og
assosiativitet (og ikke-assosiativitet) for operasjonene.
-
Det skal ogs? lages en versjon der det bare er en enklest mulig flertydig
syntaks for uttrykk som omfatter b?de logiske og aritmetiske uttrykk. Denne
skal alts? likne den som er angitt i spr?kdefinisjonen av Diss. Her skal de
konfliktene som da n?dvendigvis oppst?r l?ses ved ? spesifisere assosiativitet
og presedens til Yacc (med %left, %right, %nonassoc, etc.).
Merk at det er et problem med grammatikken n?r det gjelder if/else-setningen
(jfr Louden 120-122). Man kan l?se dette p? to m?ter: Enten bruke
fremgangsm?ten angitt i Louden (s 121), eller bruke Yacc-direktivet
%expect 1. Dette vil fortelle Yacc at man forventer at grammatikken
inneholder ?n (og bare ?n) shift/reduce konflikt, og man vil ikke f?
advarsler om dette. Yacc vil i dette tilfelle gj?re det "riktige" valget ved ?
foretrekke en shift fremfor en reduce og assosierer dermed en else med n?rmeste
if (jfr Louden 235-236).
Man skal gj?re en sammenlikning av de to parserne. Unders?k hvor mange
tilstander Yacc-automaten f?r for de to grammatikkene.
Leksikalsk analyse
Man skal gruppere de forskjellige leksikalske enheter for Diss i token-grupper
p? en fornuftig m?te, og gi hver av disse token-gruppene et navn med store
bokstaver (som antakeligvis deklareres greiest i Yacc-beskrivelsen). Ved
levering av et token fra Lex vil dermed variablen yytext angi hvilket token det
er innen gruppen.
Feil i Diss-programmet
Dersom det oppdages en syntaktisk feil i programmet skal man bare stoppe
analysen av Diss-programmet, og melde at det er funnet en feil. Det er ikke
krav om noen spesielt intelligent feilmelding (men det er morsomt om man kan f?
til noe her).
Gjennomf?ring og levering
Man kan arbeide to og to med denne oppgaven eller levere enkeltvis. Det som
skal leveres er:
-
En forside med det fulle navnet og bruker-navnet p? den/de som er med p? denne
besvarelsen.
-
En kort rapport om gjennomf?ringen, hvor mange tilstander det ble med de to
versjonene av uttrykk, etc.
-
Lex-koden for scanneren
-
Yacc-koden for de to syntaks-variantene
-
Utskrift av noen gitte testprogrammmer (blir lagt ut, og beskjed gitt) og dump
av syntaks-tre for disse, ved de to syntaks-variantene.
Dokumentasjon av Lex og Yacc
Det viktigste her er det som st?r i l?reboka i kap 2.6 og 5.5, og det blir ogs?
delt ut noe tilsvarende fra en annen bok. I tillegg kan man skrive ut
"man-sidene" til Lex og Yacc (ved f.eks.: "print -man yacc").
Det finnes ogs? to tilsvarende Gnu-produkter Flex og Bison som er noks? like
Lex og Yacc, og som det ogs? finnes en del dokumentasjon om. Se
http://www.gnu.org/software/flex/manual/ og
http://www.gnu.org/software/bison/manual/
|