1 / 24

Attribute Grammars

Attribute Grammars. Prabhaker Mateti ACK: Assembled from many sources. About Attribute Grammars. Attribute grammars (AGs) add semantic info on parse tree nodes Used for semantic checking and other compile-time analyses, e.g., type checking in a compiler

cian
Télécharger la présentation

Attribute Grammars

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Attribute Grammars PrabhakerMateti ACK: Assembled from many sources

  2. About Attribute Grammars • Attribute grammars (AGs) add semantic info on parse tree nodes • Used for semantic checking and other compile-time analyses, e.g., type checking in a compiler • Used for translation, e.g., parse tree to assembly code • A traversal of the parse tree and the computation of information.

  3. Attribute Grammars: Definition • An attribute grammar is a context-free grammar G = (S, N, T, P) with the following additions. • For each terminal and non-terminal X, disjoint sets S(X) synthesized attributes and I(X) inherited attributes: • A(X) = S(X) ∪ I(X) • X0 ::= X1 ... Xn • S(X0) = f(I(X0), A(X1), ... , A(Xn)) • I(Xj) = g(A(X0), ... , A(Xn)) • depends on the attribute value at parent and those of siblings. • Each rule has a set of predicates/ conditions to check for attribute consistency: P( A(X0), A(X1), A(X2), …, A(Xn) )

  4. Example-1: Binary Numbers • N ::= 0 • N ::= 1 • N ::= N 0 • N ::= N 1 • CFGs do not provide semantics. • CGGs provide only syntax, that too without context-sensitive details • N.val:= 0 • N.val:= 1 • N.val:= 2*N.rhs.val • N.val:= 2*N.rhs.val+1 • N.val is an attribute associated with node N of the parse tree • N.rhs Node corresponding to the rhs • Synthesized Attributes

  5. Example-2: Type Checking • E ::= n • E ::= x • E ::= E1 + E2 • E ::= E1 * E2 • Semantics we wish to add • n is an int, x is a real. • op + returns an int if both the operands are int, otherwise a real. • E.type:= int • E.type := real • if E1.type = E2.type then E.type := E1.type else E.type:= realfi • Item 3 derived version of the semantics • Static semantics

  6. Example-3: Assignment Arithmetic • stm ::= var := exp | stm; stm • exp ::= var + var | var • var ::= A | B | C • synthesized actual-type for var and exp • inherited expected-type for exp • lookup (var.string) a helper function; gives the actual type of A, B, C • exp ::= var1 + var2 • subscripts added • exp.actual-type:= var1.actual-type • exp.expected-type • from parent in the parse tree • Predicates: • var1.actual-type== var2.actual-type • exp.expected-type== exp.actual-type • var ::= A | B | C • var.actual-type:= lookup (var.string)

  7. Inherited Attributes Example • Declaration and Use{ int i, j, k; i := i + j + j; } • assign ::= var := exp • env: environment • var.env := assign.env • exp.env := assign.env

  8. Information Flow inherited computed available synthesized ... ...

  9. Attribute Value Computation • If all attributes were inherited, the tree could be decorated in top-down order. Inherited Attributes pass information • down the parse tree, or • from left siblings to the right siblings • If all attributes were synthesized, the tree could be decorated in bottom-up order. Synthesized Attributes pass information up the parse tree • In many cases, both kinds of attributes are used, and it is some combination of top-down and bottom-up that must be used. • Initially, there are intrinsic attributes on the leaves • If a condition in a tree evaluates to false, an error occurs.

  10. Prolog for Example-2 • type(n, int). • type(x, real). • type(+(E, F), T) :- type(E, T), type(F, T). • type(+(E, F), real) :- type(E, T1), type(F, T2), T1 \= T2. • Type Checking ?- type(+(n, x), real). • Type Inference ?- type(+(n, x), T). • (Definite Clause Grammars)

  11. F ::= . N N ::= 0 N ::= 1 N ::= 0 N N ::= 1 N Synthesized: val, value Inherited: pow, the number of bits between left of a non-terminal and the binary point Nr: N-right, Nl: N-left 1: F.val:= N.val; N.pow:= 1 2: N.val := 0 3: N.val := (1/2^N.pow) 4: Nl.val := Nr.val 4: Nr.pow := 1 + Nl.pow 5: Nl.Val := Nr.val+(1/2^N.pow) 5: Nr.pow := 1 + Nl.pow Example-4: Fractions in Binary

  12. Binary Fractions, same grammar as before: F ::= . N N ::= 0 N ::= 1 N ::= 0 N N ::= 1 N Alternate computation based on synthesized attribute val only 1: F.val := N.val / 2 2: N.val := 0 3: N.val := 1 4: N.val := N.val / 2 5: N.val := N.val / 2 + 1 Ex4: Synthesized Attributes Only

  13. Example-5: Distinct Identifiers • Compute the number of distinct identifiers in a straight-line program. • Semantics specified in terms of sets of identifiers. • Attributes • var id • exp  ids • stm ids  num

  14. Example-5: Distinct Identifiers • exp::= var • exp.ids = { var.id } • exp::= exp1 + exp2 • exp.ids = exp1.ids U exp2.ids • stm::= var:= exp • stm.ids = { var.id } U exp.ids • stm.num = | stm.ids | • stm::= stm1;stm2 • stm.ids = stm1.ids U stm2.ids • stm.num = | stm.ids |

  15. Example-5: Using Lists • Attributes • envi: list of vars in preceding context • envo: list of vars for following context • dnum: number of new variables • exp ::= var exp.envo = if member(var.id, exp.envi) then exp.envi else cons(var.id, exp.envi) fi

  16. Example-5: Using Lists • exp ::= exp1 + exp2 • envienvienvi • envoenvoenvo • dnumdnumdnum • exp1.envi := exp.envi • exp2.envi := exp1.envo • exp.envo := exp2.envo • exp.dnum := length(exp.envo) • exp.envo = append-sans-duplicates(exp1.envo, exp2.envo )

  17. Complete Evaluation Rules • Synthesized attribute associated with N: • Each alternative in “N ::= …” should contain a rule for evaluating the Synthesized attribute. • Inherited attribute associated with N: • For every occurrence of N in “… ::= … N …” there must be a rule for evaluating the Inherited attribute. • Whenever you create an attribute grammar (in home work/ exams), make sure it satisfies these requirements.

  18. One Pass Attribute Computation • To enable one-pass top-down left-to-right computation of the attributes: • each inherited attribute of the right-hand side symbol can depend on all the attributes associated with preceding right-hand side symbols and the inherited attribute of the left-hand side non-terminal. • Similarly, the synthesized attribute of the left-hand side non-terminal can depend on all the attributes associated with all the right-hand side symbols and the inherited attribute of the left-hand side non-terminal.

  19. More than Context-Free Power • LABC = { a^nb^nc^n | n > 0 } • Unlike LAB = { a^nb^n | n > 0 }, here we need explicit counting of a’s, b’s and c’s • LWCW = { wcw | w ∈{a, b}* } • The “flavor” of checking whether identifiers are declared before their uses • LABC, LWCW cannot be defined with a context-free grammar • Syntax analysis (i.e., parser based on CFGs) cannot handle semantic properties

  20. LABC = { a^nb^nc^n | n > 0 } • ls ::= as bscs • ExpNb(bs) := Na(as); ExpNc(cs) := Na(as) • as ::= a | a as1 • Na(as) := 1; Na(as) := Na(as1) + 1 • bs ::= b | b bs1 • cond(ExpNb(bs) = 1); ExpNb(bs1) := ExpNb(bs) - 1 • cs ::= c | c cs1 • Cond(ExpNc(cs) = 1); ExpNc(cs1) := ExpNc(cs) – 1 • Na: synthesized by as • ExpNb: inherited from bs • ExpNc: inherited from cs

  21. Uses of Attribute Grammars • Compiler Generation • Top-down Parsers (LL(1)) • FIRST sets, FOLLOW sets, etc • Code Generation Computations • Type, Storage determination, etc. • Databases • Optimizing Bottom-up Query Evaluation (Magic Sets) • Programming and Definitions

  22. Uses of Inherited Attributes • ex: 5.0 + 2 • need to generate code to coerce int 2 to real 2.0 • Determination of un-initialized variables • Determination of reachable non-terminals • Evaluation of an expression containing variables

  23. Use of Attribute Grammars • Useful for expressing arbitrary cycle-free computational walks over CFG derivation trees • Synthesized and inherited attributes • Conditions to reject invalid parse trees • Evaluation order depends on attribute dependencies • Realistic applications: • type checking • code generation • “Global” data structures must be passed around as attributes • Any container data structure (sets, etc.) can be used • The evaluation rules can call auxiliary/helper functions but the functions cannot have side effects

  24. References • T. K. Prasad, Attribute Grammars and their Applications, In: Encyclopedia of Information Science and Technology, pp. 268-273, 2008. Attribute-Grammars.pdf • PL TextBookSections • Pagan: 2.1, 2.2, 2.3, 3.2 • Stansifer: 2.2, 2.3 • Slonneger and Kurtz: 3.1, 3.2

More Related