280 likes | 1.06k Views
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
E N D
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
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
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
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-to-right 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
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 \n E ::= E1 + T E ::= T T ::= T1 * F T ::= F F ::= ( E ) F ::= 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 http://csiweb.ucd.ie/staff/acater/comp30330.html Compiler Construction
SDD applied to “9+3*5\n” L ::= E \n E ::= E1 + T E ::= T T ::= T1 * F T ::= F F ::= ( E ) F ::= 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 * F.val=5 T.val=9 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
SDD applied to “9+3*5\n” L ::= E \n E ::= E1 + T E ::= T T ::= T1 * F T ::= F F ::= ( E ) F ::= 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 * F.val=5 T.val=9 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
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
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” 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 array array 2 3 int http://csiweb.ucd.ie/staff/acater/comp30330.html Compiler Construction
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
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 * number 13 ident 2 http://csiweb.ucd.ie/staff/acater/comp30330.html Compiler Construction