This always changes as I mark the actual answers given. Last year I was slightly more generous than this marking scheme might imply.
Q1.a.
operator precedence = ... , associativity = ... [2]
precedence: ( ) > ! > == != > | > & [2]
associativity: ( ) ! == != have none, | right, & left [2]
associativity = recursion, precedence = nesting [2]
e.g. a&b&c is (a&b)&c, a|b|c is (a|(b|c),
a&b|c is a&(b|c) etc. [6]
b.
yacc:
%left '&' [%left etc.=1] %right '|' %nonassoc eq ne %nonassoc '!' [%token,y.tab.h etc.=1] %start lines %token id eq ne %% lines : line | lines line ; [line/s,\n =1] line : exp '\n' ; exp : exp '&' exp | exp '|' exp | exp eq exp | exp ne exp | '!' exp | '(' exp ')' | id ; [exp=1]
%{ #include 'y.tab.h' %} %% [eq/ne=.5] [a-zA-Z_][a-zA-Z0-9_]* return id; == return eq; != return ne; [&!|()\n=.5] [&|!()\n] return yytext[0]; [ \t] ; . /* error */ [\s\t.=.5]
Q2.
lexical: group chars into words
pairs = syntactic info, semantic info
discard white space & comments
put names into dictionary namelist
e.g. lexemes, e.g. namelist
syntactic: group words into expressions etc.
represent structure by parse trees
e.g. parse trees
semantic: declarations -> dictionary property entries
- deal with scope rules etc.
- deal with type info
check id kind (var/const/etc.) used correctly
add kind, type, position info
propagate type info thru trees, adding casts
e.g. modified parse trees, e.g. dictionary
code generation: registers used like stack?
add code addresses for functions etc.
e.g. code
code optimisation: global v. peephole
machine independant v. dependant
e.g. optimised parse trees, e.g. code
[1 per point like those above + some details]
[1 per lots of extra detail for a point]
[1 per e.g. for given example, max 20]
Q3.a.
call by value
call by ref
call by copy/back
call by name
call by function
[1 per description, 1 per example, total = 10]
b.
scope = ... , extent = ... [2]
e.g. global, local, block, export/import, etc.
e.g. static, function, recursion, heap, etc.
[1 per description + example, max = 8]
c.
integer: e.g. overflow/modulo arith [1]
float: e.g. overflow/underflow/accuracy [2]
strong typing = ... [1]
advantages = ... [1]
e.g. enum, subrange, new, date/time, flag, etc. [1 per, max=4]
usefulness = almost none unless type-checked etc. [1]
Q4.a.
dangling else = ... [1]
grammar = ... [1]
e.g. [1]
resolution = ... [1]
yacc reports shift-reduce or reduce-reduce ... [1]
yacc does shift etc. [1]
e.g. dangling else [1]
explain y.output [3]
b.
e.g. * 2 [4*2]
preprocess or not * 2 [1*2]
c.
array: e.g. bound check, slice, variable size
struct: e.g. C-like v. SML-like
union: discriminated or not
pointer: e.g. named vars, arith, garbage collection
e.g. * 4
pro & con * 4 [4*(2 or 3), max = 8]
implementation [2]