Örebro universitet
Institutionen för naturvetenskap och teknik
Thomas Padron-McCarthy (thomas.padron-mccarthy@oru.se)




Tentamen i

Kompilatorer och interpretatorer

torsdag 13 januari 2022

Gäller som tentamen för:
DT501A Kompilatorer och interpretatorer för civilingenjörer, provkod A001



Hjälpmedel: Inga hjälpmedel.
Poängkrav: Maximal poäng är 40.
För godkänt betyg krävs totalt minst 22 poäng.
Resultat: Meddelas senast torsdag 3 februari 2022.
Återlämning av tentor: Elektroniskt via webbportalen Studenttjänster.
Examinator och jourhavande: Thomas Padron-McCarthy, telefon 070 - 73 47 013.





LYCKA TILL!

Formelsamling

1. Eliminering av vänsterrekursion

En vänsterrekursiv grammatik kan skrivas om så att den inte är vänsterrekursiv. Antag att en regel (eller, korrektare uttryckt, två produktioner) i grammatiken ser ut så här:
A -> A x | y
A är en icke-terminal, men x och y står för godtyckliga konstruktioner som består av terminaler och icke-terminaler.

Regeln ersätts av följande två regler (eller, korrektare uttryckt, tre produktioner), som beskriver samma språk men som inte är vänsterrekursiva:

A -> y R
R -> x R | empty

2. Vänsterfaktorisering

Antag att grammatiken innehåller denna regel (två produktioner):
A -> x y | x z
A är en icke-terminal, men x, y och z står för godtyckliga konstruktioner som består av terminaler och icke-terminaler.

Skriv om till dessa tre produktioner:

A -> x R
R -> y | z

Uppgift 1 (11 p)

En kompilators arbete brukar delas in i ett antal faser.

a) Skriv upp vad faserna heter, och numrera dem i deras logiska ordning.

b) Vilken fas hör var och en av termerna nedan ihop med? Det kan hända att en del passar in på mer än en fas. Det kan hända att en del inte passar in på någon fas alls.

Skriv fasens nummer enligt ditt svar på a-delen vid varje term, och lämna in det här bladet tillsammans med dina övriga svar!

aktiveringspost
aktuell token
anropskonventioner
anropsstack
basic block
Bison
copy propagation
dataflödesanalys
dekorerat parse-träd
dynamisk länkning
eliminering av svansrekursion
eliminering av vänsterrekursion
FIRST()-konflikt
flödesgraf
Flex
gemensamma deluttryck
grammatik
heap
icke-terminal
instruktionsval
kontextfri grammatik
Lex
lexem
lexikaliskt värde
LL(1)
lookahead
loop unrolling
LR(1) 
operatorprioritet
operatorassociativitet
parse-träd
produktion
reduce-reduce-konflikt
registerallokering
shift-reduce-konflikt
skräpsamling
startsymbol
statiska data
statisk länkning
syntaxträd
terminal
token
treadresskod
tvetydig grammatik
typkontroll
typsystem
vänsterrekursion
Yacc

Uppgift 2 (8 p)

Det här är ett programavsnitt i ett C-liknande språk:
    a = 1;
    b = 2;
    if (c < d * e + f * g * h) {
        j = 3;
        while (j < k) {
            j = j + 4 * m;
            k = 5;
        }
        k = 6;
    }

Översätt ovanstående programavsnitt till två av följande tre typer av mellankod. (Skulle du svara på alla tre, räknas den med högst poäng bort.)

a) ett abstrakt syntaxträd (genom att rita upp trädet!)
b) postfixkod för en stackmaskin
c) treadresskod

Observera: Två av typerna, inte alla tre!

Scenario till uppgift 3-6

JSON står för JavaScript Object Notation och är ett kompakt, textbaserat format för att utbyta data. Här är ett exempel (ursprungligen från Wikipedia) på hur JSON kan se ut:

{
    "förnamn" : "Emma",
    "efternamn" : "Svensson",
    "ålder" : 25,
    "adress" : {
        "gatuadress" : "Drottninggatan 47",
        "postort" : "Boden",
        "postnummer" : "96 177"
    },
    "telefonnummer" : "070-1234567"
}

Vi ska arbeta med en delmängd av JSON, som vi kan kalla Mini-JSON. Mini-JSON innehåller:

Den som känner till hur JSON ser ut på riktigt ser att vi saknar en del saker i Mini-JSON, främst arrayer, icke-hela tal, booleska värden och värdet null. Exemplet ovan är giltig Mini-JSON. Här är några ytterligare exempel på objekt som man kan uttrycka med Mini-JSON:

{ }

{ "namn" : "Örebro", "befolkning" : 126009, "latitud" : 59, "longitud" : 15 }

{
    "typ" : "rektangel",
    "hörn-1" : {
        "x" : 17,
        "y" : 26 },
    "hörn-2" : {
        "x" : 220,
        "y" : 120 }
}
JSON kan skrivas på fritt format. Det sista exemplet ovan skulle också kunna skrivas så här:
{"typ":"rektangel","hörn-1":                  {"x"

:17,"y":26},"hörn-2":{"x":220,"y":120}}

Uppgift 3 (4 p)

a) (2p) Vilka terminaler behövs för att man ska kunna skriva en grammatik för Mini-JSON?

b) (2p) En del av terminalerna har inte fixa lexem, utan kan se olika ut. Skriv, för varje sådan terminal, ett reguljärt uttryck som beskriver hur den får se ut!

Uppgift 4 (5 p)

Skriv en grammatik för Mini-JSON. Startsymbolen ska vara objekt, som representerar ett Mini-JSON-objekt enligt scenariot ovan.

Uppgift 5 (4 p)

Ett parse-träd (ibland kallat "konkret syntaxträd") innehåller noder för alla icke-terminaler. Rita upp parse-trädet för det här Mini-JSON-objektet, enligt din grammatik i uppgiften ovan:

{ "namn" : "Örebro", "befolkning" : 126009 }

Uppgift 6 (8 p)

Skriv en prediktiv recursive-descent-parser för Mini-JSON i ett språk som åtminstone liknar C, C++, C# eller Java. Du behöver inte skriva exakt korrekt programkod, men det ska framgå vilka procedurer som finns, hur de anropar varandra, och vilka jämförelser med tokentyper som görs. Du kan anta att det finns en funktion som heter scan, som returnerar typen på nästa token, och en funktion som heter error, som man kan anropa när något gått fel och som skriver ut ett felmeddelande och avslutar programmet.