from object algebras to attribute grammarsps.informatik.uni-tuebingen.de/2014/10/23/... ·...

Post on 29-Sep-2020

0 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

From Object Algebrasto Attribute Grammars

Tillmann Rendel · Jonathan Brachthäuser · Klaus OstermannUniversity of Marburg · University of Tübingen

http://www.informatik.uni-marburg.de/~rendel/oa2ag

Presentation by Tillmann Rendel at the International Conferenceon Object-Oriented Programming, Systems, Languages, and ApplicationsPortland, Oregon, October 23, 2014

Tree Traversals

1/15

Tree Traversals

1/15

Tree Traversals

How to structurea programthat containsmultiple traversalsof complex trees?

1/15

Visitor Patternin object-oriented programming

Folds & Traversal Schemesin functional programming

Church Encodingin theoretical work

Attribute Grammarsfor compiler construction

2/15

Visitor Patternin object-oriented programming

Folds & Traversal Schemesin functional programming

Church Encodingin theoretical work

Attribute Grammarsfor 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

Visitor Patternin object-oriented programming

Folds & Traversal Schemesin functional programming

Church Encodingin theoretical work

Attribute Grammarsfor 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

Visitor Patternin object-oriented programming

Folds & Traversal Schemesin functional programming

Church Encodingin theoretical work

Object Algebrasin Scala

Attribute Grammarsfor 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

Bottom-Up Data Flow

3/15

Synthesized Attributes

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

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

Equationse0.value = ne1 .value = e2.value + e3.value

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

4/15

Synthesized Attributes

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

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

Equationse0.value = ne1 .value = e2.value + e3.value

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

4/15

Synthesized Attributes

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

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

Equationse0.value = ne1 .value = e2.value + e3.value

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

4/15

Synthesized Attributes

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

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

Equationse0.value = ne1 .value = e2.value + e3.value

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

4/15

Synthesized Attributes

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

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

Equationse0.value = ne1 .value = e2.value + e3.value

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

4/15

Synthesized Attributes

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

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

Equationse0.value = ne1 .value = e2.value + e3.value

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

4/15

Synthesized Attributes

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

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

Equationse0.value = ne1 .value = e2.value + e3.value

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

4/15

Synthesized Attributes

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

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

Equationse0.value = ne1 .value = e2.value + e3.value

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

4/15

Synthesized Attributes

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

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

Equationse0.value = ne1 .value = e2.value + e3.value

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

4/15

Synthesized Attributes

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

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

Equationse0.value = ne1 .value = e2.value + e3.value

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

4/15

Top-Down Data Flow

5/15

Inherited Attributes

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

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

Equationse2 .left = truee3 .left = false

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

6/15

Inherited Attributes

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

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

Equationse2 .left = truee3 .left = false

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

6/15

Inherited Attributes

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

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

Equationse2 .left = truee3 .left = false

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

6/15

Inherited Attributes

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

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

Equationse2 .left = truee3 .left = false

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

6/15

Inherited Attributes

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

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

Equationse2 .left = truee3 .left = false

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

6/15

Inherited Attributes

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

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

Equationse2 .left = truee3 .left = false

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

6/15

Composition

7/15

Composition

compose

7/15

Composition

compose

7/15

Composition

assemble

7/15

compose( , ) =

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

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

8/15

compose( , ) =

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

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

8/15

compose( , ) =

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

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

8/15

compose( , ) =

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

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

8/15

compose( , ) =

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

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

8/15

compose( , ) =

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

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

8/15

compose( , ) =

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

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

8/15

compose( , ) =

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

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

8/15

current node

compose( , ) =

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

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

8/15

current node

children

compose( , ) =

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

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

8/15

current node

context fromparent

compose( , ) =

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

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

8/15

current node

compose( , ) =

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

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

8/15

compose( , ) =

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

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

8/15

compose( , ) =

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

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

8/15

compose( , ) =

Composing two algebrasdef 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

compose( , ) =

Composing two algebrasdef 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

compose( , ) =

Composing two algebrasdef 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

compose( , ) =

Composing two algebrasdef 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

compose( , ) =

Composing two algebrasdef 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

compose( , ) =

Composing two algebrasdef 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

compose( , ) =

Composing two algebrasdef 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

compose( , ) =

Composing two algebrasdef 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

Assembling a one-pass traversaldef 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

Assembling a one-pass traversaldef 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

Assembling a one-pass traversaldef 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

Assembling a one-pass traversaldef 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

Assembling a one-pass traversaldef 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

Results

Object algebras correspondto synthesized attributes(bottom-up data-flow)

We extend object algebrasto support inherited attributes(top-down data flow)

We assemble multiple algebrasto support L-attributed grammars(arbitrary one-pass compiler)

11/15

Results

Object algebras correspondto synthesized attributes(bottom-up data-flow)

We extend object algebrasto support inherited attributes(top-down data flow)

We assemble multiple algebrasto support L-attributed grammars(arbitrary one-pass compiler)

11/15

Results

Object algebras correspondto synthesized attributes(bottom-up data-flow)

We extend object algebrasto support inherited attributes(top-down data flow)

We assemble multiple algebrasto support L-attributed grammars(arbitrary one-pass compiler)

11/15

11/15

Results

Object algebras correspondto synthesized attributes(bottom-up data-flow)

We extend object algebrasto support inherited attributes(top-down data flow)

We assemble multiple algebrasto support L-attributed grammars(arbitrary one-pass compiler)

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

Monolithic compiler1 file807 lines of Java codeentangled

Modularized compilerca. 25 files1620 lines of Scala codemodular

13/15

Properties of the Encoding

ModularAttributes are defined and type-checked separately

ScalableScala code size is linear in AG specification size.

CompositionalEach AG artifact is represented as a Scala value.

14/15

Properties of the Encoding

ModularAttributes are defined and type-checked separately

ScalableScala code size is linear in AG specification size.

CompositionalEach AG artifact is represented as a Scala value.

14/15

Properties of the Encoding

ModularAttributes are defined and type-checked separately

ScalableScala code size is linear in AG specification size.

CompositionalEach AG artifact is represented as a Scala value.

14/15

Properties of the Encoding

ModularAttributes are defined and type-checked separately

ScalableScala code size is linear in AG specification size

CompositionalEach AG artifact is represented as a Scala value.

14/15

Conclusions

Object Algebrasin Scala

Attribute Grammarsfor compiler construction

Rendel et al. (2014)

15/15

Conclusions

Object Algebrasin Scala

Benefits for OA

● Support forinherited attributes

● Access toextensive AG research

● Future work:encode more AG features

Attribute Grammarsfor compiler construction

Rendel et al. (2014)

15/15

Conclusions

Object Algebrasin Scala

Benefits for OA

● Support forinherited attributes

● Access toextensive AG research

● Future work:encode more AG features

Attribute Grammarsfor compiler construction

Benefits for AG

● Modular, scalable, and compositional encoding

● Embedding enablesabstraction via meta language

● Future work:AG compiler to object algebras

Rendel et al. (2014)

15/15

Conclusions

Object Algebrasin Scala

Benefits for OA

● Support forinherited attributes

● Access toextensive AG research

● Future work:encode more AG features

Attribute Grammarsfor compiler construction

Benefits for AG

● Modular, scalable, and compositional encoding

● Embedding enablesabstraction via meta language

● Future work:AG compiler to object algebras

Rendel et al. (2014)

Thank You!

top related