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 representation (AST) semantics eval(term 1 + term 2 ) = eval( term 1 ) + eval( term 2 ) eval(term 1 - term 2 ) = eval( term 1 ) - eval( term 2 ) eval(factor 1 * factor 2 ) = eval(factor 1 ) * eval(factor 2 ) eval(factor 1 / factor 2 ) = eval(factor 1 ) / eval(factor 2 ) eval(n) = n eval(( expr )) = eval(expr) div0(term 1 + term 2 ) = div0( term 1 ) ∨ div0( term 2 ) div0(term 1 - term 2 ) = div0( term 1 ) ∨ div0( term 2 ) div0(factor 1 * factor 2 ) = div0(factor 1 ) ∨ div0(factor 2 ) div0(factor 1 / factor 2 ) = div0(factor 1 ) ∨ div0(factor 2 ) div0(factor 1 / 0) = t div0(n) = f div0(( expr )) = div0(expr) 3
Class Exercise Example from “Semantics of Context Free Languages” by Donald E. Knuth in Theory of Computing Systems , 2(2), 1968, pages 127–145. N ::= L | L.L L ::= B | LB B ::= 0 | 1 4
Attribute Grammar Grammar Attributes Production Production value: v( ● ) length: | ● | Rule N → L 1 .L 2 v(N) = v(L 1 )+v(L 2 )/2 |L2| N → L v(N) = v(L) L → L 1 B v(L) = 2*v(L 1 )+v(B) |L| = |L 1 |+|B| L → B v(L) = v(B) |L| = |B| B → 0 v(B) = 0 |B| = 1 B → 1 v(B) = 1 |B| = 1 5
Class Exercise Grammar Attributes Production Production value: v( ● ) length: | ● | Rule N → L 1 .L 2 v(N) = v(L 1 )+v(L 2 ) N → L v(N) = v(L) L → L 1 B v(L) = v(L 1 )+v(B) |L| = |L 1 |+|B| L → B v(L) = v(B) |L| = |B| B → 0 v(B) = ??? |B| = 1 B → 1 v(B) = ??? |B| = 1 6
Inherited vs. Synthesized Grammar Inherited Attributes Synthesized Attributes ttributes Production Production scale: s( ● ) value: v( ● ) length: | ● | Rule s(L 1 ) = 0 N → L 1 .L 2 v(N) = v(L 1 )+v(L 2 ) s(L 2 ) = -|L 2 | s(L) = 0 N → L v(N) = v(L) s(L 1 ) = s(L)+1 L → L 1 B v(L) = v(L 1 )+v(B) |L| = |L 1 |+|B| s(B) = s(L) s(B) = s(L) L → B v(L) = v(B) |L| = |B| B → 0 v(B) = 0 |B| = 1 B → 1 v(B) = 2 s(B) |B| = 1 7
RationalNumber BinaryNumber IntegralNumber integral : BitList integral : BitList fields fields fields fraction : BitList integral.scale() = 0 integral.scale() = 0 inh inh inh fraction.scale() = -fraction.length() value = integral.value() + fraction.value() value() : double value = integral.value() syn syn syn PluralBitList BitList bitList : BitList fields fields bit : Bit bitList.scale() = scale() + 1 scale() : int inh inh value = bitList.value() + bit.value() length() : double syn syn length = bitList.length() + bit.length() Zero One Bit fields fields fields inh inh inh value = 0 value = 2^scale() syn syn syn length = 1 length = 1 8
JastAdd: A DSL for Attribute Grammars example based on jastadd.org/old/examples/knuths-binary-numbers.php abstract BinaryNumber ; abstract non-terminal class declaration IntegralNumber : BinaryNumber ::= Integral : BitList ; non-terminal class declaration RationalNumber : BinaryNumber ::= Integral : BitList Fraction : BitList ; non-terminal class inheritance name type non-terminal fi eld declaration grammar production rule abstract BitList : BinaryNumber ; PluralBitList : BitList ::= BitList Bit ; abstract Bit : BitList; Zero : Bit ::= ; One : Bit ::= ; Grammar / AST 9
JastAdd: A DSL for Attribute Grammars example based on jastadd.org/old/examples/knuths-binary-numbers.php 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() ; synthesized attribute declaration eq PluralBitList.length() = getBitList().length() + getBit().length() ; eq Zero.length() = 1 ; eq One.length() = 1 ; synthesized attribute de fi nition 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 ; } Attributes 10
JastAdd: A DSL for Attribute Grammars example based on jastadd.org/old/examples/knuths-binary-numbers.php 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() ; synthesized attribute declaration eq PluralBitList.length() = getBitList().length() + getBit().length() ; eq Zero.length() = 1 ; eq One.length() = 1 ; synthesized attribute de fi nition 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 ; } Attributes 10
JastAdd: A DSL for Attribute Grammars example based on jastadd.org/old/examples/knuths-binary-numbers.php 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() ; synthesized attribute declaration eq PluralBitList.length() = getBitList().length() + getBit().length() ; eq Zero.length() = 1 ; eq One.length() = 1 ; synthesized attribute de fi nition inh int BitList.scale() ; inherited attribute declaration eq IntegralNumber.getIntegral().scale() = 0 ; inherited attribute de fi nition eq RationalNumber.getIntegral().scale() = 0 ; eq RationalNumber.getFraction().scale() = -getFraction().length() ; eq PluralBitList.getBitList().scale() = scale() + 1 ; } Attributes 10
JastAdd is a DSL for: Re-writeable Circular Reference Attribute Grammars 11
Picobot (Ad Nauseum) 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. state: 0; state: 1; rule: 0 **x* -> W 0; rule: 0 x*W* -> N 1; rule: 1 x*** -> N 1; Example Program 12
Picobot (Ad Nauseum) a Program has zero or more Declaration s Program ::= Declaration*; terminal fi eld 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; Grammar / AST 13
Some Utilities 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() ; } 14
Some Utilities 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; } collection attribute declaration commutative initial value sub-tree scope add operator coll Set<Rule> Program.rules() [ new HashSet<Rule>() ] with add root Program ; Rule contributes this to Program.rules() for program() ; } contributor element collection attribute contributee to add collection attribute contribution 14
Uh-Oh? state: 0; state: 1; rule: 0 **x* -> W 0; Program rule: 0 x*W* -> N 1; rule: 1 x*** -> N 1; Declaration Declaration Declaration Declaration Declaration State State Rule Rule Rule TargetLabel TargetLabel Label TargetLabel Label SourceLabel SourceLabel SourceLabel "0" "1" "0" Pattern MoveDirection "0" "0" Pattern MoveDirection "1" "1" Pattern MoveDirection "1" ... MoveWest ... MoveNorth ... MoveNorth 15
JastAdd is a DSL for: Re-writeable Circular Reference Attribute Grammars 16
Recommend
More recommend