typ, slut, sportnamn, semikolon
b) (1p)
[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
c) (2p)
([0-9]+:)?[0-9]?[0-9]:[0-9][0-9](\.[0-9]+)?
dagbok -> satser slut ;
satser -> sats satser | empty
sats -> typsats | träningssats
typsats -> typ sportnamn ;
träningssats -> datum sportnamn ; | datum sportnamn tid ;
b) (2p)
De två produktionerna
träningssats -> datum sportnamn | datum sportnamn tid ;
ger en FIRST()-konflikt, och måste vänsterfaktoriseras. Skriv om dem till:
träningssats -> datum sportnamn valfri-tid;
valfri-tid -> tid | empty
Här är en kort träningsdagbok:
typ vila; 2009-10-19 vila 24:00:00; 2009-10-20 fika 1:00:00; slut;
Rita upp ett parse-träd för denna träningsdagbok, med din grammatik från (b-)uppgiften ovan.
Du kan anta att det redan finns en funktion som heter scan, och att den returnerar typen på nästa token.
Ett programs adressrymd kan delas upp i fyra delar: programkod och konstanter, statiska data, heap och stack. Rita upp hur stacken, heapen och statiska data ser ut när programkörningen kommer till kommentaren "Här!".#include <stdlib.h> #include <stdio.h> int x = 1; int apa(int a, int b) { int* p = malloc(sizeof(int)); *p = a; x = a; if (a <= 2) { /* Här! */ return 3; } else { return apa(a - 4, b); } } void svamp(int a, int y) { int z; z = 5; z = apa(6, x); } int main(void) { int a; int y; a = 7; y = 8; svamp(a, y); a = 9; return 0; }
Översätt ovanstående programavsnitt till var och en av följande tre typer av mellankod.i = 0; j = 10; n = 0; while (i < j) { if (i % 2 == 0) i = i + 2; else j = j - 1; n = (j - i - 1) / 2; }
a) ett abstrakt syntaxträd (genom att rita upp trädet!)
b) postfixkod för en stackmaskin
a) Skriv en grammatikregel för while-satsen i C.
b) Välj en form av mellankod (bland dem från uppgift 6 ovan), och tala om vilken du valde. Skriv sedan en syntax-styrd definition eller ett syntaxstyrt översättningsschema (och tala om vilken du valde) för översättning av while-satsen till mellankod. (Tala också om vilket du valde.)
a) Kompilatorn har ju faser som "scanning", "parsning" och så vidare. Varför finns det ingen fas i kompilatorn som heter "skräpsamling"? Skräpsamling är ju ett ändå ganska viktigt begrepp i modern programmering?
b) Jag tycker att man borde sluta med kompilatorer och bara använda interpretatorer, för interpretatorer måste ju vara mycket snabbare. En kompilator översätter ju först källkoden, innan den kan köras, medan en interpretator börjar köra programmet direkt!
c) Bison säger att jag har en massa "shift/reduce"-konflikter här i min grammatik. Vad kan det bero på? Är det farligt?