Uploaded by Unknown Anonymous

7630092

advertisement
Syntax-Directed Translation
Two approaches are distinguished
1.
A syntax-directed definition (SDD) associates a semantic rule with each grammar
production, the rule states how attributes are calculated
 conceptually, (and for SDTs too) each node may have multiple attributes
– perhaps a struct/record/dictionary is used to group many attributes
 attributes may be concerned e.g. with data type, numeric value, symbol
identification, code fragment, memory address, machine register choice
2.
A syntax-directed translation scheme (SDT) uses semantic actions embedded
anywhere in the bodies (right hand sides) of productions
 actions may perform arbitrary computations, such as appending output
 they are carried out in left-to-right order during parsing.
http://csiweb.ucd.ie/staff/acater/comp30330.html
Compiler Construction
1
Compare/Contrast SDD & SDT
• SDDs have a declarative flavour
 the grammar writer specifies what calculations have to be done
 the order of evaluation is unspecified
– it must be fixed by the parser (or parser generator)
 the grammar is more readable
• SDTs have a more procedural flavour
 the grammar writer specifies both
– the calculations that have to be done
– at what time they must be done
 the grammar is often more efficiently parsable
http://csiweb.ucd.ie/staff/acater/comp30330.html
Compiler Construction
2
Synthesized and Inherited Attributes
• For a grammar symbol X and its attribute a, use notation “X.a”
• Each attribute X.x at a parse tree node for symbol X may be
 synthesized, meaning that its value is obtained
– from attributes of child nodes in the parse tree,
– or from the lexical analyzer,
– or from other attributes of the same node in the parse tree
 inherited, meaning that its value is obtained
– from the parent node in the parse tree,
– or from sibling nodes in the parse tree
– v. useful when there is mismatch between grammar
for parsing, and “abstract syntax” for translation
http://csiweb.ucd.ie/staff/acater/comp30330.html
Compiler Construction
3
Restricted classes of grammars
• The most general – least restrictive – kind of syntax-directed translation involves
 building a parse tree explicitly,
 then “walking” it carrying out the actions in the productions.
• Two special cases allow actions to be carried out during parsing, with no explicit
parse tree having to be built
 L-attributed translations, grammars (‘L’ for left-to-right)
– inherited attributes are allowed provided they can be calculated in left-toright fashion
 S-attributed translations, grammars (‘S’ for Synthesized)
– only synthesized attributes are allowed
– easy for a bottom-up parser to handle
• The term “attribute grammar” means a grammar with attributes but its rules or
actions may not have side effects
http://csiweb.ucd.ie/staff/acater/comp30330.html
Compiler Construction
4
Syntax-Directed Definitions (SDDs)
• A SDD is a context-free grammar, plus attributes, and rules attached to the
productions of the grammar stating how attributes are computed
• Desk calculator’s Arithmetic Expression example:
– all attributes in this example are synthesized
– val and lexval attribute names are purposely different
– subscripts distinguish occurrences of the same grammar symbol
– practical rules may also have side-effects
(such as printing, manipulating a symbol table)
L
E
E
T
T
F
F
::= E \n
::= E1 + T
::= T
::= T1 * F
::= F
::= ( E )
::= digit
http://csiweb.ucd.ie/staff/acater/comp30330.html
L.val = E.val
E.val = E1.val + T.val
E.val = T.val
T.val = T1.val * F.val
T.val = F.val}
F.val = E.val
F.val = digit.lexval
Compiler Construction
5
SDD applied to “9+3*5\n”
L
E
E
T
T
F
F
::= E \n
::= E1 + T
::= T
::= T1 * F
::= F
::= ( E )
::= digit
L.val = E.val
E.val = E1.val + T.val
E.val = T.val
T.val = T1.val * F.val
T.val = F.val
F.val = E.val
F.val = digit.lexval
L.val=24
\n
E.val=24
+
E.val=9
T.val=15
T.val=3
T.val=9
*
F.val=5
This is an annotated parse tree
Note that no complete parse tree need
actually be constructed.
F.val=9
digit.lexval=9
http://csiweb.ucd.ie/staff/acater/comp30330.html
Compiler Construction
6
SDD applied to “9+3*5\n”
L
E
E
T
T
F
F
::= E \n
::= E1 + T
::= T
::= T1 * F
::= F
::= ( E )
::= digit
L.val = E.val
E.val = E1.val + T.val
E.val = T.val
T.val = T1.val * F.val
T.val = F.val
F.val = E.val
F.val = digit.lexval
L.val=24
\n
E.val=24
+
E.val=9
T.val=15
T.val=3
T.val=9
*
F.val=5
This is an annotated parse tree
Note that no complete parse tree need
actually be constructed.
F.val=9
digit.lexval=9
http://csiweb.ucd.ie/staff/acater/comp30330.html
Compiler Construction
7
Evaluation order
• Values of synthesized attributes may be calculated in any order
• For a S-attributed SDD, any bottom-up order suffices
• Where inherited attributes are allowed, order of evaluation is important
 it is possible to write rules for which no order of evaluation is possible
 circularity – NP-hard to detect if a set of rules could give rise to circularity
 In a L-attributed SDD, dependencies always go left-to-right, so no circularity is
possible
• A “Dependency Graph” depicts the flow of information between attributes in a
particular parse tree
• A “topological sort” of this graph produces a possible sequential order of evaluation
– if there is one, if the graph is not cyclic
http://csiweb.ucd.ie/staff/acater/comp30330.html
Compiler Construction
8
Usefulness of inherited attributes
• There can be tension between the design of a grammar for parsing purposes, and its
use in syntax-directed translation
 elimination of left recursion, to allow top-down parsing
 covering syntactic sugar constructs – mismatch of surface & abstract syntax
The C syntax int[2][3]
reads as
“an array of two arrays of three integers”
array
array
2
3
int
http://csiweb.ucd.ie/staff/acater/comp30330.html
T ::= B C
B := int
B := float
C := [ num ] C1
C := e
T.t=C.t; C.b=B.t
B.t=‘integer’
B.t=‘float’
C.t=array(num.val, C1.t); C1b=C.b)
C.t=C.b
Compiler Construction
9
Utilising SDDs
• SDDs can strike a balance between
 side-effect-free “attribute grammars” where any order of evaluation of rule
elements is permitted consistent with dependency graph
 translation schemes whose actions may contain arbitrary side-effects but must
be evaluated in strict left-to-right order
• This balance may be achieved in either of two ways
 permit only incidental side-effects which do not have any impact upon the
ordering of evaluation of rule elements
 somehow constrain the order of evaluation, effectively adding edges to the
dependency graph, so that significant side-effects may be allowed
– eg desk calculator: printing info; compiler: add type info to symbol table
• It is common to use SDD to produce an actual parse tree, which may be used as an
intermediate representation for a tree-walking translator
http://csiweb.ucd.ie/staff/acater/comp30330.html
Compiler Construction
10
Building a parse tree using a SDD
E := E1 + T
E := E1 – T
E := T
T := ( E )
T := id
T := num
E.node= new Node(‘+’, E1.node, T.node)
E.node= new Node(‘-’, E1.node, T.node)
E.node= T.node
T.node= E.node
T.node= new Leaf(‘ident’, id.entrynumber)
T.node= new Leaf(‘number’, num.lexval)
fred – george * 13
=>
ident
1
*
ident
2
http://csiweb.ucd.ie/staff/acater/comp30330.html
number
13
Compiler Construction
11
Download