decorated attribute grammars (cc 2009)

29
Decorated Attribute Grammars Attribute Evaluation Meets Strategic Programming CC 2009, York, UK Lennart Kats, TU Delft (me) Tony Sloane, Macquarie Eelco Visser, TU Delft Software Engineering Research Group March 19, 2009

Upload: lennartkats

Post on 17-May-2015

661 views

Category:

Technology


2 download

DESCRIPTION

Attribute grammars are a powerful specification formalism for tree-based computation, particularly for software language processing. Various extensions have been proposed to abstract over common patterns in attribute grammar specifications. These include various forms of copy rules to support non-local dependencies, collection attributes, and expressing dependencies that are evaluated to a fixed point. Rather than implementing extensions natively in an attribute evaluator, we propose attribute decorators that describe an abstract evaluation mechanism for attributes, making it possible to provide such extensions as part of a library of decorators. Inspired by strategic programming, decorators are specified using generic traversal operators. To demonstrate their effectiveness, we describe how to employ decorators in name, type, and flow analysis.

TRANSCRIPT

Page 1: Decorated Attribute Grammars (CC 2009)

DecoratedAttribute GrammarsAttribute Evaluation Meets Strategic Programming

CC 2009, York, UK

Lennart Kats, TU Delft (me)Tony Sloane, MacquarieEelco Visser, TU Delft

Software Engineering Research Group

March 19, 2009

Page 2: Decorated Attribute Grammars (CC 2009)

2

Context

• Domain-specific languages• example: WebDSL• language composition and extension

• SDF/SGLR + Stratego/XT• abstract syntax trees• traversal, rewrite rules

Page 3: Decorated Attribute Grammars (CC 2009)

3

Trees and Attribute Grammars

• Attributes • Declarative, compositional equations• Express dependencies between nodes

• Attribute evaluator• Determines evaluation order

Page 4: Decorated Attribute Grammars (CC 2009)

4

Basic Example: Global Minimum

def Root(t): id.min := t.min t.gmin := t.min

def Fork(t1, t2): id.min := <min> (t1.min,t2.min) t1.gmin := id.gmin t2.gmin := id.gmin

def Leaf(v): id.min := v

• Synthesized: flows up

Page 5: Decorated Attribute Grammars (CC 2009)

5

Basic Example: Global Minimum

def Root(t): id.min := t.min t.gmin := t.min

def Fork(t1, t2): id.min := <min> (t1.min,t2.min) t1.gmin := id.gmin t2.gmin := id.gmin

def Leaf(v): id.min := v

• Synthesized: flows up• Inherited: flows down

Page 6: Decorated Attribute Grammars (CC 2009)

6

def Root(t): id.min := t.min t.gmin := t.min

def Fork(t1, t2): id.min := <min> (t1.min,t2.min) t1.gmin := id.gmin t2.gmin := id.gmin

def Leaf(v): id.min := v

Basic Example: Global Minimum

min=31

min=22

min=22

min=6

min=6

min=

min=

min=

min=6min=

Page 7: Decorated Attribute Grammars (CC 2009)

7

def Root(t): id.min := t.min t.gmin := t.min

def Fork(t1, t2): id.min := <min> (t1.min,t2.min) t1.gmin := id.gmin t2.gmin := id.gmin

def Leaf(v): id.min := v

Basic Example: Global Minimum

min=31

min=22

min=22

min=6

min=6

gmin=6

min=

min=

min=

gmin=

min=6min=6

min=6min=

Page 8: Decorated Attribute Grammars (CC 2009)

8

def Root(t): id.min := t.min t.gmin := t.min

def Fork(t1, t2): id.min := <min> (t1.min,t2.min) t1.gmin := id.gmin t2.gmin := id.gmin

def Leaf(v): id.min := v

Global Minimum: Identifying Copy Rules

min=31

min=22

min=22

min=6

min=6

gmin=6

min=

min=

min=

gmin=

min=6min=6

min=6min=

Page 9: Decorated Attribute Grammars (CC 2009)

9

Introducing Decorators

• Abstract over traversal or evaluation pattern• Express intent

• min: “upward flow”• gmin: “downward flow”

• May introduce default behavior• May modify existing behavior

Page 10: Decorated Attribute Grammars (CC 2009)

10

Example: up/down copying decorators

def Root(t): id.min := t.min t.gmin := t.min

def Fork(t1, t2): id.min := <min> (t1.min,t2.min) t1.gmin := id.gmin t2.gmin := id.gmin

def Leaf(v): id.min := v

Page 11: Decorated Attribute Grammars (CC 2009)

11

Example: up/down copying decorators

def Root(t): t.gmin := t.min

def Fork(t1, t2): id.min := <min> (t1.min,t2.min)

def Leaf(v): id.min := v

def down gmindef up min

Page 12: Decorated Attribute Grammars (CC 2009)

12

Introducing Decorators (ct'd)

Based on strategic programming• Programmable: decorators available as a library• Generic: independent of a particular tree• Reflective: may use properties of attributes

decorator down(a) = if a.defined then a else id.parent.down(a) end

decorator up(a) = if a.defined then a else id.child(id.up(a)) end

Page 13: Decorated Attribute Grammars (CC 2009)

13

Basic Building Blocks of Decorators

decorator down(a) = if a.defined then a else id.parent.down(a) end

Arguments• attribute a• functions, terms

Reflective attributes• a.defined• a.attribute-name• a.signature

Tree access attributes• id.parent• id.child(c), id.prev-sibling, ...

Recursion

Page 14: Decorated Attribute Grammars (CC 2009)

14

Abstraction Using Decorators (1)

Boilerplate code elimination:• avoid repetitive code (e.g., “copy rules”)• reduce accidental complexity• implement some of the boilerplate-coping

mechanisms of other AG systems

Page 15: Decorated Attribute Grammars (CC 2009)

15

Abstraction Using Decorators (2)

Control over evaluation:• tracing• memoization• assertions

Control over evaluation:• tracing• memoization• assertions

def trace gmin

decorator trace(a) = t := id; a; log(|[a.attribute-name, " at ", t.path, ": ", id])

Page 16: Decorated Attribute Grammars (CC 2009)

16

Abstraction Using Decorators (2)

Control over evaluation:• tracing• memoization• assertions

Control over evaluation:• tracing• memoization• assertions

decorator default-caching(a) = if id.get-cached(a) then id.get-cached(a) elseif a then ... a ; ...set-cached... end

Page 17: Decorated Attribute Grammars (CC 2009)

17

Abstraction Using Decorators (2)

Control over evaluation:• tracing• memoization• assertions

Control over evaluation:• tracing• memoization• assertions

Nothing to see here

def assert-after(<leq> (id.gmin, id.min)) gmin

decorator assert-after(a, c) = t := id; a; id.set-cached-for(a|t); if not(<c> t) then fatal-err(|["Assertion failed for ", a.attribute-name, " at ", t.path]) end

Page 18: Decorated Attribute Grammars (CC 2009)

18

Abstraction Using Decorators (3)

Help in typical compiler front-end tasks:• name analysis• type analysis• control- and data-flow analysis

encapsulation of recurring attribution patterns

Page 19: Decorated Attribute Grammars (CC 2009)

19

Type Analysis with Aster

def type: Int(i) → IntType

|[ var x : t ; ]| → t

Var(x) → id.lookup-local(|x).type

|[ f (arg*) ]| → id.lookup-function(|f, arg*).type

...

Concrete syntax [Visser 2002]

VarDecl(x, t)

Reference attributes [Hedin 2000]

look up declaration nodes

var x : Int;

Page 20: Decorated Attribute Grammars (CC 2009)

20

Type Analysis with Aster:Using Decorators (1)

def lookup-ordered(id.is-scope) lookup-local(|x): |[ var x : t ; ]| → id |[ x : t ]| → id

Lookup decorators require:• Lookup type (ordered, unordered, global, ...)• Tree nodes to fetch• Scoping definition

Page 21: Decorated Attribute Grammars (CC 2009)

21

Type Analysis with Aster:Using Decorators (2)

def is-scope: |[ { s* } ]| → id |[ function x(param*) : t { stm* } ]| → id ...

Lookup decorators require:• Lookup type (ordered, unordered, global, ...)• Tree nodes to fetch• Scoping definition

Page 22: Decorated Attribute Grammars (CC 2009)

22

Type Analysis with Aster:Using Decorators (3)

def lookup-unordered(id.is-scope) lookup-function(|x, arg*): |[ function x (param*) : t { stm* } ]| → id where argtype* := arg*.map(id.type); paramtype* := param*.map(id.type); paramtype*.eq(|argtype*)

Page 23: Decorated Attribute Grammars (CC 2009)

23

Type Analysis with Aster:Decorator Definitions

decorator down lookup-ordered(a, is-s) = if a then a else id.prev-sibling(id.lookup-inside(a, is-s)) end

decorator lookup-inside(a, is-scope) = if a then a else if not(is-scope) then // enter preceding subtrees id.child(id.lookup-inside(a, is-scope)) end

function x() : Int { var j : Int; ...}

function y() : Int { if (true) { var i : Int; } return j;}

Decorator stacking

Page 24: Decorated Attribute Grammars (CC 2009)

24

Error Reporting Using Decorators

def errors: |[ while (e) s ]| → "Condition must be of type Boolean" where not(e.type BoolType)

...

def collect-all add-error-context errors

decorator add-error-context(a) = <conc-strings > (a," at ", id.pp, " in ", id.file, ":", id.linenumber)

module Reporting

module Constraints

Decorator stacking

Page 25: Decorated Attribute Grammars (CC 2009)

25

Control-flow Analysis (1)

def default(id.default-succ) succ: |[ if (e) s1 else s2 ]| → [s1, s2] |[ return e ; ]| → [ ] |[ { s1; s* } ]| → [s1] ...

decorator default(a, default) = if a.defined then a else default end

Page 26: Decorated Attribute Grammars (CC 2009)

26

Control-flow Analysis (2)

def down default-succ: Program(_) → [] [s1, s2 | _ ].s1 → [s2] ...

Page 27: Decorated Attribute Grammars (CC 2009)

27

“But Wait, There's More!”

• Data-flow analysis• reaching definitions, liveness, ...• data-flow equations as attribute equations• circular (fixed point) attribute evaluation

• Deriving the reverse control flow

// Statement copies itself to successorsdef contributes-to(id.succ) pred: stm → id

Page 28: Decorated Attribute Grammars (CC 2009)

28

Go Figures!

• Syntax: 3 modules 341 lines• Compiler: 25 modules 2831 lines• Library: 25 modules 1845 lines• Tests: 33 modules 1531 lines

Total: 86 modules 6548 lines

Page 29: Decorated Attribute Grammars (CC 2009)

• Language growth in the hands of the users• decorators implement automatic copy rules, self rules,

collection attributes, circular attributes, ...

• Combine generic behavior with (simple) reflection• Future:

• Library, language extension• IDE integration

Decorated Attribute Grammars. Attribute Evaluation Meets StrategicProgramming. Lennart C. L. Kats, Anthony M. Sloane, and Eelco Visser.18th International Conference on Compiler Construction (CC 2009).http://www.strategoxt.org/Stratego/Aster

Concluding Remarks