FACIT TILL OMTENTAMEN I PROGRAMSPRÅK DVG C01 140821 kl. 08:15-13:15 Ansvarig Lärare: Donald F. Ross Hjälpmedel: Bilaga A: BNF-definition Betygsgräns: Kurs: Max 60p, Med beröm godkänd 50p, Icke utan beröm godkänd 40p, Godkänd 30p (varav minimum 20p från tentan, 10p från labbarna) Tenta: Max 40p, Med beröm godkänd 34p, Icke utan beröm godkänd 27p, Godkänd 20p Labbarna: Max 20p, Med beröm godkänd 18p, Icke utan beröm godkänd 14p, Godkänd 10p SKRIV TYDLIGT LÄS UPPGIFTERNA NOGGRANT 1. Ange kortfattade svar på följande uppgifter: (a) Ge en definition av (i) aktuell parameter samt (ii) formell parameter (1) Expression (2) Identifier (b) Vad är skillnaden mellan statisk och dynamisk scopning? (Static and dynamic scoping) a. Static defined by the program text the environment is the local environment plus all non hidden objects in the lexically enclosing environment(s) b. Dynamic defined by the call sequence the environment is the local environment plus all non hidden objects going backwards through the call sequence (c) Vad är skillnaden mellan ett parseträd (parsetree) och ett syntaxträd (syntax tree)? a. Parse Tree contains non-terminal symbols in the interior nodes b. Syntax tree only contains terminal symbols in the nodes correcponds to the Parse Tree without the non-terminal nodes for a given expression DFR/AA/ND 140821 PS omtentamen - facit Sidan 1 av 14
(e) Ge ett exempel av ett parseträd samt syntaxträd för uttrycket 2+2. a. Parse Tree (assuming the grammar in Appendix A) Syntax Tree + expr 2 2 term R1 factor R2 + term R1 operand factor R2 number operand 2 number 2 (f) Hur lösas problemet med vänsterrekursion i en grammatikdefinition? a. Re-write the grammar using right recursion b. e.g. Left Recursion: the general case is A ::= B A C B c. Rewriting for right recursion gives d. Right (tail) Recursion is: A ::= B ATail ; ATail ::= empty C A (g) I en lexer, vad är ett mönster (pattern)? Ge ett exempel. a. A pattern is either a literal string e.g. program or a regular expression such as b. [A Za--z][A Za z0--9]* to define an identifier (h) Förklara varför identifierare inte deklarerat är ett semantiskfel och inte ett syntaxfel. a. This is a semantic error since the grammar (syntax) does not define any rules as to whetheror not an identifier is used but not declared to do this, a symbol table must be used (again, this is not part of the syntax). (i) Förklara begreppet scope. a. The scope of an object consists of all the environments (local) in with the object is visible (accessible) DFR/AA/ND 140821 PS omtentamen - facit Sidan 2 av 14
(j) Vad är en predikat i ett programspråk? a. A Boolean function i.e. a function which returns either true or false. (k) Förklara begreppet ett deklaritivt språk. a. Examples are Prolog and Lisp. b. The program is written without regard to the flow of control (compare this with imperative / OO languages where the flow of control is an intregal part of the program. c. Prolog gives a set of rules for calculation and the Prolog system decides which of these rules to apply. i. Totalt 5p DFR/AA/ND 140821 PS omtentamen - facit Sidan 3 av 14
2. Programmeringsspråk Diskutera ingående den historiska utvecklingen av dagens programmeringsspråk. Kommentera dagens programmeringsspråk samt vart man är på väg med hänsyn till framtidens utveckling av programmeringsspråk. Ge gärna exempel. Marks for good answers 5p Historical development Machine code assembler 3 rd generation languages (imperative) OO programming Functional languages Prolog Haskel / Miranda Discuss the level of abstraction here Improved flow of control (imperative languages) Stack model from Algol60 on (not part of the earlier Fortran II or IV languages) OO Programming discuss the development and contribution DFR/AA/ND 140821 PS omtentamen - facit Sidan 4 av 14
3. Felhantering och återhämting Diskutera det generella problemet med återsynkronisering och felåterhämtning i en parser. 1. There are 2 cursors (pointers) in the parsing process (i) in the parse tree and (ii) in the input stream. When an error occurs, these may become unsynchronised and the problem is often how to re-synchronise them. There are 2 assumptions which may be made. 2. Assumption 1 is that there is a missing token in the input stream, in which case no resynchronisation action need be taken since the parser cursor will move to the correct part of the grammat rule which requires the next token on the input stream. 3. Assumption 2 is that there is an extra token in the input stream, in which case this token is ignored and the next token read in 4. If either of these assumptions is not true then it can be more difficult to resynchronise the two cursors and a number of consequential errors may be generated by the parser. 2p Titta på grammatiken nedan. I den Right Recursive Grammar skriv pseudokod till varje icketerminal symbol (dvs line, expr, R1, term, R2 samt factor) och visa hur och var man kan hantera syntaktiska fel. Finns det någon tumregel/några tumregler för att bestämma när och var man kan införa syntaxkontroll i denna grammatik? Original Grammar! Right Recursive Grammar! line -> expr {;expr ; '\n'! line -> expr {;expr ; '\n'! expr -> expr + term term! expr -> term R1! R1 -> e '+' term R1! term -> term * factor factor! term -> factor R2! R2 -> e '*' factor R2! factor -> '(' expr ')' DIGIT! factor -> '(' expr ')' DIGIT!! (e = empty) 3p Rules of Thumb Totalt 5p 1. If the rule consists of non-terminals only then no check can be made. (expr & term) 2. If the rule contains an empty production then no check can be made. (R1 & R2) 3. Only if the rule contains terminal symbols (and no empty symbol) can syntax checks be performed. (line & factor) See the examples below. DFR/AA/ND 140821 PS omtentamen - facit Sidan 5 av 14
void factor() { if (lookahead == '(') { match('('); expr(); if (lookahead == ')') match(')'); else error("*** ')' EXPECTED *** (in procedure factor)"); return; else if (lookahead == DIGIT) { match(lookahead); return; else error("*** UNEXPECTED SYMBOL *** (in procedure factor)"); printf("\n *** Skipping input symbol *** \n "); plookahead(); lookahead = yylex(); /* skip over symbol - no synch!!! */ void R2() { if (lookahead == '*') { match('*'); factor(); R2(); ; ; void term() { factor(); R2(); void R1() { if (lookahead == '+') { match('+'); term(); R1(); ; void expr() { term(); R1(); void line() { do { iserror = 0; expr(); plookahead(); if (lookahead == ';') match(';'); else error("*** ';' EXPECTED *** (in procedure line)"); if (!iserror) printf(" \n Parse Successful! \n"); else printf(" \n Parse Failed! \n"); while (lookahead!= '\n'); if (lookahead == '\n') match('\n'); else error("*** NEWLINE EXPECTED *** (in procedure line)"); ; DFR/AA/ND 140821 PS omtentamen - facit Sidan 6 av 14
4. Funktionell programmering Till vilken mån kan man programmera på ett funktionellt sätt i C? Finns det några tumregler? Om svaret är ja vilka är dessa tumregler? Diskutera ingående. Ge gärna exempel på pseudokod där du visar ett funktionellt sätt samt ett icke-funktionellt sätt att programmera samma idé. What are the characteristics of functional programming? 5p 1. Use expressions 2. no global variables 3. no side effects in function calls (function applications) 4. available constructs in C use only these constructs a. functions & expressions b. the conditional expression? : which corresponds to cond in Lisp 5. keep functions short and to the point Example:- counting the number of elements in a list. static int be_size_list() { int size=0; get_seq_first(); while (!is_seq_empty()) { size++; get_seq_next(); return size; static int be_size_list(listref L) { return is_empty(l)? 0 : 1 + be_size_list(tail(l)); 5. Parametrar Diskutera ingående hur parametrar hanteras vid exekverings-tid (engelska: run-time environment). Marks for good answers. See the revision notes on the web. 5p DFR/AA/ND 140821 PS omtentamen - facit Sidan 7 av 14
6. Lisp Vad är resultatet på varje print operation i följande kod i Lisp? (setf q (last (cons '(A B) (list (append '(A B) '(A B)) '(A B)) ) ) ) (print q) (setf q (remove-if-not #'listp (cons '(A B) (list (append '(A B) '(A B)) '(A B)) ))) (print q) Work from the indside out 1p (append '(A B) '(A B)) (A B A B) (list (A B A B) '(A B)) ) ( (A B A B) (A B) ) (cons '(A B) ( (A B A B) (A B) )) ( (A B) (A B A B) (A B) ) (last ( (A B) (A B A B) (A B) )) ( (A B) ) q is set to ( (A B) ) (remove-if-not #'listp ( (A B) (A B A B) (A B) ) ) ( (A B) (A B A B) (A B) ) Since Each element in the list is a list hence none is removed! q is set to ( (A B) (A B A B) (A B) ) (setf x 'A) (let ((x 'B) (y x)) (setf q (list x y)) (print q) ) (setf q (mapcar #'(lambda (n) (+ (* n 2) 1)) '(5 6 7 8))) (print q) These expressions should be worked through sequentially 1. non-local-x is A 2. The let creates a local environment where local-x is bound to B 3. The question for local-y is which X applies since this is a let (parallel evaluation of let), non-local-x applies and Y is set to A 4. (list x y) therefore gives ( B A ) 5. q is therefore set to ( B A ) 1. (lambda (n) (+ (* n 2) 1)) is a lambda expression with one argument (n) 2. The body of the lambda expression is (* (+ n 1) 2)) i.e. the expression returns 2*n+1 3. The expression is applied to each element in the list (5 6 7 8) This gives the result (11 13 15 17) which is bound to q 1p DFR/AA/ND 140821 PS omtentamen - facit Sidan 8 av 14
(defun p (a b c) (list (list 'a a) (list 'b b) (list 'c c) ) ) (defun q (r s) (if (eql s (first (first r))) ; line 1 (cons (list 's (first (second r)) s) (rest r)) ; line 2 (cons (first r) (q (rest r) s)) ; line 3 ) ) (setf b (p '(a b) '(c d) '(e f))) (print b) (setf q (q b 'b)) (print q) The rseult is b is ((A (A B)) (B (C D)) (C (E F))) and q is ((A (A B)) (S C B) (C (E F))) 1p Förklara stegvis hur proceduren q ovan fungerar med de givna parametrarna. p takes 3 arguments <a> <b> <c> and returns a list ( (A <a>) (B <b>) (C <c>) ) <a> <b> <c> can be of any type - <x> is just a notation to distinguish the formal parameters from their actual values Q is called with 2 actual parameters (i) the list ((A (A B)) (B (C D)) (C (E F))) and (ii) the literal symbol B 1. First call - line 1 checks if the first of the first of parameter 1 is equal to the symbol B i.e. is (first (A (A B)) equal to B answer no 2. First call - line 3 is then executed which is a cons of (A (A B)) with q applied to ((B (C D)) (C (E F))) and the symbol B 3. The second call to q is with parameters ((B (C D)) (C (E F))) and the symbol B 4. Second call line 1 checks if the first of the first of parameter 1 is equal to the symbol B i.e. is (first (B (C D)) equal to B answer yes 5. Second call line 2 work from the inside out a. (second r) is (C (E F) ) b. (first (C (E F)) is C c. (list S C S) is ( S C B ) ; S is B d. (rest r) is (C (E F)) e. (cons (S C B) (C (E F))) is ((S C B) (C (E F))) 6. The value returned from the second call is thus ((S C B) (C (E F))) 7. This is cons:ed with (first r) from the first call i.e. (A (A B)) 8. The final answer is thus ((A (A B)) ((S C B) (C (E F))) 2p Totalt 5p DFR/AA/ND 140821 PS omtentamen - facit Sidan 9 av 14
7. Objektorientering (5p) A. Vad betyder det att en klass är abstrakt? (0.5p) B. Varför deklarerar man vissa klasser som abstrakta? (1.0p) C. Vad innebär det att en medlemsvariabel är private? (0.5p) D. Vad innebär det att en metod INTE är virtuell? (0.5p) E. Givet följande program skrivet i Java. Vad skrivs ut när programmet körs och varför? Utöver att ange rätt utskrift från programmet så skall du även redovisa för de mekanismer som gör att utskriften blir som den blir. class Person { void print() { System.out.println("Person"); (2.5p) class Teacher extends Person { void print() { System.out.println("Teacher"); public class Program { static void print(person person) { person.print(); public static void main(string[] args) { Person person = new Person(); Teacher teacher = new Teacher(); Person xenomorph = new Teacher(); print(person); print(teacher); print(xenomorph); DFR/AA/ND 140821 PS omtentamen - facit Sidan 10 av 14
A. Det går ej att skapa instanser/objekt av klassen. Klassen kan innehålla abstrakta metoder, men inte nödvändigtvis. Abstrakta klasser kan innehålla icke-abstrakta metoder. Abstrakta klasser används inte för att instansiera objekt utan som basklasser för arv. Man kan se en abstrakt klass som en mall från vilken man kan härleda fler utökade klasser via arv. B. Flera anledningar: 1. Man vill inte att klassen skall instansieras av någon anledning. Kan vara tex ett mattebibliotek med statiska/klass-metoder. Genom att göra klassen abstrakt så förhindrar man att onödiga objekt instansieras från klassen. 2. Den mer vanliga anledningen är att klassen innehåller minst en abstrakt metod(dvs en metod utanimplementering/kropp) och då är klassen per automatik abstrakt. C. En medlemsvariabel som är private kan endast nås(läsas/modifieras) av metoder inom den egna klassen. Alla metoder i utomstående klasser(inklusive subklasser) har ej tillgång. D. Om en metod inte är virtuell så är dennas implementation/kropp konstant. Dvs dess implementation kan inte skrivas över/omdfefinieras av en ärvande klass. DFR/AA/ND 140821 PS omtentamen - facit Sidan 11 av 14
E. Följande kommer skrivas ut: Person Teacher Teacher Person är en basklass med en printmetod. Teacher är en härledd klass från Person som har en egen printmetod och därför skriver över/omdefinierar printmetoen. Klassen Program har också sin egen printmetod, men klassen program är inte inblandad i något arv. Program skapar tre stycken objekt. 1styck instans av klassen Person och två stycken instanser av klassen Teacher. Den andra instansen av klassen Teacher lagras i ett dataobjekt av typen Person. Detta är helt godkännt tack vara subtyp-polymorphism som säger att dataobjekt av typen Person kan lagra instanser av klassen Person och alla subtyper(härledda klasser) av klassen Person vilket klassen Teacher är. När anropet till metoden print från metoden main sker så är det metoden print i samma klass som main(dvs Program) som anropas. Denna metod förväntar sig ett objekt av typen Person, men tack vara subtyp-polymorphism så accepterar den även subtyper av Person. Metoden Program.print anropar i sin tur objektets egna printmetod. När ett objekt av klassen Person skickas till metoden Program.print så kommer metoden Person.print att anropas och "Person" skrivs ut. När ett objekt av klassen Teacher skickas till metoden Program.print så kommer metoden Teacher.print att anropas och "Teacher" skrivs ut. Detta gäller för bägge instanserna av klassen Teacher. Oavsett vad vi angett för datatyp när vi lagrade objektet så är fortfarande objektet en instans av klassen Teacher och kommer "agera" därefter DFR/AA/ND 140821 PS omtentamen - facit Sidan 12 av 14
8. Prolog 1. Skriv ett predikat, ersatt_alla(+inelem, +UtElem, +InLista, -UtLista), där alla förekomster av elementet InElem i listan InLista ersätts med elementet UtElem och returnerar listan Utlista. Predikatet måste skrivas så att inte falska lösningar kan erhållas när man trycker ; Exempel på körning:?- ersatt_alla(a, b, [a, c, a, d, a], L). L = [b, c, b, d, b] (2,5 p) 2. Beskriv utförligt med egna ord och med kodexempel hur parserdelen i laborationen kontroller om tokenlistan är korrekt enligt grammatikreglerna. Beskriv också hur vissa av de givna grammatikreglerna måste modifieras för att koden skall fungera. (2,5 p) Totalt 5p (1) ersatt_alla(e1, E2, [], []). /* Basfall 0,5 p */ ersatt_alla(e1, E2, [E1 R1], [E2 R2]) :-!, ersatt_alla(e1, E2, R1, R2). /* Rekursivt fall 1 p */ ersatt_alla(e1, E2, [F R1], [F R2]) :- E1 \= F, ersatt_alla(e1, E2, R1, R2). /* Rekursivt fall 1 p */ För undvikande av falska lösningar skall antingen cut (!) användas i regel 2 eller villkoret i regel 3, annars 0,5 p avdrag. /* Totalt 2,5 p */ (2) Här kan man tänka sig stor variation i svaren. Lite kod av typen prog --> prog_header, var_part, stat_part. var_dec_list --> var_dec. var_dec_list --> var_dec, var_dec_list. /* Högerrekursion */ var --> 259. /* Terminal symbol */ bör finnas med. Dessutom ska koden kommenteras med egna ord. I samband med var_dec_list kan man kommentera vikten av högerrekursion som ju är den modifiering som krävs av grammatikregler för att koden skall fungera. Kommenterar man att skrivsättet med --> är ett förkortat skrivsätt för att slippa skriva ut 2 parametrar i varje predikat är det ett plus. /* Totalt 2,5 p */ OBS. Grammatikreglerna för Pascal skall vara bifogade till tentauppgifterna OBS DFR/AA/ND 140821 PS omtentamen - facit Sidan 13 av 14
Bilaga A - Grammatik: Pascallik språk 1. [prog] ::= [prog header] [var part] [stat part] 2. [prog header] ::= program id ( input, output ) ; 3. [var part] ::= var [var dec list] 4. [stat part] ::= begin [stat list] end. 5. [var dec list] ::= [var dec] [var dec list] [var dec] 6. [var dec] ::= [id list] : [type] ; 7. [stat list] ::= [stat] [stat list] ; [stat] 8. [stat] ::= [assign stat] 9. [assign stat] ::= id := [expr] 10. [expr] ::= [term] [R1] 11. [R1] ::= e + [term] [R1] 12. [term] ::= [factor] [R2] 13. [R2] ::= e * [factor] [R2] 14. [factor] ::= ( [expr] ) [operand] 15. [type] ::= integer 16. [id list] ::= id [id list], id 17. [operand] ::= id number DFR/AA/ND 140821 PS omtentamen - facit Sidan 14 av 14