Attribute Grammars intermediate syntax semantics representation - - PowerPoint PPT Presentation

attribute grammars
SMART_READER_LITE
LIVE PREVIEW

Attribute Grammars intermediate syntax semantics representation - - PowerPoint PPT Presentation

Attribute Grammars intermediate syntax semantics representation Language Implementation 2 expr ::= term | term + term | term - term term ::= factor | factor * factor | factor / factor factor ::= n | ( expr ) intermediate


slide-1
SLIDE 1

Attribute Grammars

slide-2
SLIDE 2

2

Language Implementation

intermediate representation semantics syntax

slide-3
SLIDE 3

3

expr ::= term | term + term | term - term term ::= factor | factor * factor | factor / factor factor ::= n | ( expr ) eval(term1 + term2) = eval( term1 ) + eval( term2 ) eval(term1 - term2) = eval( term1 ) - eval( term2 ) eval(factor1 * factor2) = eval(factor1) * eval(factor2) eval(factor1 / factor2) = eval(factor1) / eval(factor2) eval(n) = n eval(( expr )) = eval(expr) div0(term1 + term2) = div0( term1 ) ∨ div0( term2 ) div0(term1 - term2) = div0( term1 ) ∨ div0( term2 ) div0(factor1 * factor2) = div0(factor1) ∨ div0(factor2) div0(factor1 / factor2) = div0(factor1) ∨ div0(factor2) div0(factor1 / 0) = t div0(n) = f div0(( expr )) = div0(expr)

intermediate representation (AST) semantics

slide-4
SLIDE 4

4

N ::= L | L.L L ::= B | LB B ::= 0 | 1

Class Exercise

Example from “Semantics of Context Free Languages” by Donald E. Knuth in Theory of Computing Systems, 2(2), 1968, pages 127–145.

slide-5
SLIDE 5

5

Grammar Production Attributes Production Rule value: v(●) length: |●| N → L1.L2 v(N) = v(L1)+v(L2)/2|L2| N → L v(N) = v(L) L → L1B v(L) = 2*v(L1)+v(B) |L| = |L1|+|B| L → B v(L) = v(B) |L| = |B| B → 0 v(B) = 0 |B| = 1 B → 1 v(B) = 1 |B| = 1

Attribute Grammar

slide-6
SLIDE 6

6

Grammar Production Attributes Production Rule value: v(●) length: |●| N → L1.L2 v(N) = v(L1)+v(L2) N → L v(N) = v(L) L → L1B v(L) = v(L1)+v(B) |L| = |L1|+|B| L → B v(L) = v(B) |L| = |B| B → 0 v(B) = ??? |B| = 1 B → 1 v(B) = ??? |B| = 1

Class Exercise

slide-7
SLIDE 7

7

Inherited Attributes Grammar Production Synthesized Attributes ttributes scale: s(●) Production Rule value: v(●) length: |●| s(L1) = 0 s(L2) = -|L2| N → L1.L2 v(N) = v(L1)+v(L2) s(L) = 0 N → L v(N) = v(L) s(L1) = s(L)+1 s(B) = s(L) L → L1B v(L) = v(L1)+v(B) |L| = |L1|+|B| s(B) = s(L) L → B v(L) = v(B) |L| = |B| B → 0 v(B) = 0 |B| = 1 B → 1 v(B) = 2s(B) |B| = 1

Inherited vs. Synthesized

slide-8
SLIDE 8

8 BinaryNumber fields inh syn value() : double BitList fields inh scale() : int syn length() : double IntegralNumber fields integral : BitList inh integral.scale() = 0 syn value = integral.value() Bit fields inh syn RationalNumber fields integral : BitList fraction : BitList inh integral.scale() = 0 fraction.scale() = -fraction.length() syn value = integral.value() + fraction.value() PluralBitList fields bitList : BitList bit : Bit inh bitList.scale() = scale() + 1 syn value = bitList.value() + bit.value() length = bitList.length() + bit.length() Zero fields inh syn value = 0 length = 1 One fields inh syn value = 2^scale() length = 1

slide-9
SLIDE 9

9

JastAdd: A DSL for Attribute Grammars

abstract BinaryNumber; IntegralNumber : BinaryNumber ::= Integral:BitList; RationalNumber : BinaryNumber ::= Integral:BitList Fraction:BitList; abstract BitList:BinaryNumber; PluralBitList : BitList ::= BitList Bit; abstract Bit : BitList; Zero:Bit ::= ; One:Bit ::= ;

example based on jastadd.org/old/examples/knuths-binary-numbers.php

Grammar / AST

abstract non-terminal class declaration non-terminal class declaration non-terminal class inheritance grammar production rule name type non-terminal field declaration

slide-10
SLIDE 10

aspect BinaryNumberValue { syn double BinaryNumber.value(); eq IntegralNumber.value() = getIntegral().value(); eq RationalNumber.value() = getIntegral().value() + getFraction().value(); eq PluralBitList.value() = getBit().value() + getBitList().value(); eq Zero.value() = 0; eq One.value() = java.lang.Math.pow(2.0, scale()); syn int BitList.length(); eq PluralBitList.length() = getBitList().length() + getBit().length(); eq Zero.length() = 1; eq One.length() = 1; inh int BitList.scale(); eq IntegralNumber.getIntegral().scale() = 0; eq RationalNumber.getIntegral().scale() = 0; eq RationalNumber.getFraction().scale() = -getFraction().length(); eq PluralBitList.getBitList().scale() = scale() + 1; }

10

JastAdd: A DSL for Attribute Grammars

Attributes

example based on jastadd.org/old/examples/knuths-binary-numbers.php

synthesized attribute declaration synthesized attribute definition

slide-11
SLIDE 11

aspect BinaryNumberValue { syn double BinaryNumber.value(); eq IntegralNumber.value() = getIntegral().value(); eq RationalNumber.value() = getIntegral().value() + getFraction().value(); eq PluralBitList.value() = getBit().value() + getBitList().value(); eq Zero.value() = 0; eq One.value() = java.lang.Math.pow(2.0, scale()); syn int BitList.length(); eq PluralBitList.length() = getBitList().length() + getBit().length(); eq Zero.length() = 1; eq One.length() = 1; inh int BitList.scale(); eq IntegralNumber.getIntegral().scale() = 0; eq RationalNumber.getIntegral().scale() = 0; eq RationalNumber.getFraction().scale() = -getFraction().length(); eq PluralBitList.getBitList().scale() = scale() + 1; }

10

JastAdd: A DSL for Attribute Grammars

Attributes

example based on jastadd.org/old/examples/knuths-binary-numbers.php

synthesized attribute declaration synthesized attribute definition

slide-12
SLIDE 12

aspect BinaryNumberValue { syn double BinaryNumber.value(); eq IntegralNumber.value() = getIntegral().value(); eq RationalNumber.value() = getIntegral().value() + getFraction().value(); eq PluralBitList.value() = getBit().value() + getBitList().value(); eq Zero.value() = 0; eq One.value() = java.lang.Math.pow(2.0, scale()); syn int BitList.length(); eq PluralBitList.length() = getBitList().length() + getBit().length(); eq Zero.length() = 1; eq One.length() = 1; inh int BitList.scale(); eq IntegralNumber.getIntegral().scale() = 0; eq RationalNumber.getIntegral().scale() = 0; eq RationalNumber.getFraction().scale() = -getFraction().length(); eq PluralBitList.getBitList().scale() = scale() + 1; }

10

JastAdd: A DSL for Attribute Grammars

Attributes

example based on jastadd.org/old/examples/knuths-binary-numbers.php

synthesized attribute declaration synthesized attribute definition inherited attribute declaration inherited attribute definition

slide-13
SLIDE 13

11

JastAdd is a DSL for: Re-writeable Circular Reference Attribute Grammars

slide-14
SLIDE 14

12

state: 0; state: 1; rule: 0 **x* -> W 0; rule: 0 x*W* -> N 1; rule: 1 x*** -> N 1;

Picobot (Ad Nauseum)

Example Program

Example based on “An Introductory Tutorial on JastAdd Attribute Grammars” by Görel Hedin in Generative and Transformational Techniques in Software Engineering III, volume 6491 of Lecture Notes in Computer Science, pages 166–200. Springer Berlin / Heidelberg, 2011.

slide-15
SLIDE 15

13

Program ::= Declaration*; abstract Declaration; State : Declaration ::= <Label:String>; Rule : Declaration ::= <SourceLabel:String> Pattern MoveDirection <TargetLabel:String>; Pattern ::= North:PatternDirection East:PatternDirection West:PatternDirection South:PatternDirection; abstract PatternDirection; BlockedNorth : PatternDirection; BlockedEast : PatternDirection; BlockedWest : PatternDirection; BlockedSouth : PatternDirection; Free : PatternDirection; BlockedOrFree : PatternDirection; abstract MoveDirection; MoveNorth : MoveDirection; MoveEast : MoveDirection; MoveWest : MoveDirection; MoveSouth : MoveDirection; Stay : MoveDirection;

Picobot (Ad Nauseum)

Grammar / AST

a Program has zero or more Declarations terminal field declaration

slide-16
SLIDE 16

aspect Properties { inh Program Declaration.program(); eq Program.getDeclaration(int i).program() = this; syn Set<State> Program.states() { Set<State> result = new HashSet<State>(); for (Declaration d : getDeclarationList()) if (d instanceof State) result.add((State)d); return result; } coll Set<Rule> Program.rules() [new HashSet<Rule>()] with add root Program; Rule contributes this to Program.rules() for program(); }

Some Utilities

14

slide-17
SLIDE 17

aspect Properties { inh Program Declaration.program(); eq Program.getDeclaration(int i).program() = this; syn Set<State> Program.states() { Set<State> result = new HashSet<State>(); for (Declaration d : getDeclarationList()) if (d instanceof State) result.add((State)d); return result; } coll Set<Rule> Program.rules() [new HashSet<Rule>()] with add root Program; Rule contributes this to Program.rules() for program(); }

Some Utilities

14 collection attribute declaration initial value commutative add operator sub-tree scope collection attribute contribution element to add contributee contributor collection attribute

slide-18
SLIDE 18

Uh-Oh?

15

Program Declaration Declaration Declaration State State Rule "0" "1" "0" Pattern MoveDirection "0" Declaration Rule "0" Pattern MoveDirection "1" Declaration Rule "1" Pattern MoveDirection "1" ... MoveWest MoveNorth MoveNorth ... ...

Label Label SourceLabel SourceLabel SourceLabel TargetLabel TargetLabel TargetLabel

state: 0; state: 1; rule: 0 **x* -> W 0; rule: 0 x*W* -> N 1; rule: 1 x*** -> N 1;

slide-19
SLIDE 19

16

JastAdd is a DSL for: Re-writeable Circular Reference Attribute Grammars

slide-20
SLIDE 20

aspect NameAnalysis { syn State Rule.source() = lookup(getSourceLabel()); syn State Rule.target() = lookup(getTargetLabel()); syn State Declaration.lookup(String label); eq Rule.lookup(String label) { for (State s : program().states()) { State match = s.lookup(label); if (match != null) return match; } return null; } eq State.lookup(String label) = (label.equals(getLabel())) ? this : null; }

17

Reference Attributes

are really no different from “regular” attributes

slide-21
SLIDE 21

aspect NameAnalysis { syn State Rule.source() = lookup(getSourceLabel()); syn State Rule.target() = lookup(getTargetLabel()); syn State Declaration.lookup(String label); eq Rule.lookup(String label) { for (State s : program().states()) { State match = s.lookup(label); if (match != null) return match; } return null; } eq State.lookup(String label) = (label.equals(getLabel())) ? this : null; }

17

Reference Attributes

are really no different from “regular” attributes

parameterized attribute

slide-22
SLIDE 22

aspect NameAnalysis { syn State Rule.source() = lookup(getSourceLabel()); syn State Rule.target() = lookup(getTargetLabel()); syn State Declaration.lookup(String label); eq Rule.lookup(String label) { for (State s : program().states()) { State match = s.lookup(label); if (match != null) return match; } return null; } eq State.lookup(String label) = (label.equals(getLabel())) ? this : null; }

17

Reference Attributes

are really no different from “regular” attributes

parameterized attribute

slide-23
SLIDE 23

Class Exercise: Reachability

18

state: 0; state: 1; state: 2; state: 3; rule: 0 x*** -> N 1; rule: 1 *x** -> E 2; rule: 2 ***x -> E 3; rule: 3 x*** -> E 0;

coll Set<State> State.targets() [new HashSet<State>()] with add root Program; Rule contributes target() to State.targets() for source(); syn Set<State> State.reachable(); eq State.reachable() { ??? }

1 2 3

slide-24
SLIDE 24

Uh-Oh?

19

state: 0; state: 1; state: 2; state: 3; rule: 0 x*** -> N 1; rule: 1 *x** -> E 2; rule: 2 ***x -> E 3; rule: 3 x*** -> E 0;

coll Set<State> State.targets() [new HashSet<State>()] with add root Program; Rule contributes target() to State.targets() for source(); syn Set<State> State.reachable(); eq State.reachable() { Set<State> result = new HashSet<State>(); for (State s : targets()) { result.add(s); result.addAll(s.reachable()); } return result; }

1 2 3

slide-25
SLIDE 25

20

JastAdd is a DSL for: Re-writeable Circular Reference Attribute Grammars

slide-26
SLIDE 26

Circular Attributes

21

state: 0; state: 1; state: 2; state: 3; rule: 0 x*** -> N 1; rule: 1 *x** -> E 2; rule: 2 ***x -> E 3; rule: 3 x*** -> E 0;

coll Set<State> State.targets() [new HashSet<State>()] with add root Program; Rule contributes target() to State.targets() for source(); syn Set<State> State.reachable() circular [new HashSet<State>()]; eq State.reachable() { Set<State> result = new HashSet<State>(); for (State s : targets()) { result.add(s); result.addAll(s.reachable()); } return result; }

1 2 3

initial value

slide-27
SLIDE 27

More Fun With DSLs!

22

aspect dot { syn String Program.dot() { StringBuilder sb = new StringBuilder(); sb.append("digraph picobot {\n\n"); sb.append("\trankdir=LR\n"); for (Rule rule : rules()) sb.append("\t" + rule.dot() + "\n"); sb.append("\n}"); return sb.toString(); } syn String Rule.dot() = String.format("%s -> %s [label =\"[%s]{%s}\"]", getSourceLabel(), getTargetLabel(), getPattern().dot(), getMoveDirection().dot()); syn String Pattern.dot() = String.format("%s%s%s%s", getNorth().dot(), getEast().dot(), getWest().dot(), getSouth().dot()); syn String PatternDirection.dot(); eq BlockedNorth.dot() = "N"; eq BlockedEast.dot() = "E"; eq BlockedWest.dot() = "W"; eq BlockedSouth.dot() = "S"; eq Free.dot() = "x"; eq BlockedOrFree.dot() = "*"; syn String MoveDirection.dot(); eq MoveNorth.dot() = "N"; eq MoveEast.dot() = "E"; eq MoveWest.dot() = "W"; eq MoveSouth.dot() = "S"; eq Stay.dot() = "X"; }

slide-28
SLIDE 28

It’s DSLs All The Way Down

23

To implement our DSL, we used the following DSLs:

  • Flex for lexing
  • Beaver for parsing
  • JastAdd for intermediate representation and semantics

with sub-DSLs for ASTs and grammar

  • Ant for building
  • Dot for visualization