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]