SlideShare ist ein Scribd-Unternehmen logo
1 von 173
Downloaden Sie, um offline zu lesen
Eelco Visser
IN4303 Compiler Construction
TU Delft
September 2017
Declare Your Language
Chapter 4: Transformation
by Strategic Term Rewriting
2
Source
Code
Editor
Parse
Abstract
Syntax
Tree
Transform
Abstract
Syntax
Tree
DeïŹne transformations on abstract syntax trees (terms) using rewrite rules
Reading Material
3
The following papers add background, conceptual
exposition, and examples to the material from
the slides. Some notation and technical details
have been changed; check the documentation.
4
Term rewrite rules define
transformations on (abstract syntax)
trees. Traditional rewrite systems
apply rules exhaustively. This paper
introduces programmable rewriting
strategies to control the application
of rules, the core of the design of the
Stratego transformation language.
Note that the notation for contextual
rules is no longer supported by
Stratego. However, the technique to
implement contextual rules still
applies.
https://doi.org/10.1145/291251.289425
ICFP 1998
5
Stratego/XT combines SDF2 and Stratego
into toolset for program transformation.
This paper gives a high-level overview of
the concepts.
The StrategoXT.jar is still part of the
Spoofax distribution.
https://doi.org/10.1007/978-3-540-25935-0_13
Lecture Notes in Computer Science 2003
6
Spoofax combines SDF2 and Stratego
into a language workbench, i.e. an
IDE for creating language definition
from which IDEs for the defined
languages can be generated.
A distinctive feature of Spoofax is
live language development, which
supports developing a language
definition and programs in the
defined language in the same IDE
instance.
Spoofax was developed for Eclipse,
which is still the main development
platform. However, Spoofax Core is
now independent of any IDE.
https://doi.org/10.1145/1932682.1869497
OOPSLA 2010
7
Note that the since the publication
of this paper, we have introduced
more declarative approaches to name
and type analysis, which will be the
topic of the next lectures.
https://doi.org/10.1145/1932682.1869497
OOPSLA 2010
8
Documentation for Stratego at the metaborg.org website.
http://www.metaborg.org/en/latest/source/langdev/meta/lang/stratego/index.html
Transformation Architecture
9
This presentation uses the Stratego Shell for explaining the behavior of
Stratego programs. The Stratego Shell is currently not supported by Spoofax
10
11
12
13
14
15
16
17
18
Terms
19
Parsing: From Text to Terms
20
Let(
[ FunDec(
"fact"
, [FArg("n", Tp(Tid("int")))]
, Tp(Tid("int"))
, If(
Lt(Var("n"), Int("1"))
, Int("1")
, Seq(
[ Times(
Var("n")
, Call(
Var("fact")
, [Minus(Var("n"), Int("1"))]
)
)
]
)
)
)
]
, [Call(Var("fact"), [Int("10")])]
)
let function fact(n : int) : int =
if n < 1 then 1 else (n * fact(n - 1))
in fact(10)
end
Syntax of Terms
21
module Terms
sorts Cons Term
lexical syntax
Cons = [a-zA-Z][a-zA-Z0-9]*
context-free syntax
Term.App = <<Cons>(<{Term ","}*>)>
Zero()
Succ(Zero())
Cons(A(), Cons(B(), Nil()))
Syntax of Terms
22
module Terms
sorts Cons Term
lexical syntax
Cons = [a-zA-Z][a-zA-Z0-9]*
context-free syntax
Term.App = <<Cons>(<{Term ","}*>)>
Term.List = <[<{Term ","}*>]>
Term.Tuple = <(<{Term ","}*>)>
Zero()
Succ(Zero())
[A(), B()]
module ATerms
sorts Cons Term
lexical syntax
Cons = [a-zA-Z][a-zA-Z0-9]*
Cons = String
Int = [0-9]+
String = """ StringChar* """
StringChar = ~["n]
StringChar = "" ["]
context-free syntax
Term.Str = <<String>>
Term.Int = <<Int>>
Term.App = <<Cons>(<{Term ","}*>)>
Term.List = <[<{Term ","}*>]>
Term.Tuple = <(<{Term ","}*>)>
Syntax of Terms
23
0
1
[A(), B()]
Var(“x”)
Let(
[ Decl(“x”, IntT()),
Decl(“y”, BoolT())
]
, Eq(Var(“x”), Int(0))
)
Syntax of A(nnotated) Terms
24
module ATerms
sorts Cons Term
lexical syntax
Cons = [a-zA-Z][a-zA-Z0-9]*
// more lexical syntax omitted
context-free syntax
Term.Anno = <<PreTerm>{<{Term “,"}*>}>
Term = <<PreTerm>>
PreTerm.Str = <<String>>
PreTerm.Int = <<Int>>
PreTerm.App = <<Cons>(<{Term ","}*>)>
PreTerm.List = <[<{Term ","}*>]>
PreTerm.Tuple = <(<{Term ","}*>)>
Var(“x”){Type(IntT())}
Signatures
25
Signatures
26
signature
constructors
Uminus : Exp -> Exp
Power : Exp * Exp -> Exp
Times : Exp * Exp -> Exp
Divide : Exp * Exp -> Exp
Plus : Exp * Exp -> Exp
Minus : Exp * Exp -> Exp
CPlus : Exp * Exp -> Exp
CMinus : Exp * Exp -> Exp
Eq : Exp * Exp -> Exp
Neq : Exp * Exp -> Exp
Gt : Exp * Exp -> Exp
Lt : Exp * Exp -> Exp
Geq : Exp * Exp -> Exp
Leq : Exp * Exp -> Exp
True : Exp
False : Exp
And : Exp * Exp -> Exp
Or : Exp * Exp -> Exp
context-free syntax
Exp.Uminus = [- [Exp]]
Exp.Power = [[Exp] ** [Exp]]
Exp.Times = [[Exp] * [Exp]]
Exp.Divide = [[Exp] / [Exp]]
Exp.Plus = [[Exp] + [Exp]]
Exp.Minus = [[Exp] - [Exp]]
Exp.CPlus = [[Exp] +i [Exp]]
Exp.CMinus = [[Exp] -i [Exp]]
Exp.Eq = [[Exp] = [Exp]]
Exp.Neq = [[Exp] <> [Exp]]
Exp.Gt = [[Exp] > [Exp]]
Exp.Lt = [[Exp] < [Exp]]
Exp.Geq = [[Exp] >= [Exp]]
Exp.Leq = [[Exp] <= [Exp]]
Exp.True = <true>
Exp.False = <false>
Exp.And = [[Exp] & [Exp]]
Exp.Or = [[Exp] | [Exp]]
Signature declares argument and
return types of term constructors
Signature is automatically
generated from SDF3 productions
Stratego compiler only checks
arity of constructor applications
Rewrite Rules
27
Desugaring
28
if x then
printint(x)
desugar: IfThen(e1, e2) -> IfThenElse(e1, e2, NoVal())
if x then
printint(x)
else
()
IfThen(
Var("x")
, Call(
"printint"
, [Var("x")]
)
)
IfThenElse(
Var("x")
, Call(
"printint"
, [Var("x")]
)
, NoVal()
)
pattern matching pattern instantiation
e1
e2
More Desugaring
29
desugar: Uminus(e) -> Bop(MINUS(), Int("0"), e)
desugar: Plus(e1, e2) -> Bop(PLUS(), e1, e2)
desugar: Minus(e1, e2) -> Bop(MINUS(), e1, e2)
desugar: Times(e1, e2) -> Bop(MUL(), e1, e2)
desugar: Divide(e1, e2) -> Bop(DIV(), e1, e2)
desugar: Eq(e1, e2) -> Rop(EQ(), e1, e2)
desugar: Neq(e1, e2) -> Rop(NE(), e1, e2)
desugar: Leq(e1, e2) -> Rop(LE(), e1, e2)
desugar: Lt(e1, e2) -> Rop(LT(), e1, e2)
desugar: Geq(e1, e2) -> Rop(LE(), e2, e1)
desugar: Gt(e1, e2) -> Rop(LT(), e2, e1)
desugar: And(e1, e2) -> IfThenElse(e1, e2, Int("0"))
desugar: Or(e1, e2) -> IfThenElse(e1, Int("1"), e2)
signature
constructors
PLUS: BinOp
MINUS: BinOp
MUL: BinOp
DIV: BinOp
EQ: RelOp
NE: RelOp
LE: RelOp
LT: RelOp
Bop: BinOp * Expr * Expr -> Expr
Rop: RelOp * Expr * Expr -> Expr
Constant Folding
30
x := 21 + 21 + x
eval: Bop(PLUS(), Int(i1), Int(i2)) -> Int(i3)
where <addS> (i1, i2) => i3
x := 42 + x
Assign(
Var("x")
, Plus(
Plus(
Int("21")
, Int("21")
)
, Var("x")
)
)
Assign(
Var("x")
, Plus(
Int("42")
, Var("x")
)
)
More Constant Folding
31
eval: Bop(PLUS(), Int(i1), Int(i2)) -> Int(<addS> (i1, i2))
eval: Bop(MINUS(), Int(i1), Int(i2)) -> Int(<subtS> (i1, i2))
eval: Bop(MUL(), Int(i1), Int(i2)) -> Int(<mulS> (i1, i2))
eval: Bop(DIV(), Int(i1), Int(i2)) -> Int(<divS> (i1, i2))
eval: Rop(EQ(), Int(i), Int(i)) -> Int("1")
eval: Rop(EQ(), Int(i1), Int(i2)) -> Int("0") where not( <eq> (i1, i2) )
eval: Rop(NE(), Int(i), Int(i)) -> Int("0")
eval: Rop(NE(), Int(i1), Int(i2)) -> Int("1") where not( <eq> (i1, i2) )
eval: Rop(LT(), Int(i1), Int(i2)) -> Int("1") where <ltS> (i1, i2)
eval: Rop(LT(), Int(i1), Int(i2)) -> Int("0") where not( <ltS> (i1, i2) )
eval: Rop(LE(), Int(i1), Int(i2)) -> Int("1") where <leqS> (i1, i2)
eval: Rop(LE(), Int(i1), Int(i2)) -> Int("0") where not( <leqS> (i1, i2))
Term Rewriting
(Bottom-up)
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
Parameterized Rewrite Rules: Map
62
[ 1
, 2
, 3
]
[ 2
, 3
, 4
]
map(inc)
inc
1
2
3
2
3
4inc
inc
map(s): [] -> []
map(s): [x|xs] -> [<s> x | <map(s)> xs]
Parameterized Rewrite Rules: Zip
63
[ 1
, 2
, 3
]
[ (1,4)
, (2,5)
, (3,6)
]
[ 4
, 5
, 6
]
zip
[ 1
, 2
, 3
]
[ 5
, 7
, 9
]
[ 4
, 5
, 6
]
zip(add)
map(add)
zip(s): ([],[]) -> []
zip(s): ([x|xs],[y|ys]) -> [<s> (x,y) | <zip(s)> (xs,ys)]
zip = zip(id)
Parameterized Rewrite Rules: Fold
64
[1,2,3] foldr(!0,add) 6
[]
0
[3]
3
[2,3]
56
[1,2,3]
foldr(s1,s2): [] -> <s1>
foldr(s1,s2): [x|xs] -> <s2> (x,<foldr(s1,s2)> xs)
Parameterized Rewrite Rules: Inverse
65
[1,2,3] inverse(|[]) [3,2,1]
[2,3]
[1][]
[1,2,3] [3]
[2,1] [3,2,1]
[]
inverse(|is): [] -> is
inverse(|is): [x|xs] -> <inverse(|[x|is])> xs
66
67
68
69
Traversal Strategies
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
Traversal Combinators
85
86
87
88
89
90
91
92
Traversal: Topdown
93
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
topdown(s) = s ; all(topdown(s))
topdown(switch)
Const
Mul
Const
3 4 5
Const
Add1
Traversal: Topdown
94
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
topdown(s) = s ; all(topdown(s))
topdown(switch)
Mul
Const
3
Const
4 5
Const
Add1
2
Traversal: Topdown
95
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
topdown(s) = s ; all(topdown(s))
topdown(switch)
Mul
Const
3
Const
5 4
Const
Add1
2
3
Traversal: Topdown/Try
96
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
topdown(s) = s ; all(topdown(s))
topdown(try(switch))
Const
Mul
Const
3 4 5
Const
Add1
Traversal: Topdown/Try
97
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
topdown(s) = s ; all(topdown(s))
topdown(try(switch))
Mul
Const
3
Const
4 5
Const
Add1
2
Traversal: Topdown/Try
98
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
topdown(s) = s ; all(topdown(s))
topdown(try(switch))
Mul
Const
3
Const
5 4
Const
Add1
2
3
4
5
6
7
8
Traversal: Alltd
99
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
alltd(s) = s <+ all(alltd(s))
alltd(switch)
Const
Mul
Const
3 4 5
Const
Add1
Traversal: Alltd
100
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
alltd(s) = s <+ all(alltd(s))
alltd(switch)
Mul
Const
3
Const
4 5
Const
Add1
Traversal: Alltd
101
switch: Mul(e1, e2) -> Mul(e2, e1)
alltd(s) = s <+ all(alltd(s))
alltd(switch)
Const
Mul
Const
3 4 5
Const
Add1
2
3
4
Traversal: Alltd
102
switch: Mul(e1, e2) -> Mul(e2, e1)
alltd(s) = s <+ all(alltd(s))
alltd(switch)
Const
Mul
Const
3 5 4
Const
Add1
2
3
4
Traversal: Bottomup
103
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(switch)
Const
Mul
Const
3 4 5
Const
Add1
2
3
Traversal: Bottomup
104
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(try(switch))
Const
Mul
Const
3 4 5
Const
Add1
2
3
4
5
6
7
8
Traversal: Bottomup
105
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(try(switch))
Const
Mul
Const
3 4 5
Const
Add1
2
3
4
Traversal: Bottomup
106
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(try(switch))
Const
Mul
Const
3 5 4
Const
Add1
2
3
4
Traversal: Bottomup
107
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(try(switch))
Const
Mul
Const
3 5 4
Const
Add1
Traversal: Bottomup
108
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(try(switch))
Mul
Const
3
Const
5 4
Const
Add1
109
110
Traversal: Innermost
111
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
innermost(s) = bottomup(try(s ; innermost(s)))
innermost(switch)
Const
Mul
Const
3 4 5
Const
Add1
2
3
4
5
6
7
8
Traversal: Innermost
112
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
innermost(s) = bottomup(try(s ; innermost(s)))
innermost(switch)
Const
Mul
Const
3 4 5
Const
Add1
2
3
4
Traversal: Innermost
113
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
innermost(s) = bottomup(try(s ; innermost(s)))
innermost(switch)
Const
Mul
Const
3 5 4
Const
Add1
2
3
4
9
10
11
12
Traversal: Innermost
114
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
innermost(s) = bottomup(try(s ; innermost(s)))
innermost(switch)
Const
Mul
Const
3 5 4
Const
Add1
2
3
4
Traversal: Innermost
115
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
innermost(s) = bottomup(try(s ; innermost(s)))
innermost(switch)
Const
Mul
Const
3 4 5
Const
Add1
2
3
4
116
117
118
119
120
121
Type-Unifying
Transformations
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
Spoofax Builders
155
Spoofax Builders
156
rules
build :
(node, _, ast, path, project-path) -> result
with
<some-transformation> ast => result
Builder gets AST as parameter
Tiger: AST Builder
157
rules // Debugging
debug-show-aterm:
(node, _, _, path, project-path) -> (filename, result)
with
filename := <guarantee-extension(|"aterm")> path
; result := node
trans/tiger.str
module Syntax
menus
menu: "Syntax" (openeditor)
action: "Format" = editor-format (source)
action: "Show parsed AST" = debug-show-aterm (source)
editor/syntax.esv
Builder gets AST as parameter
Application: Formatting
158
Tiger: Formatting Builder
159
module Syntax
menus
menu: "Syntax" (openeditor)
action: "Format" = editor-format (source)
action: "Show parsed AST" = debug-show-aterm (source)
rules
editor-format:
(node, _, ast, path, project-path) -> (filename, result)
with
ext := <get-extension> path
; filename := <guarantee-extension(|$[pp.[ext]])> path
; result := <pp-debug> node
editor/syntax.esv
trans/pp.str
rules
pp-Tiger-string =
parenthesize-Tiger
; prettyprint-Tiger-start-symbols
; !V([], <id>)
; box2text-string(|120)
pp-debug :
ast -> result
with
result := <pp-Tiger-string> ast
<+ 

; result := “"
trans/pp.str
Tiger: Parenthesize
160
module pp/Tiger-parenthesize
imports
libstratego-lib
signatures/-
strategies
parenthesize-Tiger =
innermost(TigerParenthesize)
rules
TigerParenthesize :
Or(t_0, t_1) -> Or(t_0, Parenthetical(t_1))
where <(?For(_, _, _, _)
+ ?While(_, _)
+ ?IfThen(_, _)
+ ?If(_, _, _)
+ ?Assign(_, _)
+ ?Array(_, _, _)
+ ?Or(_, _)
+ fail)> t_1
TigerParenthesize :
And(t_0, t_1) -> And(Parenthetical(t_0), t_1)
where <(?For(_, _, _, _)
+ ?While(_, _)
+ ?IfThen(_, _)
+ ?If(_, _, _)
+ ?Assign(_, _)
+ ?Array(_, _, _)
+ ?Or(_, _)
+ fail)> t_0
pp/Tiger-parenthesize.str
context-free priorities
Exp.And
> Exp.Or
> Exp.Array
> Exp.Assign
> 

Tiger: Pretty-Print Rules
161
rules
prettyprint-Tiger-Exp :
If(t1__, t2__, t3__) -> [ H(
[SOpt(HS(), "0")]
, [ S("if ")
, t1__'
, S(" then")
]
)
, t2__'
, H(
[SOpt(HS(), "0")]
, [S("else")]
)
, t3__'
]
with t1__' := <pp-one-Z(prettyprint-Tiger-Exp)
<+ pp-one-Z(prettyprint-completion-aux)> t1__
with t2__' := <pp-indent(|"2")> [
<pp-one-Z(prettyprint-Tiger-Exp)
<+ pp-one-Z(prettyprint-completion-aux)> t2__ ]
with t3__' := <pp-indent(|"2")> [
<pp-one-Z(prettyprint-Tiger-Exp)
<+ pp-one-Z(prettyprint-completion-aux)> t3__ ]
context-free syntax
Exp.If = <
if <Exp> then
<Exp>
else
<Exp>
>
syntax/Control-Flow.sdf3
pp/Control-Flow-pp.str
Application: Desugaring
162
Tiger: Desugaring
163
function printboard() = (
for i := 0 to N-1 do (
for j := 0 to N-1 do
print(if col[i]=j then " O" else " .");
print("n")
);
print("n")
)
function printboard() = (
let
var i : int := 0
in
while i < N - 1 do ( (
let
var j : int := 0
in
while j < N - 1 do (
print(if col[i] = j then
" O"
else
" .");
j := j + 1
)
end;
print("n")
);
i := i + 1
)
end;
print("n")
)
Expressing for in terms of while++
Tiger: Desugaring Builder
164
rules // Desugaring
editor-desugar :
(node, _, _, path, project-path) -> (filename, result)
with
filename := <guarantee-extension(|"des.tig")> path
; result := <desugar-all; pp-Tiger-string>node
editor-desugar-ast :
(node, _, _, path, project-path) -> (filename, result)
with
filename := <guarantee-extension(|"aterm")> path
; result := <desugar-all>node
trans/tiger.str
module Transformation
menus
menu: "Transform" (openeditor) (realtime)
action: "Desugar" = editor-desugar (source)
action: "Desugar AST" = editor-desugar-ast (source)
editor/Transformation.esv
Tiger: Desugaring Transformation
165
module desugar
imports signatures/Tiger-sig
imports 

strategies
desugar-all = topdown(try(desugar))
rules
desugar :
For(
Var(i)
, e1
, e2
, e_body
) ->
Let(
[VarDec(i, Tid("int"), e1)]
, [ While(
Lt(Var(i), e2)
, Seq(
[ e_body
, Assign(Var(i), Plus(Var(i), Int("1")))
]
)
)
]
)
Application: Outline View
166
Tiger: Outline View
167
Tiger: Outline View Builder
168
module Syntax
views
outline view: editor-outline (source)
expand to level: 3
editor/syntax.esv
trans/outline.str
module outline
imports
signatures/Tiger-sig
signatures/Types-sig
signatures/Records-sig
signatures/Variables-sig
signatures/Functions-sig
signatures/Bindings-sig
libspoofax/editor/outline
pp
rules
editor-outline:
(_, _, ast, path, project-path) -> outline
where
outline := <simple-label-outline(to-outline-label)> ast
Tiger: Outline View Rules
169
rules
to-outline-label :
Let(_, _) -> $[let]
to-outline-label :
TypeDec(name, _) -> $[type [name]]
to-outline-label :
FunDec(name, _, t, _) -> $[fun [name] : [<pp-tiger-type> t]]
to-outline-label :
ProcDec(name, _, _) -> $[fun [name]]
to-outline-label :
VarDecNoType(name, _) -> $[var [name]]
to-outline-label :
VarDec(name, _, _) -> $[var [name]]
trans/outline.str
rules
to-outline-label :
Call(f, _) -> $[[f]()]
to-outline-label :
If(_, _, _) -> $[if]
to-outline-label :
For(Var(name), _, _, _) -> $[for [name]]
// etc.
Outline View: Generic Strategy
170
module libspoofax/editor/outline
imports 

signature
constructors
Node : Label * Children -> Node
rules
simple-label-outline(s1) =
collect-om(to-outline-node(s1, fail), conc)
custom-label-outline(s1, s2) =
collect-om(origin-track-forced(s2) <+ to-outline-node(s1, s2), conc)
to-outline-node(s1, s2):
term -> Node(label, children)
where
random := <next-random>;
label := <origin-track-forced(s1; term-to-outline-label)> term;
children := <get-arguments; custom-label-outline(s1, s2)> term
term-to-outline-label =
is-string
<+ ?term{a}; origin-text; ?label; !label{a}
<+ write-to-string // fallback
Language-independent
strategy for collecting
outline nodes
Term structure for
outline nodes
Application: Completion
171
Tiger: Completion Rules
172
rules
suggest-completions(|completions):
Exp-Plhdr() -> <add-completions(
| ( "If"
, If(
<try(inline-completions(|Exp-Plhdr()))> Exp-Plhdr()
, <try(inline-completions(|Exp-Plhdr()))> Exp-Plhdr()
, <try(inline-completions(|Exp-Plhdr()))> Exp-Plhdr()
)
)
)
; fail> completions
context-free syntax
Exp.If = <
if <Exp> then
<Exp>
else
<Exp>
>
syntax/Control-Flow.sdf3
completion/Control-Flow-cp.str
173
Except where otherwise noted, this work is licensed under

Weitere Àhnliche Inhalte

Was ist angesagt?

Declarative Type System Specification with Statix
Declarative Type System Specification with StatixDeclarative Type System Specification with Statix
Declarative Type System Specification with Statix
Eelco Visser
 
Declare Your Language (at DLS)
Declare Your Language (at DLS)Declare Your Language (at DLS)
Declare Your Language (at DLS)
Eelco Visser
 

Was ist angesagt? (20)

CS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | ParsingCS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | Parsing
 
Dynamic Semantics Specification and Interpreter Generation
Dynamic Semantics Specification and Interpreter GenerationDynamic Semantics Specification and Interpreter Generation
Dynamic Semantics Specification and Interpreter Generation
 
CS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definitionCS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definition
 
Dynamic Semantics
Dynamic SemanticsDynamic Semantics
Dynamic Semantics
 
CS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic ServicesCS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic Services
 
Compiler Construction | Lecture 4 | Parsing
Compiler Construction | Lecture 4 | Parsing Compiler Construction | Lecture 4 | Parsing
Compiler Construction | Lecture 4 | Parsing
 
Declarative Semantics Definition - Term Rewriting
Declarative Semantics Definition - Term RewritingDeclarative Semantics Definition - Term Rewriting
Declarative Semantics Definition - Term Rewriting
 
Declarative Type System Specification with Statix
Declarative Type System Specification with StatixDeclarative Type System Specification with Statix
Declarative Type System Specification with Statix
 
Static name resolution
Static name resolutionStatic name resolution
Static name resolution
 
Compiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersCompiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | Interpreters
 
Term Rewriting
Term RewritingTerm Rewriting
Term Rewriting
 
Separation of Concerns in Language Definition
Separation of Concerns in Language DefinitionSeparation of Concerns in Language Definition
Separation of Concerns in Language Definition
 
Declare Your Language (at DLS)
Declare Your Language (at DLS)Declare Your Language (at DLS)
Declare Your Language (at DLS)
 
Chapter 22. Lambda Expressions and LINQ
Chapter 22. Lambda Expressions and LINQChapter 22. Lambda Expressions and LINQ
Chapter 22. Lambda Expressions and LINQ
 
Compiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual MachinesCompiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual Machines
 
Compiler Construction | Lecture 3 | Syntactic Editor Services
Compiler Construction | Lecture 3 | Syntactic Editor ServicesCompiler Construction | Lecture 3 | Syntactic Editor Services
Compiler Construction | Lecture 3 | Syntactic Editor Services
 
A Language Designer’s Workbench. A one-stop shop for implementation and verif...
A Language Designer’s Workbench. A one-stop shop for implementation and verif...A Language Designer’s Workbench. A one-stop shop for implementation and verif...
A Language Designer’s Workbench. A one-stop shop for implementation and verif...
 
13. Java text processing
13.  Java text processing13.  Java text processing
13. Java text processing
 
19. Data Structures and Algorithm Complexity
19. Data Structures and Algorithm Complexity19. Data Structures and Algorithm Complexity
19. Data Structures and Algorithm Complexity
 
15. Streams Files and Directories
15. Streams Files and Directories 15. Streams Files and Directories
15. Streams Files and Directories
 

Ähnlich wie Declare Your Language: Transformation by Strategic Term Rewriting

Profiling and optimization
Profiling and optimizationProfiling and optimization
Profiling and optimization
g3_nittala
 
Compilation of COSMO for GPU using LLVM
Compilation of COSMO for GPU using LLVMCompilation of COSMO for GPU using LLVM
Compilation of COSMO for GPU using LLVM
Linaro
 
Faster Python, FOSDEM
Faster Python, FOSDEMFaster Python, FOSDEM
Faster Python, FOSDEM
Victor Stinner
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 

Ähnlich wie Declare Your Language: Transformation by Strategic Term Rewriting (20)

IntroducciĂłn a Elixir
IntroducciĂłn a ElixirIntroducciĂłn a Elixir
IntroducciĂłn a Elixir
 
time_complexity_list_02_04_2024_22_pages.pdf
time_complexity_list_02_04_2024_22_pages.pdftime_complexity_list_02_04_2024_22_pages.pdf
time_complexity_list_02_04_2024_22_pages.pdf
 
Haskellă§ć­Šă¶é–ąæ•°ćž‹èš€èȘž
Haskellă§ć­Šă¶é–ąæ•°ćž‹èš€èȘžHaskellă§ć­Šă¶é–ąæ•°ćž‹èš€èȘž
Haskellă§ć­Šă¶é–ąæ•°ćž‹èš€èȘž
 
Egor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov - .NET Core intrinsics and other micro-optimizationsEgor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov - .NET Core intrinsics and other micro-optimizations
 
Profiling and optimization
Profiling and optimizationProfiling and optimization
Profiling and optimization
 
Transducers in JavaScript
Transducers in JavaScriptTransducers in JavaScript
Transducers in JavaScript
 
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
 
Seminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mmeSeminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mme
 
Basic R Data Manipulation
Basic R Data ManipulationBasic R Data Manipulation
Basic R Data Manipulation
 
Clojure for Data Science
Clojure for Data ScienceClojure for Data Science
Clojure for Data Science
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 
Compilation of COSMO for GPU using LLVM
Compilation of COSMO for GPU using LLVMCompilation of COSMO for GPU using LLVM
Compilation of COSMO for GPU using LLVM
 
Faster Python, FOSDEM
Faster Python, FOSDEMFaster Python, FOSDEM
Faster Python, FOSDEM
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Language
 
Clojure basics
Clojure basicsClojure basics
Clojure basics
 
The secrets of inverse brogramming
The secrets of inverse brogrammingThe secrets of inverse brogramming
The secrets of inverse brogramming
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Optimization and Mathematical Programming in R and ROI - R Optimization Infra...
Optimization and Mathematical Programming in R and ROI - R Optimization Infra...Optimization and Mathematical Programming in R and ROI - R Optimization Infra...
Optimization and Mathematical Programming in R and ROI - R Optimization Infra...
 
Day 4b iteration and functions for-loops.pptx
Day 4b   iteration and functions  for-loops.pptxDay 4b   iteration and functions  for-loops.pptx
Day 4b iteration and functions for-loops.pptx
 

Mehr von Eelco Visser

Mehr von Eelco Visser (16)

CS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: IntroductionCS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: Introduction
 
A Direct Semantics of Declarative Disambiguation Rules
A Direct Semantics of Declarative Disambiguation RulesA Direct Semantics of Declarative Disambiguation Rules
A Direct Semantics of Declarative Disambiguation Rules
 
Compiler Construction | Lecture 17 | Beyond Compiler Construction
Compiler Construction | Lecture 17 | Beyond Compiler ConstructionCompiler Construction | Lecture 17 | Beyond Compiler Construction
Compiler Construction | Lecture 17 | Beyond Compiler Construction
 
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Domain Specific Languages for Parallel Graph AnalytiX (PGX)Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
 
Compiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory ManagementCompiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory Management
 
Compiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code GenerationCompiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code Generation
 
Compiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone FrameworksCompiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone Frameworks
 
Compiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 10 | Data-Flow AnalysisCompiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 10 | Data-Flow Analysis
 
Compiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type CheckingCompiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type Checking
 
Compiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 6 | Introduction to Static AnalysisCompiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 6 | Introduction to Static Analysis
 
Compiler Construction | Lecture 2 | Declarative Syntax Definition
Compiler Construction | Lecture 2 | Declarative Syntax DefinitionCompiler Construction | Lecture 2 | Declarative Syntax Definition
Compiler Construction | Lecture 2 | Declarative Syntax Definition
 
Compiler Construction | Lecture 1 | What is a compiler?
Compiler Construction | Lecture 1 | What is a compiler?Compiler Construction | Lecture 1 | What is a compiler?
Compiler Construction | Lecture 1 | What is a compiler?
 
Declare Your Language: Virtual Machines & Code Generation
Declare Your Language: Virtual Machines & Code GenerationDeclare Your Language: Virtual Machines & Code Generation
Declare Your Language: Virtual Machines & Code Generation
 
Declare Your Language: Dynamic Semantics
Declare Your Language: Dynamic SemanticsDeclare Your Language: Dynamic Semantics
Declare Your Language: Dynamic Semantics
 
Declare Your Language: Constraint Resolution 2
Declare Your Language: Constraint Resolution 2Declare Your Language: Constraint Resolution 2
Declare Your Language: Constraint Resolution 2
 
Declare Your Language: Constraint Resolution 1
Declare Your Language: Constraint Resolution 1Declare Your Language: Constraint Resolution 1
Declare Your Language: Constraint Resolution 1
 

KĂŒrzlich hochgeladen

CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Bert Jan Schrijver
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 

KĂŒrzlich hochgeladen (20)

%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
call girls in Vaishali (Ghaziabad) 🔝 >àŒ’8448380779 🔝 genuine Escort Service đŸ”âœ”ïžâœ”ïž
call girls in Vaishali (Ghaziabad) 🔝 >àŒ’8448380779 🔝 genuine Escort Service đŸ”âœ”ïžâœ”ïžcall girls in Vaishali (Ghaziabad) 🔝 >àŒ’8448380779 🔝 genuine Escort Service đŸ”âœ”ïžâœ”ïž
call girls in Vaishali (Ghaziabad) 🔝 >àŒ’8448380779 🔝 genuine Escort Service đŸ”âœ”ïžâœ”ïž
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 

Declare Your Language: Transformation by Strategic Term Rewriting

  • 1. Eelco Visser IN4303 Compiler Construction TU Delft September 2017 Declare Your Language Chapter 4: Transformation by Strategic Term Rewriting
  • 3. Reading Material 3 The following papers add background, conceptual exposition, and examples to the material from the slides. Some notation and technical details have been changed; check the documentation.
  • 4. 4 Term rewrite rules define transformations on (abstract syntax) trees. Traditional rewrite systems apply rules exhaustively. This paper introduces programmable rewriting strategies to control the application of rules, the core of the design of the Stratego transformation language. Note that the notation for contextual rules is no longer supported by Stratego. However, the technique to implement contextual rules still applies. https://doi.org/10.1145/291251.289425 ICFP 1998
  • 5. 5 Stratego/XT combines SDF2 and Stratego into toolset for program transformation. This paper gives a high-level overview of the concepts. The StrategoXT.jar is still part of the Spoofax distribution. https://doi.org/10.1007/978-3-540-25935-0_13 Lecture Notes in Computer Science 2003
  • 6. 6 Spoofax combines SDF2 and Stratego into a language workbench, i.e. an IDE for creating language definition from which IDEs for the defined languages can be generated. A distinctive feature of Spoofax is live language development, which supports developing a language definition and programs in the defined language in the same IDE instance. Spoofax was developed for Eclipse, which is still the main development platform. However, Spoofax Core is now independent of any IDE. https://doi.org/10.1145/1932682.1869497 OOPSLA 2010
  • 7. 7 Note that the since the publication of this paper, we have introduced more declarative approaches to name and type analysis, which will be the topic of the next lectures. https://doi.org/10.1145/1932682.1869497 OOPSLA 2010
  • 8. 8 Documentation for Stratego at the metaborg.org website. http://www.metaborg.org/en/latest/source/langdev/meta/lang/stratego/index.html
  • 9. Transformation Architecture 9 This presentation uses the Stratego Shell for explaining the behavior of Stratego programs. The Stratego Shell is currently not supported by Spoofax
  • 10. 10
  • 11. 11
  • 12. 12
  • 13. 13
  • 14. 14
  • 15. 15
  • 16. 16
  • 17. 17
  • 18. 18
  • 20. Parsing: From Text to Terms 20 Let( [ FunDec( "fact" , [FArg("n", Tp(Tid("int")))] , Tp(Tid("int")) , If( Lt(Var("n"), Int("1")) , Int("1") , Seq( [ Times( Var("n") , Call( Var("fact") , [Minus(Var("n"), Int("1"))] ) ) ] ) ) ) ] , [Call(Var("fact"), [Int("10")])] ) let function fact(n : int) : int = if n < 1 then 1 else (n * fact(n - 1)) in fact(10) end
  • 21. Syntax of Terms 21 module Terms sorts Cons Term lexical syntax Cons = [a-zA-Z][a-zA-Z0-9]* context-free syntax Term.App = <<Cons>(<{Term ","}*>)> Zero() Succ(Zero()) Cons(A(), Cons(B(), Nil()))
  • 22. Syntax of Terms 22 module Terms sorts Cons Term lexical syntax Cons = [a-zA-Z][a-zA-Z0-9]* context-free syntax Term.App = <<Cons>(<{Term ","}*>)> Term.List = <[<{Term ","}*>]> Term.Tuple = <(<{Term ","}*>)> Zero() Succ(Zero()) [A(), B()]
  • 23. module ATerms sorts Cons Term lexical syntax Cons = [a-zA-Z][a-zA-Z0-9]* Cons = String Int = [0-9]+ String = """ StringChar* """ StringChar = ~["n] StringChar = "" ["] context-free syntax Term.Str = <<String>> Term.Int = <<Int>> Term.App = <<Cons>(<{Term ","}*>)> Term.List = <[<{Term ","}*>]> Term.Tuple = <(<{Term ","}*>)> Syntax of Terms 23 0 1 [A(), B()] Var(“x”) Let( [ Decl(“x”, IntT()), Decl(“y”, BoolT()) ] , Eq(Var(“x”), Int(0)) )
  • 24. Syntax of A(nnotated) Terms 24 module ATerms sorts Cons Term lexical syntax Cons = [a-zA-Z][a-zA-Z0-9]* // more lexical syntax omitted context-free syntax Term.Anno = <<PreTerm>{<{Term “,"}*>}> Term = <<PreTerm>> PreTerm.Str = <<String>> PreTerm.Int = <<Int>> PreTerm.App = <<Cons>(<{Term ","}*>)> PreTerm.List = <[<{Term ","}*>]> PreTerm.Tuple = <(<{Term ","}*>)> Var(“x”){Type(IntT())}
  • 26. Signatures 26 signature constructors Uminus : Exp -> Exp Power : Exp * Exp -> Exp Times : Exp * Exp -> Exp Divide : Exp * Exp -> Exp Plus : Exp * Exp -> Exp Minus : Exp * Exp -> Exp CPlus : Exp * Exp -> Exp CMinus : Exp * Exp -> Exp Eq : Exp * Exp -> Exp Neq : Exp * Exp -> Exp Gt : Exp * Exp -> Exp Lt : Exp * Exp -> Exp Geq : Exp * Exp -> Exp Leq : Exp * Exp -> Exp True : Exp False : Exp And : Exp * Exp -> Exp Or : Exp * Exp -> Exp context-free syntax Exp.Uminus = [- [Exp]] Exp.Power = [[Exp] ** [Exp]] Exp.Times = [[Exp] * [Exp]] Exp.Divide = [[Exp] / [Exp]] Exp.Plus = [[Exp] + [Exp]] Exp.Minus = [[Exp] - [Exp]] Exp.CPlus = [[Exp] +i [Exp]] Exp.CMinus = [[Exp] -i [Exp]] Exp.Eq = [[Exp] = [Exp]] Exp.Neq = [[Exp] <> [Exp]] Exp.Gt = [[Exp] > [Exp]] Exp.Lt = [[Exp] < [Exp]] Exp.Geq = [[Exp] >= [Exp]] Exp.Leq = [[Exp] <= [Exp]] Exp.True = <true> Exp.False = <false> Exp.And = [[Exp] & [Exp]] Exp.Or = [[Exp] | [Exp]] Signature declares argument and return types of term constructors Signature is automatically generated from SDF3 productions Stratego compiler only checks arity of constructor applications
  • 28. Desugaring 28 if x then printint(x) desugar: IfThen(e1, e2) -> IfThenElse(e1, e2, NoVal()) if x then printint(x) else () IfThen( Var("x") , Call( "printint" , [Var("x")] ) ) IfThenElse( Var("x") , Call( "printint" , [Var("x")] ) , NoVal() ) pattern matching pattern instantiation e1 e2
  • 29. More Desugaring 29 desugar: Uminus(e) -> Bop(MINUS(), Int("0"), e) desugar: Plus(e1, e2) -> Bop(PLUS(), e1, e2) desugar: Minus(e1, e2) -> Bop(MINUS(), e1, e2) desugar: Times(e1, e2) -> Bop(MUL(), e1, e2) desugar: Divide(e1, e2) -> Bop(DIV(), e1, e2) desugar: Eq(e1, e2) -> Rop(EQ(), e1, e2) desugar: Neq(e1, e2) -> Rop(NE(), e1, e2) desugar: Leq(e1, e2) -> Rop(LE(), e1, e2) desugar: Lt(e1, e2) -> Rop(LT(), e1, e2) desugar: Geq(e1, e2) -> Rop(LE(), e2, e1) desugar: Gt(e1, e2) -> Rop(LT(), e2, e1) desugar: And(e1, e2) -> IfThenElse(e1, e2, Int("0")) desugar: Or(e1, e2) -> IfThenElse(e1, Int("1"), e2) signature constructors PLUS: BinOp MINUS: BinOp MUL: BinOp DIV: BinOp EQ: RelOp NE: RelOp LE: RelOp LT: RelOp Bop: BinOp * Expr * Expr -> Expr Rop: RelOp * Expr * Expr -> Expr
  • 30. Constant Folding 30 x := 21 + 21 + x eval: Bop(PLUS(), Int(i1), Int(i2)) -> Int(i3) where <addS> (i1, i2) => i3 x := 42 + x Assign( Var("x") , Plus( Plus( Int("21") , Int("21") ) , Var("x") ) ) Assign( Var("x") , Plus( Int("42") , Var("x") ) )
  • 31. More Constant Folding 31 eval: Bop(PLUS(), Int(i1), Int(i2)) -> Int(<addS> (i1, i2)) eval: Bop(MINUS(), Int(i1), Int(i2)) -> Int(<subtS> (i1, i2)) eval: Bop(MUL(), Int(i1), Int(i2)) -> Int(<mulS> (i1, i2)) eval: Bop(DIV(), Int(i1), Int(i2)) -> Int(<divS> (i1, i2)) eval: Rop(EQ(), Int(i), Int(i)) -> Int("1") eval: Rop(EQ(), Int(i1), Int(i2)) -> Int("0") where not( <eq> (i1, i2) ) eval: Rop(NE(), Int(i), Int(i)) -> Int("0") eval: Rop(NE(), Int(i1), Int(i2)) -> Int("1") where not( <eq> (i1, i2) ) eval: Rop(LT(), Int(i1), Int(i2)) -> Int("1") where <ltS> (i1, i2) eval: Rop(LT(), Int(i1), Int(i2)) -> Int("0") where not( <ltS> (i1, i2) ) eval: Rop(LE(), Int(i1), Int(i2)) -> Int("1") where <leqS> (i1, i2) eval: Rop(LE(), Int(i1), Int(i2)) -> Int("0") where not( <leqS> (i1, i2))
  • 33. 33
  • 34. 34
  • 35. 35
  • 36. 36
  • 37. 37
  • 38. 38
  • 39. 39
  • 40. 40
  • 41. 41
  • 42. 42
  • 43. 43
  • 44. 44
  • 45. 45
  • 46. 46
  • 47. 47
  • 48. 48
  • 49. 49
  • 50. 50
  • 51. 51
  • 52. 52
  • 53. 53
  • 54. 54
  • 55. 55
  • 56. 56
  • 57. 57
  • 58. 58
  • 59. 59
  • 60. 60
  • 61. 61
  • 62. Parameterized Rewrite Rules: Map 62 [ 1 , 2 , 3 ] [ 2 , 3 , 4 ] map(inc) inc 1 2 3 2 3 4inc inc map(s): [] -> [] map(s): [x|xs] -> [<s> x | <map(s)> xs]
  • 63. Parameterized Rewrite Rules: Zip 63 [ 1 , 2 , 3 ] [ (1,4) , (2,5) , (3,6) ] [ 4 , 5 , 6 ] zip [ 1 , 2 , 3 ] [ 5 , 7 , 9 ] [ 4 , 5 , 6 ] zip(add) map(add) zip(s): ([],[]) -> [] zip(s): ([x|xs],[y|ys]) -> [<s> (x,y) | <zip(s)> (xs,ys)] zip = zip(id)
  • 64. Parameterized Rewrite Rules: Fold 64 [1,2,3] foldr(!0,add) 6 [] 0 [3] 3 [2,3] 56 [1,2,3] foldr(s1,s2): [] -> <s1> foldr(s1,s2): [x|xs] -> <s2> (x,<foldr(s1,s2)> xs)
  • 65. Parameterized Rewrite Rules: Inverse 65 [1,2,3] inverse(|[]) [3,2,1] [2,3] [1][] [1,2,3] [3] [2,1] [3,2,1] [] inverse(|is): [] -> is inverse(|is): [x|xs] -> <inverse(|[x|is])> xs
  • 66. 66
  • 67. 67
  • 68. 68
  • 69. 69
  • 71. 71
  • 72. 72
  • 73. 73
  • 74. 74
  • 75. 75
  • 76. 76
  • 77. 77
  • 78. 78
  • 79. 79
  • 80. 80
  • 81. 81
  • 82. 82
  • 83. 83
  • 84. 84
  • 86. 86
  • 87. 87
  • 88. 88
  • 89. 89
  • 90. 90
  • 91. 91
  • 92. 92
  • 93. Traversal: Topdown 93 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) topdown(s) = s ; all(topdown(s)) topdown(switch) Const Mul Const 3 4 5 Const Add1
  • 94. Traversal: Topdown 94 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) topdown(s) = s ; all(topdown(s)) topdown(switch) Mul Const 3 Const 4 5 Const Add1 2
  • 95. Traversal: Topdown 95 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) topdown(s) = s ; all(topdown(s)) topdown(switch) Mul Const 3 Const 5 4 Const Add1 2 3
  • 96. Traversal: Topdown/Try 96 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) topdown(s) = s ; all(topdown(s)) topdown(try(switch)) Const Mul Const 3 4 5 Const Add1
  • 97. Traversal: Topdown/Try 97 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) topdown(s) = s ; all(topdown(s)) topdown(try(switch)) Mul Const 3 Const 4 5 Const Add1 2
  • 98. Traversal: Topdown/Try 98 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) topdown(s) = s ; all(topdown(s)) topdown(try(switch)) Mul Const 3 Const 5 4 Const Add1 2 3 4 5 6 7 8
  • 99. Traversal: Alltd 99 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) alltd(s) = s <+ all(alltd(s)) alltd(switch) Const Mul Const 3 4 5 Const Add1
  • 100. Traversal: Alltd 100 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) alltd(s) = s <+ all(alltd(s)) alltd(switch) Mul Const 3 Const 4 5 Const Add1
  • 101. Traversal: Alltd 101 switch: Mul(e1, e2) -> Mul(e2, e1) alltd(s) = s <+ all(alltd(s)) alltd(switch) Const Mul Const 3 4 5 Const Add1 2 3 4
  • 102. Traversal: Alltd 102 switch: Mul(e1, e2) -> Mul(e2, e1) alltd(s) = s <+ all(alltd(s)) alltd(switch) Const Mul Const 3 5 4 Const Add1 2 3 4
  • 103. Traversal: Bottomup 103 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(switch) Const Mul Const 3 4 5 Const Add1 2 3
  • 104. Traversal: Bottomup 104 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(try(switch)) Const Mul Const 3 4 5 Const Add1 2 3 4 5 6 7 8
  • 105. Traversal: Bottomup 105 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(try(switch)) Const Mul Const 3 4 5 Const Add1 2 3 4
  • 106. Traversal: Bottomup 106 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(try(switch)) Const Mul Const 3 5 4 Const Add1 2 3 4
  • 107. Traversal: Bottomup 107 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(try(switch)) Const Mul Const 3 5 4 Const Add1
  • 108. Traversal: Bottomup 108 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(try(switch)) Mul Const 3 Const 5 4 Const Add1
  • 109. 109
  • 110. 110
  • 111. Traversal: Innermost 111 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) innermost(s) = bottomup(try(s ; innermost(s))) innermost(switch) Const Mul Const 3 4 5 Const Add1 2 3 4 5 6 7 8
  • 112. Traversal: Innermost 112 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) innermost(s) = bottomup(try(s ; innermost(s))) innermost(switch) Const Mul Const 3 4 5 Const Add1 2 3 4
  • 113. Traversal: Innermost 113 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) innermost(s) = bottomup(try(s ; innermost(s))) innermost(switch) Const Mul Const 3 5 4 Const Add1 2 3 4 9 10 11 12
  • 114. Traversal: Innermost 114 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) innermost(s) = bottomup(try(s ; innermost(s))) innermost(switch) Const Mul Const 3 5 4 Const Add1 2 3 4
  • 115. Traversal: Innermost 115 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) innermost(s) = bottomup(try(s ; innermost(s))) innermost(switch) Const Mul Const 3 4 5 Const Add1 2 3 4
  • 116. 116
  • 117. 117
  • 118. 118
  • 119. 119
  • 120. 120
  • 121. 121
  • 123. 123
  • 124. 124
  • 125. 125
  • 126. 126
  • 127. 127
  • 128. 128
  • 129. 129
  • 130. 130
  • 131. 131
  • 132. 132
  • 133. 133
  • 134. 134
  • 135. 135
  • 136. 136
  • 137. 137
  • 138. 138
  • 139. 139
  • 140. 140
  • 141. 141
  • 142. 142
  • 143. 143
  • 144. 144
  • 145. 145
  • 146. 146
  • 147. 147
  • 148. 148
  • 149. 149
  • 150. 150
  • 151. 151
  • 152. 152
  • 153. 153
  • 154. 154
  • 156. Spoofax Builders 156 rules build : (node, _, ast, path, project-path) -> result with <some-transformation> ast => result Builder gets AST as parameter
  • 157. Tiger: AST Builder 157 rules // Debugging debug-show-aterm: (node, _, _, path, project-path) -> (filename, result) with filename := <guarantee-extension(|"aterm")> path ; result := node trans/tiger.str module Syntax menus menu: "Syntax" (openeditor) action: "Format" = editor-format (source) action: "Show parsed AST" = debug-show-aterm (source) editor/syntax.esv Builder gets AST as parameter
  • 159. Tiger: Formatting Builder 159 module Syntax menus menu: "Syntax" (openeditor) action: "Format" = editor-format (source) action: "Show parsed AST" = debug-show-aterm (source) rules editor-format: (node, _, ast, path, project-path) -> (filename, result) with ext := <get-extension> path ; filename := <guarantee-extension(|$[pp.[ext]])> path ; result := <pp-debug> node editor/syntax.esv trans/pp.str rules pp-Tiger-string = parenthesize-Tiger ; prettyprint-Tiger-start-symbols ; !V([], <id>) ; box2text-string(|120) pp-debug : ast -> result with result := <pp-Tiger-string> ast <+ 
 ; result := “" trans/pp.str
  • 160. Tiger: Parenthesize 160 module pp/Tiger-parenthesize imports libstratego-lib signatures/- strategies parenthesize-Tiger = innermost(TigerParenthesize) rules TigerParenthesize : Or(t_0, t_1) -> Or(t_0, Parenthetical(t_1)) where <(?For(_, _, _, _) + ?While(_, _) + ?IfThen(_, _) + ?If(_, _, _) + ?Assign(_, _) + ?Array(_, _, _) + ?Or(_, _) + fail)> t_1 TigerParenthesize : And(t_0, t_1) -> And(Parenthetical(t_0), t_1) where <(?For(_, _, _, _) + ?While(_, _) + ?IfThen(_, _) + ?If(_, _, _) + ?Assign(_, _) + ?Array(_, _, _) + ?Or(_, _) + fail)> t_0 pp/Tiger-parenthesize.str context-free priorities Exp.And > Exp.Or > Exp.Array > Exp.Assign > 

  • 161. Tiger: Pretty-Print Rules 161 rules prettyprint-Tiger-Exp : If(t1__, t2__, t3__) -> [ H( [SOpt(HS(), "0")] , [ S("if ") , t1__' , S(" then") ] ) , t2__' , H( [SOpt(HS(), "0")] , [S("else")] ) , t3__' ] with t1__' := <pp-one-Z(prettyprint-Tiger-Exp) <+ pp-one-Z(prettyprint-completion-aux)> t1__ with t2__' := <pp-indent(|"2")> [ <pp-one-Z(prettyprint-Tiger-Exp) <+ pp-one-Z(prettyprint-completion-aux)> t2__ ] with t3__' := <pp-indent(|"2")> [ <pp-one-Z(prettyprint-Tiger-Exp) <+ pp-one-Z(prettyprint-completion-aux)> t3__ ] context-free syntax Exp.If = < if <Exp> then <Exp> else <Exp> > syntax/Control-Flow.sdf3 pp/Control-Flow-pp.str
  • 163. Tiger: Desugaring 163 function printboard() = ( for i := 0 to N-1 do ( for j := 0 to N-1 do print(if col[i]=j then " O" else " ."); print("n") ); print("n") ) function printboard() = ( let var i : int := 0 in while i < N - 1 do ( ( let var j : int := 0 in while j < N - 1 do ( print(if col[i] = j then " O" else " ."); j := j + 1 ) end; print("n") ); i := i + 1 ) end; print("n") ) Expressing for in terms of while++
  • 164. Tiger: Desugaring Builder 164 rules // Desugaring editor-desugar : (node, _, _, path, project-path) -> (filename, result) with filename := <guarantee-extension(|"des.tig")> path ; result := <desugar-all; pp-Tiger-string>node editor-desugar-ast : (node, _, _, path, project-path) -> (filename, result) with filename := <guarantee-extension(|"aterm")> path ; result := <desugar-all>node trans/tiger.str module Transformation menus menu: "Transform" (openeditor) (realtime) action: "Desugar" = editor-desugar (source) action: "Desugar AST" = editor-desugar-ast (source) editor/Transformation.esv
  • 165. Tiger: Desugaring Transformation 165 module desugar imports signatures/Tiger-sig imports 
 strategies desugar-all = topdown(try(desugar)) rules desugar : For( Var(i) , e1 , e2 , e_body ) -> Let( [VarDec(i, Tid("int"), e1)] , [ While( Lt(Var(i), e2) , Seq( [ e_body , Assign(Var(i), Plus(Var(i), Int("1"))) ] ) ) ] )
  • 168. Tiger: Outline View Builder 168 module Syntax views outline view: editor-outline (source) expand to level: 3 editor/syntax.esv trans/outline.str module outline imports signatures/Tiger-sig signatures/Types-sig signatures/Records-sig signatures/Variables-sig signatures/Functions-sig signatures/Bindings-sig libspoofax/editor/outline pp rules editor-outline: (_, _, ast, path, project-path) -> outline where outline := <simple-label-outline(to-outline-label)> ast
  • 169. Tiger: Outline View Rules 169 rules to-outline-label : Let(_, _) -> $[let] to-outline-label : TypeDec(name, _) -> $[type [name]] to-outline-label : FunDec(name, _, t, _) -> $[fun [name] : [<pp-tiger-type> t]] to-outline-label : ProcDec(name, _, _) -> $[fun [name]] to-outline-label : VarDecNoType(name, _) -> $[var [name]] to-outline-label : VarDec(name, _, _) -> $[var [name]] trans/outline.str rules to-outline-label : Call(f, _) -> $[[f]()] to-outline-label : If(_, _, _) -> $[if] to-outline-label : For(Var(name), _, _, _) -> $[for [name]] // etc.
  • 170. Outline View: Generic Strategy 170 module libspoofax/editor/outline imports 
 signature constructors Node : Label * Children -> Node rules simple-label-outline(s1) = collect-om(to-outline-node(s1, fail), conc) custom-label-outline(s1, s2) = collect-om(origin-track-forced(s2) <+ to-outline-node(s1, s2), conc) to-outline-node(s1, s2): term -> Node(label, children) where random := <next-random>; label := <origin-track-forced(s1; term-to-outline-label)> term; children := <get-arguments; custom-label-outline(s1, s2)> term term-to-outline-label = is-string <+ ?term{a}; origin-text; ?label; !label{a} <+ write-to-string // fallback Language-independent strategy for collecting outline nodes Term structure for outline nodes
  • 172. Tiger: Completion Rules 172 rules suggest-completions(|completions): Exp-Plhdr() -> <add-completions( | ( "If" , If( <try(inline-completions(|Exp-Plhdr()))> Exp-Plhdr() , <try(inline-completions(|Exp-Plhdr()))> Exp-Plhdr() , <try(inline-completions(|Exp-Plhdr()))> Exp-Plhdr() ) ) ) ; fail> completions context-free syntax Exp.If = < if <Exp> then <Exp> else <Exp> > syntax/Control-Flow.sdf3 completion/Control-Flow-cp.str
  • 173. 173 Except where otherwise noted, this work is licensed under