Lecture 4
Lecture 4
SDD and SDT scheme Example: SDD vs SDT scheme – infix to postfix trans
* *
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 3 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 4 / 29
Syntax directed translation - overview Syntax directed definition
* *
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 5 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 6 / 29
Attribute is any quantity associated with a programming construct. Idea: attribute the syntax tree
Example: data types, line numbers, instruction details
can add attributes (fields) to each node
Two kinds of attributes: for a non-terminal A, at a parse tree node N specify equations to define values (unique)
A synthesized attribute: defined by a semantic rule associated can use attributes from parent and children
with the production at N.
Example: to ensure that constants are immutable:
defined only in terms of attribute values at the children of N and at add type and class attributes to expression nodes
N itself. rules for production on := that
An inherited attribute: defined by a semantic rule associated with 1 check that LHS.class is variable
the parent production of N. 2 check that LHS.type and RHS.type are consistent or conform
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 7 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 8 / 29
Attribute grammars Example
To formalize such systems Knuth introduced attribute grammars: P RODUCTION S EMANTIC RULES
grammar-based specification of tree attributes D → TL L.in := T.type
value assignments associated with productions T → int T.type := integer
each attribute uniquely, locally defined T → real T.type := real
label identical terms uniquely
L → L1 , id L1 .in := L.in
Can specify context-sensitive actions with attribute grammars addtype(id.entry, L.in)
L → id addtype(id.entry, L.in)
* *
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 9 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 10 / 29
if SIGN.neg
NUM.val := -LIST.val
pos: 0
else SIGN neg: T LIST
val: 5
NUM.val := LIST.val
SIGN → + SIGN.neg := false val and neg are
SIGN → - SIGN.neg := true LIST
pos: 1
BIT
pos: 0
synthesized attributes
LIST → BIT BIT.pos := LIST.pos
val: 4 val: 1
pos is an inherited
LIST.val := BIT.val attribute
pos: 2 pos: 1
LIST → LIST1 BIT LIST1 .pos := LIST.pos + 1 LIST BIT
val: 4 val: 0
BIT.pos := LIST.pos
LIST.val := LIST1 .val + BIT.val pos: 2
BIT →0 BIT.val := 0 BIT
val: 4
- 1 0 1
* *
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 11 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 12 / 29
Dependences between attributes The attribute dependency graph
* *
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 13 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 14 / 29
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 15 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 16 / 29
Evaluation strategies Avoiding cycles
* *
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 17 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 18 / 29
Top-down (LL) on-the-fly one-pass evaluation Bottom-up (LR) on-the-fly one-pass evaluation
L-attributed grammar:
Informally – dependency-graph edges may go from left to right, not
other way around.
given production A → X1 X2 · · · Xn
inherited attributes of Xj depend only on: S-attributed grammar:
1 inherited attributes of A L-attributed
2 arbitrary attributes of X1 , X2 , · · · Xj−1
only synthesized attributes for non-terminals
actions at far right of a RHS
synthesized attributes of A depend only on its inherited attributes
and arbitrary RHS attributes Can evaluate S-attributed in one bottom-up (LR) pass.
synthesized attributes of an action depends only on its inherited
attributes
i.e., evaluation order:
Inh(A), Inh(X1 ), Syn(X1 ), . . . , Inh(Xn ), Syn(Xn ), Syn(A)
This is precisely the order of evaluation for an LL parser
* *
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 19 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 20 / 29
Evaluate S-attributed grammar in bottom-up parsing Inherited Vs Synthesised attributes
Evaluate it in any bottum-up order of the nodes in the parse tree. Synthesized attributes are limited
(One option:) Apply postorder to the root of the parse tree:
void postorder (N) { Inherited attributes (are good): derive values from constants, parents,
for (each child C of N) siblings
do used to express context (context-sensitive checking)
postorder(C); inherited attributes are more “natural”
done
We want to use both kinds of attributes
evaluate the attributes associated with N; can always rewrite L-attributed LL grammars (using markers and
} copying) to avoid inherited attribute problems with LR
post order traversal of the parse tree corresponds to the exact Self reading (if interested) – Dragon book Section 5.5.4.
order in which the bottom-up parsing builds the parse tree.
Thus, we can evaluate S-attributed in one bottom-up (LR) pass.
* *
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 21 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 22 / 29
push EOF
push Start Symbol
token ← next token()
repeat
How does an LL parser handle (aka - execute) actions? pop X
if X is a terminal or EOF then
Expand productions before scanning RHS symbols, so:
if X = token then
push actions onto parse stack like other grammar symbols token ← next token()
pop and perform action when it comes to top of parse stack else error()
else if X is an action
perform X
else /* X is a non-terminal */
if M[X,token] = X → Y1 Y2 · · · Yk then
push Yk , Yk−1 , · · · , Y1
else error()
until X = EOF
* *
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 23 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 24 / 29
LR parsers and action symbols Action-controlled semantic stacks
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 25 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 26 / 29
* *
V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 27 / 29 V.Krishna Nandivada (IIT Madras) CS3300 - Aug 2019 28 / 29
Attribute Grammars
Advantages
clean formalism
automatic generation of evaluator
high-level specification
Disadvantages
evaluation strategy determines efficiency
increased space requirements
parse tree evaluators need dependency graph
results distributed over tree
circularity testing
Intel’s 80286 Pascal compiler used an attribute grammar evaluator to
perform context-sensitive analysis.
Historically, attribute grammar evaluators have been deemed too large
and expensive for commercial-quality compilers. *