From Object Algebras to Attribute Grammars Tillmann Rendel Jonathan - - PowerPoint PPT Presentation

from object algebras to attribute grammars
SMART_READER_LITE
LIVE PREVIEW

From Object Algebras to Attribute Grammars Tillmann Rendel Jonathan - - PowerPoint PPT Presentation

From Object Algebras to Attribute Grammars Tillmann Rendel Jonathan Brachthuser Klaus Ostermann University of Marburg University of Tbingen http://www.informatik.uni-marburg.de/~rendel/oa2ag Presentation by Tillmann Rendel at the


slide-1
SLIDE 1

From Object Algebras to Attribute Grammars

Tillmann Rendel · Jonathan Brachthäuser · Klaus Ostermann University of Marburg · University of Tübingen http://www.informatik.uni-marburg.de/~rendel/oa2ag

Presentation by Tillmann Rendel at the International Conference

  • n Object-Oriented Programming, Systems, Languages, and Applications

Portland, Oregon, October 23, 2014

slide-2
SLIDE 2

Tree Traversals

1/15

slide-3
SLIDE 3

Tree Traversals

1/15

slide-4
SLIDE 4

Tree Traversals

How to structure a program that contains multiple traversals

  • f complex trees?

1/15

slide-5
SLIDE 5

Visitor Pattern

in object-oriented programming

Folds & Traversal Schemes

in functional programming

Church Encoding

in theoretical work

Attribute Grammars

for compiler construction

2/15

slide-6
SLIDE 6

Visitor Pattern

in object-oriented programming

Folds & Traversal Schemes

in functional programming

Church Encoding

in theoretical work

Attribute Grammars

for compiler construction

Hinze (2006) Chirica & Martin (1979) Johnsson (1987) Gibbons (2006) Buchlovsky & Thielecke (2006) Oliveira et al. (2008) Oliveira et al. (2013) Middelkoop et al. (2011)

2/15

slide-7
SLIDE 7

Visitor Pattern

in object-oriented programming

Folds & Traversal Schemes

in functional programming

Church Encoding

in theoretical work

Attribute Grammars

for compiler construction

Hinze (2006) Chirica & Martin (1979) Johnsson (1987) Gibbons (2006) Buchlovsky & Thielecke (2006) Oliveira et al. (2008) Oliveira et al. (2013)

this paper

Middelkoop et al. (2011)

2/15

slide-8
SLIDE 8

Visitor Pattern

in object-oriented programming

Folds & Traversal Schemes

in functional programming

Church Encoding

in theoretical work

Object Algebras

in Scala

Attribute Grammars

for compiler construction

Hinze (2006) Chirica & Martin (1979) Johnsson (1987) Gibbons (2006) Buchlovsky & Thielecke (2006) Oliveira et al. (2008) Oliveira et al. (2013)

this paper

Middelkoop et al. (2011)

2/15

slide-9
SLIDE 9

Bottom-Up Data Flow

3/15

slide-10
SLIDE 10

Synthesized Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Lit: Int ⇒ E def Add: (E, E) ⇒ E }

Equations

e0.value = n e1 .value = e2.value + e3.value

Algebra

val Alg = new Sig[Int] { def Lit = n ⇒ n def Add = (e2, e3) ⇒ e2 + e3 }

4/15

slide-11
SLIDE 11

Synthesized Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Lit: Int ⇒ E def Add: (E, E) ⇒ E }

Equations

e0.value = n e1 .value = e2.value + e3.value

Algebra

val Alg = new Sig[Int] { def Lit = n ⇒ n def Add = (e2, e3) ⇒ e2 + e3 }

4/15

slide-12
SLIDE 12

Synthesized Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Lit: Int ⇒ E def Add: (E, E) ⇒ E }

Equations

e0.value = n e1 .value = e2.value + e3.value

Algebra

val Alg = new Sig[Int] { def Lit = n ⇒ n def Add = (e2, e3) ⇒ e2 + e3 }

4/15

slide-13
SLIDE 13

Synthesized Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Lit: Int ⇒ E def Add: (E, E) ⇒ E }

Equations

e0.value = n e1 .value = e2.value + e3.value

Algebra

val Alg = new Sig[Int] { def Lit = n ⇒ n def Add = (e2, e3) ⇒ e2 + e3 }

4/15

slide-14
SLIDE 14

Synthesized Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Lit: Int ⇒ E def Add: (E, E) ⇒ E }

Equations

e0.value = n e1 .value = e2.value + e3.value

Algebra

val Alg = new Sig[Int] { def Lit = n ⇒ n def Add = (e2, e3) ⇒ e2 + e3 }

4/15

slide-15
SLIDE 15

Synthesized Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Lit: Int ⇒ E def Add: (E, E) ⇒ E }

Equations

e0.value = n e1 .value = e2.value + e3.value

Algebra

val Alg = new Sig[Int] { def Lit = n ⇒ n def Add = (e2, e3) ⇒ e2 + e3 }

4/15

slide-16
SLIDE 16

Synthesized Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Lit: Int ⇒ E def Add: (E, E) ⇒ E }

Equations

e0.value = n e1 .value = e2.value + e3.value

Algebra

val Alg = new Sig[Int] { def Lit = n ⇒ n def Add = (e2, e3) ⇒ e2 + e3 }

4/15

slide-17
SLIDE 17

Synthesized Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Lit: Int ⇒ E def Add: (E, E) ⇒ E }

Equations

e0.value = n e1 .value = e2.value + e3.value

Algebra

val Alg = new Sig[Int] { def Lit = n ⇒ n def Add = (e2, e3) ⇒ e2 + e3 }

4/15

slide-18
SLIDE 18

Synthesized Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Lit: Int ⇒ E def Add: (E, E) ⇒ E }

Equations

e0.value = n e1 .value = e2.value + e3.value

Algebra

val Alg = new Sig[Int] { def Lit = n ⇒ n def Add = (e2, e3) ⇒ e2 + e3 }

4/15

slide-19
SLIDE 19

Synthesized Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Lit: Int ⇒ E def Add: (E, E) ⇒ E }

Equations

e0.value = n e1 .value = e2.value + e3.value

Algebra

val Alg = new Sig[Int] { def Lit = n ⇒ n def Add = (e2, e3) ⇒ e2 + e3 }

4/15

slide-20
SLIDE 20

Top-Down Data Flow

5/15

slide-21
SLIDE 21

Inherited Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Add1: E ⇒ E def Add2: (E, E) ⇒ E }

Equations

e2 .left = true

e3.left = false

Algebra

val Alg = new Sig[Bool] { def Add1 = e ⇒ true def Add2 = (e1, e2) ⇒ false }

6/15

slide-22
SLIDE 22

Inherited Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Add1: E ⇒ E def Add2: (E, E) ⇒ E }

Equations

e2 .left = true

e3.left = false

Algebra

val Alg = new Sig[Bool] { def Add1 = e ⇒ true def Add2 = (e1, e2) ⇒ false }

6/15

slide-23
SLIDE 23

Inherited Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Add1: E ⇒ E def Add2: (E, E) ⇒ E }

Equations

e2 .left = true

e3.left = false

Algebra

val Alg = new Sig[Bool] { def Add1 = e ⇒ true def Add2 = (e1, e2) ⇒ false }

6/15

slide-24
SLIDE 24

Inherited Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Add1: E ⇒ E def Add2: (E, E) ⇒ E }

Equations

e2 .left = true

e3.left = false

Algebra

val Alg = new Sig[Bool] { def Add1 = e ⇒ true def Add2 = (e1, e2) ⇒ false }

6/15

slide-25
SLIDE 25

Inherited Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Add1: E ⇒ E def Add2: (E, E) ⇒ E }

Equations

e2 .left = true

e3.left = false

Algebra

val Alg = new Sig[Bool] { def Add1 = e ⇒ true def Add2 = (e1, e2) ⇒ false }

6/15

slide-26
SLIDE 26

Inherited Attributes

Grammar

e0 → n { Lit } e1 → e2 "+" e3 { Add }

Signature

trait Sig[E] { def Add1: E ⇒ E def Add2: (E, E) ⇒ E }

Equations

e2 .left = true

e3.left = false

Algebra

val Alg = new Sig[Bool] { def Add1 = e ⇒ true def Add2 = (e1, e2) ⇒ false }

6/15

slide-27
SLIDE 27

Composition

7/15

slide-28
SLIDE 28

Composition

compose 7/15

slide-29
SLIDE 29

Composition

compose 7/15

slide-30
SLIDE 30

Composition

assemble 7/15

slide-31
SLIDE 31

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

slide-32
SLIDE 32

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

slide-33
SLIDE 33

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

slide-34
SLIDE 34

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

slide-35
SLIDE 35

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

slide-36
SLIDE 36

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

slide-37
SLIDE 37

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

slide-38
SLIDE 38

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

current node

slide-39
SLIDE 39

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

current node children

slide-40
SLIDE 40

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

current node context from parent

slide-41
SLIDE 41

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

current node

slide-42
SLIDE 42

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

slide-43
SLIDE 43

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

slide-44
SLIDE 44

compose( , ) =

Extensible Records

trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[A, B]: (A, B) ⇒ A with B

Dependency Tracking

trait Sig[-E, -C, +O] { def Lit: Int ⇒ C ⇒ O def Add: (E, E) ⇒ C ⇒ O }

8/15

slide-45
SLIDE 45

compose( , ) =

Composing two algebras

def compose [E1, C1, O1, E2, C2 >: C1 with O1, O2] (alg1: Sig[E1, C1, O1], alg2: Sig[E2, C2, O2]): Sig[E1 with E2, C1, O1 with O2]

9/15

slide-46
SLIDE 46

compose( , ) =

Composing two algebras

def compose [E1, C1, O1, E2, C2 >: C1 with O1, O2] (alg1: Sig[E1, C1, O1], alg2: Sig[E2, C2, O2]): Sig[E1 with E2, C1, O1 with O2]

9/15

slide-47
SLIDE 47

compose( , ) =

Composing two algebras

def compose [E1, C1, O1, E2, C2 >: C1 with O1, O2] (alg1: Sig[E1, C1, O1], alg2: Sig[E2, C2, O2]): Sig[E1 with E2, C1, O1 with O2]

9/15

slide-48
SLIDE 48

compose( , ) =

Composing two algebras

def compose [E1, C1, O1, E2, C2 >: C1 with O1, O2] (alg1: Sig[E1, C1, O1], alg2: Sig[E2, C2, O2]): Sig[E1 with E2, C1, O1 with O2]

9/15

slide-49
SLIDE 49

compose( , ) =

Composing two algebras

def compose [E1, C1, O1, E2, C2 >: C1 with O1, O2] (alg1: Sig[E1, C1, O1], alg2: Sig[E2, C2, O2]): Sig[E1 with E2, C1, O1 with O2]

9/15

slide-50
SLIDE 50

compose( , ) =

Composing two algebras

def compose [E1, C1, O1, E2, C2 >: C1 with O1, O2] (alg1: Sig[E1, C1, O1], alg2: Sig[E2, C2, O2]): Sig[E1 with E2, C1, O1 with O2]

9/15

slide-51
SLIDE 51

compose( , ) =

Composing two algebras

def compose [E1, C1, O1, E2, C2 >: C1 with O1, O2] (alg1: Sig[E1, C1, O1], alg2: Sig[E2, C2, O2]): Sig[E1 with E2, C1, O1 with O2]

9/15

slide-52
SLIDE 52

compose( , ) =

Composing two algebras

def compose [E1, C1, O1, E2, C2 >: C1 with O1, O2] (alg1: Sig[E1, C1, O1], alg2: Sig[E2, C2, O2]): Sig[E1 with E2, C1, O1 with O2]

9/15

slide-53
SLIDE 53

Assembling a one-pass traversal

def assemble [C, O] (alg1: Sig1[C with O, C, O], alg2: Sig2[C with O, C, C]): Sig[C ⇒ C with O]

assemble( , ) =

10/15

slide-54
SLIDE 54

Assembling a one-pass traversal

def assemble [C, O] (alg1: Sig1[C with O, C, O], alg2: Sig2[C with O, C, C]): Sig[C ⇒ C with O]

assemble( , ) =

10/15

slide-55
SLIDE 55

Assembling a one-pass traversal

def assemble [C, O] (alg1: Sig1[C with O, C, O], alg2: Sig2[C with O, C, C]): Sig[C ⇒ C with O]

assemble( , ) =

10/15

slide-56
SLIDE 56

Assembling a one-pass traversal

def assemble [C, O] (alg1: Sig1[C with O, C, O], alg2: Sig2[C with O, C, C]): Sig[C ⇒ C with O]

assemble( , ) =

10/15

slide-57
SLIDE 57

Assembling a one-pass traversal

def assemble [C, O] (alg1: Sig1[C with O, C, O], alg2: Sig2[C with O, C, C]): Sig[C ⇒ C with O]

assemble( , ) =

10/15

slide-58
SLIDE 58

Results

Object algebras correspond to synthesized attributes (bottom-up data-flow) We extend object algebras to support inherited attributes (top-down data flow) We assemble multiple algebras to support L-attributed grammars (arbitrary one-pass compiler) 11/15

slide-59
SLIDE 59

Results

Object algebras correspond to synthesized attributes (bottom-up data-flow) We extend object algebras to support inherited attributes (top-down data flow) We assemble multiple algebras to support L-attributed grammars (arbitrary one-pass compiler) 11/15

slide-60
SLIDE 60

Results

Object algebras correspond to synthesized attributes (bottom-up data-flow) We extend object algebras to support inherited attributes (top-down data flow) We assemble multiple algebras to support L-attributed grammars (arbitrary one-pass compiler) 11/15

slide-61
SLIDE 61

11/15

Results

Object algebras correspond to synthesized attributes (bottom-up data-flow) We extend object algebras to support inherited attributes (top-down data flow) We assemble multiple algebras to support L-attributed grammars (arbitrary one-pass compiler)

slide-62
SLIDE 62

Modularizing a One-Pass Compiler

  • existing one-pass compiler for a subset of C
  • 9 nonterminals
  • written for teaching at Aarhus university

(not by the authors of the present paper) 12/15

slide-63
SLIDE 63

Monolithic compiler

1 file 807 lines of Java code entangled

Modularized compiler

  • ca. 25 files

1620 lines of Scala code modular 13/15

slide-64
SLIDE 64

Properties of the Encoding

Modular Attributes are defined and type-checked separately Scalable Scala code size is linear in AG specification size. Compositional Each AG artifact is represented as a Scala value. 14/15

slide-65
SLIDE 65

Properties of the Encoding

Modular Attributes are defined and type-checked separately Scalable Scala code size is linear in AG specification size. Compositional Each AG artifact is represented as a Scala value. 14/15

slide-66
SLIDE 66

Properties of the Encoding

Modular Attributes are defined and type-checked separately Scalable Scala code size is linear in AG specification size. Compositional Each AG artifact is represented as a Scala value. 14/15

slide-67
SLIDE 67

Properties of the Encoding

Modular Attributes are defined and type-checked separately Scalable Scala code size is linear in AG specification size Compositional Each AG artifact is represented as a Scala value. 14/15

slide-68
SLIDE 68

Conclusions

Object Algebras

in Scala

Attribute Grammars

for compiler construction

Rendel et al. (2014)

15/15

slide-69
SLIDE 69

Conclusions

Object Algebras

in Scala Benefits for OA

  • Support for

inherited attributes

  • Access to

extensive AG research

  • Future work:

encode more AG features

Attribute Grammars

for compiler construction

Rendel et al. (2014)

15/15

slide-70
SLIDE 70

Conclusions

Object Algebras

in Scala Benefits for OA

  • Support for

inherited attributes

  • Access to

extensive AG research

  • Future work:

encode more AG features

Attribute Grammars

for compiler construction Benefits for AG

  • Modular, scalable, and

compositional encoding

  • Embedding enables

abstraction via meta language

  • Future work:

AG compiler to object algebras

Rendel et al. (2014)

15/15

slide-71
SLIDE 71

Conclusions

Object Algebras

in Scala Benefits for OA

  • Support for

inherited attributes

  • Access to

extensive AG research

  • Future work:

encode more AG features

Attribute Grammars

for compiler construction Benefits for AG

  • Modular, scalable, and

compositional encoding

  • Embedding enables

abstraction via meta language

  • Future work:

AG compiler to object algebras

Rendel et al. (2014)

Thank You!