SlideShare a Scribd company logo
Eelco Visser
CS4200 Compiler Construction
TU Delft
September 2018
Lecture 5: Transformation by Term Rewriting
No deadlines
- There are no deadlines for homework

- I have removed the ‘advisory’ deadlines

- Make at your own pace; but important to prepare for exam

Reading material on parsing
- Read sections 4.1, 4.2, 4.3, 4.5, 4.6 of ‘Dragon’ book

- In particular: FIRST and FOLLOW set, constructing SLR table

New assignments
- Week 1.2: templates, completion

- Week 1.3: LR parsing

Slides on parsing extended with more examples
!2
Notes on Homework
Would you be interested in
peer review of homework
assignments?
3
Channel on research group Slack
Where many Spoofax users hang out
Ask questions about Spoofax
(Not answers to assignments)
No guarantee to quick response, or answer at all
Send me an email if you want an invitation
!4
#spoofax-users
This Lecture
!5
Source
Code
Editor
Parse
Abstract
Syntax
Tree
Transform
Abstract
Syntax
Tree
Define transformations on abstract syntax trees (terms) using rewrite rules
Reading Material
6
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.
!7
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
!8
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
!9
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
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.
!10
Documentation for Stratego at
the metaborg.org website.
http://www.metaborg.org/en/latest/source/langdev/meta/lang/stratego/index.html
!11
This paper defines the formal semantics of the full Stratego
language, including its scoped dynamic rules feature.
If you want to dig deeper
These slides document most features of the base language
without dynamic rules and without giving the formal
semantics.
Transformation Architecture
12
This presentation uses the Stratego Shell for explaining the behavior of
Stratego programs. The Stratego Shell is currently not supported by Spoofax
!13
!14
!15
!16
!17
!18
!19
!20
!21
Terms
22
Parsing: From Text to Terms
!23
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
!24
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
!25
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
!26
0
1
[A(), B()]
Var(“x”)
Let(
[ Decl(“x”, IntT()),
Decl(“y”, BoolT())
]
, Eq(Var(“x”), Int(0))
)
Syntax of A(nnotated) Terms
!27
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
28
Signatures
!29
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
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
Rewrite Rules
30
Desugaring
!31
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
if x then
printint(x)
More Desugaring
!32
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"))
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
!33
x := 21 + 21 + x
eval: 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
!34
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))
Application: Spoofax
Builders
35
Spoofax Builders
!36
rules
build :
(node, _, ast, path, project-path) -> result
with
<some-transformation> ast => result
Builder gets AST as parameter
Tiger: AST Builder
!37
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
38
Tiger: Formatting Builder
!39
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
!40
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
!41
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
42
Tiger: Desugaring
!43
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
!44
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
!45
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
46
Tiger: Outline View
!47
Tiger: Outline View Builder
!48
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
!49
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
!50
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
51
Tiger: Completion Rules
!52
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
Rewriting =
Matching & Building
53
!54
!55
!56
!57
!58
!59
!60
!61
!62
!63
!64
!65
!66
!67
!68
!69
!70
Combining Rewrite Rules
with Strategies
71
!72
!73
!74
!75
!76
!77
!78
!79
!80
!81
!82
!83
Parameterized
Rewrite Rules
84
f(x,y|a,b): lhs -> rhs
- strategy or rule parameters x,y

- term parameters a,b

- no matching

f(|a,b): lhs -> rhs
- optional strategy parameters

f(x,y): lhs -> rhs
- optional term parameters

f: lhs -> rhs
!85
Parameterized Rewrite Rules
Parameterized Rewrite Rules: Map
!86
[ 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
!87
[ 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
!88
[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
!89
[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
Traversal Strategies
90
!91
!92
!93
!94
!95
!96
!97
!98
!99
!100
!101
!102
!103
!104
Traversal Combinators
105
!106
!107
!108
!109
!110
!111
!112
Traversal: Topdown
!113
Const
Mul
Const
3 4 5
Const
Add1
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
topdown(s) = s ; all(topdown(s))
topdown(switch)
Traversal: Topdown
!114
Mul
Const
3
Const
4 5
Const
Add1
2
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
topdown(s) = s ; all(topdown(s))
topdown(switch)
Traversal: Topdown
!115
Mul
Const
3
Const
5 4
Const
Add1
2
3
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
topdown(s) = s ; all(topdown(s))
topdown(switch)
Traversal: Topdown/Try
!116
Const
Mul
Const
3 4 5
Const
Add1
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
topdown(s) = s ; all(topdown(s))
topdown(try(switch))
Traversal: Topdown/Try
!117
Mul
Const
3
Const
4 5
Const
Add1
2
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
topdown(s) = s ; all(topdown(s))
topdown(try(switch))
Traversal: Topdown/Try
!118
Mul
Const
3
Const
5 4
Const
Add1
2
3
4
5
6
7
8
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
topdown(s) = s ; all(topdown(s))
topdown(try(switch))
Traversal: Alltd
!119
Const
Mul
Const
3 4 5
Const
Add1
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
alltd(s) = s <+ all(alltd(s))
alltd(switch)
Traversal: Alltd
!120
Mul
Const
3
Const
4 5
Const
Add1
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
alltd(s) = s <+ all(alltd(s))
alltd(switch)
Traversal: bottomup
!121
Const
Mul
Const
3 4 5
Const
Add1
2
3
4
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(switch)
Traversal: Bottomup
!122
Const
Mul
Const
3 4 5
Const
Add1
2
3
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(try(switch))
Traversal: Bottomup
!123
Const
Mul
Const
3 4 5
Const
Add1
2
3
4
5
6
7
8
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(try(switch))
Traversal: Bottomup
!124
Const
Mul
Const
3 4 5
Const
Add1
2
3
4
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(try(switch))
Traversal: Bottomup
!125
Const
Mul
Const
3 5 4
Const
Add1
2
3
4
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(try(switch))
Traversal: Bottomup
!126
Const
Mul
Const
3 5 4
Const
Add1
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(try(switch))
Traversal: Bottomup
!127
Mul
Const
3
Const
5 4
Const
Add1
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
bottomup(s) = all(bottomup(s)) ; s
bottomup(try(switch))
!128
!129
Traversal: Innermost
!130
Const
Mul
Const
3 4 5
Const
Add1
2
3
4
5
6
7
8
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
innermost(s) = bottomup(try(s ; innermost(s)))
innermost(switch)
Traversal: Innermost
!131
Const
Mul
Const
3 4 5
Const
Add1
2
3
4
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
innermost(s) = bottomup(try(s ; innermost(s)))
innermost(switch)
Traversal: Innermost
!132
Const
Mul
Const
3 5 4
Const
Add1
2
3
4
9
10
11
12
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
innermost(s) = bottomup(try(s ; innermost(s)))
innermost(switch)
Traversal: Innermost
!133
Const
Mul
Const
3 5 4
Const
Add1
2
3
4
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
innermost(s) = bottomup(try(s ; innermost(s)))
innermost(switch)
Traversal: Innermost
!134
Const
Mul
Const
3 4 5
Const
Add1
2
3
4
switch: Add(e1, e2) -> Add(e2, e1)
switch: Mul(e1, e2) -> Mul(e2, e1)
innermost(s) = bottomup(try(s ; innermost(s)))
innermost(switch)
!135
!136
!137
!138
!139
!140
Type-Unifying
Transformations
141
!142
!143
!144
!145
!146
!147
!148
!149
!150
!151
!152
!153
!154
!155
!156
!157
!158
!159
!160
!161
!162
!163
!164
!165
!166
!167
!168
!169
!170
!171
!172
!173
Next: Type Checking
174
!175
Except where otherwise noted, this work is licensed under

More Related Content

What's hot (20)

PDF
Declare Your Language: Name Resolution
Eelco Visser
 
PDF
Declare Your Language: Type Checking
Eelco Visser
 
PDF
Declare Your Language: Transformation by Strategic Term Rewriting
Eelco Visser
 
PDF
Compiler Construction | Lecture 2 | Declarative Syntax Definition
Eelco Visser
 
PDF
Compiler Construction | Lecture 14 | Interpreters
Eelco Visser
 
PDF
Declarative Type System Specification with Statix
Eelco Visser
 
PDF
Compiler Construction | Lecture 4 | Parsing
Eelco Visser
 
PDF
CS4200 2019 | Lecture 2 | syntax-definition
Eelco Visser
 
PDF
Compiler Construction | Lecture 6 | Introduction to Static Analysis
Eelco Visser
 
PDF
Declare Your Language: Syntactic (Editor) Services
Eelco Visser
 
PDF
Declarative Semantics Definition - Term Rewriting
Guido Wachsmuth
 
PDF
Programming languages
Eelco Visser
 
PPT
Lex (lexical analyzer)
Sami Said
 
PDF
Term Rewriting
Eelco Visser
 
PDF
Writing Parsers and Compilers with PLY
David Beazley (Dabeaz LLC)
 
PDF
Dynamic Semantics
Eelco Visser
 
PPTX
Introduction of flex
vip_du
 
PDF
Dynamic Semantics Specification and Interpreter Generation
Eelco Visser
 
PPTX
Introduction of bison
vip_du
 
PDF
Introduction - Imperative and Object-Oriented Languages
Guido Wachsmuth
 
Declare Your Language: Name Resolution
Eelco Visser
 
Declare Your Language: Type Checking
Eelco Visser
 
Declare Your Language: Transformation by Strategic Term Rewriting
Eelco Visser
 
Compiler Construction | Lecture 2 | Declarative Syntax Definition
Eelco Visser
 
Compiler Construction | Lecture 14 | Interpreters
Eelco Visser
 
Declarative Type System Specification with Statix
Eelco Visser
 
Compiler Construction | Lecture 4 | Parsing
Eelco Visser
 
CS4200 2019 | Lecture 2 | syntax-definition
Eelco Visser
 
Compiler Construction | Lecture 6 | Introduction to Static Analysis
Eelco Visser
 
Declare Your Language: Syntactic (Editor) Services
Eelco Visser
 
Declarative Semantics Definition - Term Rewriting
Guido Wachsmuth
 
Programming languages
Eelco Visser
 
Lex (lexical analyzer)
Sami Said
 
Term Rewriting
Eelco Visser
 
Writing Parsers and Compilers with PLY
David Beazley (Dabeaz LLC)
 
Dynamic Semantics
Eelco Visser
 
Introduction of flex
vip_du
 
Dynamic Semantics Specification and Interpreter Generation
Eelco Visser
 
Introduction of bison
vip_du
 
Introduction - Imperative and Object-Oriented Languages
Guido Wachsmuth
 

Similar to Compiler Construction | Lecture 5 | Transformation by Term Rewriting (20)

PDF
Declarative Language Definition
Eelco Visser
 
PDF
Grammarware Memes
Eelco Visser
 
PDF
Scope Graphs: A fresh look at name binding in programming languages
Eelco Visser
 
PDF
Declare Your Language (at DLS)
Eelco Visser
 
PDF
The Magnificent Seven
Mike Fogus
 
PDF
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...
Eelco Visser
 
KEY
Verification with LoLA: 2 The LoLA Input Language
Universität Rostock
 
PDF
Declare Your Language: Dynamic Semantics
Eelco Visser
 
PDF
SWP - A Generic Language Parser
kamaelian
 
PDF
Control structure
baran19901990
 
PDF
Static name resolution
Eelco Visser
 
KEY
Programming Haskell Chapter8
Kousuke Ruichi
 
PDF
Name binding with scope graphs
Eelco Visser
 
PPT
Lexical analysis, syntax analysis, semantic analysis. Ppt
ovidlivi91
 
PDF
Lecture4
mahendraranwa9
 
PDF
Model-Driven Software Development - Language Workbenches & Syntax Definition
Eelco Visser
 
PPT
SS & CD Module 3
ShwetaNirmanik
 
PPT
Module 2
ShwetaNirmanik
 
PDF
Compiling fµn language
Didier Plaindoux
 
Declarative Language Definition
Eelco Visser
 
Grammarware Memes
Eelco Visser
 
Scope Graphs: A fresh look at name binding in programming languages
Eelco Visser
 
Declare Your Language (at DLS)
Eelco Visser
 
The Magnificent Seven
Mike Fogus
 
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...
Eelco Visser
 
Verification with LoLA: 2 The LoLA Input Language
Universität Rostock
 
Declare Your Language: Dynamic Semantics
Eelco Visser
 
SWP - A Generic Language Parser
kamaelian
 
Control structure
baran19901990
 
Static name resolution
Eelco Visser
 
Programming Haskell Chapter8
Kousuke Ruichi
 
Name binding with scope graphs
Eelco Visser
 
Lexical analysis, syntax analysis, semantic analysis. Ppt
ovidlivi91
 
Lecture4
mahendraranwa9
 
Model-Driven Software Development - Language Workbenches & Syntax Definition
Eelco Visser
 
SS & CD Module 3
ShwetaNirmanik
 
Module 2
ShwetaNirmanik
 
Compiling fµn language
Didier Plaindoux
 
Ad

More from Eelco Visser (13)

PDF
CS4200 2019 Lecture 1: Introduction
Eelco Visser
 
PDF
A Direct Semantics of Declarative Disambiguation Rules
Eelco Visser
 
PDF
Compiler Construction | Lecture 17 | Beyond Compiler Construction
Eelco Visser
 
PDF
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Eelco Visser
 
PDF
Compiler Construction | Lecture 15 | Memory Management
Eelco Visser
 
PDF
Compiler Construction | Lecture 13 | Code Generation
Eelco Visser
 
PDF
Compiler Construction | Lecture 11 | Monotone Frameworks
Eelco Visser
 
PDF
Compiler Construction | Lecture 10 | Data-Flow Analysis
Eelco Visser
 
PDF
Compiler Construction | Lecture 7 | Type Checking
Eelco Visser
 
PDF
Compiler Construction | Lecture 1 | What is a compiler?
Eelco Visser
 
PDF
Declare Your Language: Virtual Machines & Code Generation
Eelco Visser
 
PDF
Declare Your Language: Constraint Resolution 2
Eelco Visser
 
PDF
Declare Your Language: Constraint Resolution 1
Eelco Visser
 
CS4200 2019 Lecture 1: Introduction
Eelco Visser
 
A Direct Semantics of Declarative Disambiguation Rules
Eelco Visser
 
Compiler Construction | Lecture 17 | Beyond Compiler Construction
Eelco Visser
 
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Eelco Visser
 
Compiler Construction | Lecture 15 | Memory Management
Eelco Visser
 
Compiler Construction | Lecture 13 | Code Generation
Eelco Visser
 
Compiler Construction | Lecture 11 | Monotone Frameworks
Eelco Visser
 
Compiler Construction | Lecture 10 | Data-Flow Analysis
Eelco Visser
 
Compiler Construction | Lecture 7 | Type Checking
Eelco Visser
 
Compiler Construction | Lecture 1 | What is a compiler?
Eelco Visser
 
Declare Your Language: Virtual Machines & Code Generation
Eelco Visser
 
Declare Your Language: Constraint Resolution 2
Eelco Visser
 
Declare Your Language: Constraint Resolution 1
Eelco Visser
 
Ad

Recently uploaded (20)

PDF
Applitools Platform Pulse: What's New and What's Coming - July 2025
Applitools
 
PPT
Brief History of Python by Learning Python in three hours
adanechb21
 
PDF
How to Download and Install ADT (ABAP Development Tools) for Eclipse IDE | SA...
SAP Vista, an A L T Z E N Company
 
PPT
Activate_Methodology_Summary presentatio
annapureddyn
 
PDF
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
PDF
AI Image Enhancer: Revolutionizing Visual Quality”
docmasoom
 
PDF
AWS_Agentic_AI_in_Indian_BFSI_A_Strategic_Blueprint_for_Customer.pdf
siddharthnetsavvies
 
PDF
Step-by-Step Guide to Install SAP HANA Studio | Complete Installation Tutoria...
SAP Vista, an A L T Z E N Company
 
PDF
Salesforce Pricing Update 2025: Impact, Strategy & Smart Cost Optimization wi...
GetOnCRM Solutions
 
PPTX
Presentation about variables and constant.pptx
kr2589474
 
PDF
On Software Engineers' Productivity - Beyond Misleading Metrics
Romén Rodríguez-Gil
 
PDF
New Download MiniTool Partition Wizard Crack Latest Version 2025
imang66g
 
PDF
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
PDF
What companies do with Pharo (ESUG 2025)
ESUG
 
PDF
Supabase Meetup: Build in a weekend, scale to millions
Carlo Gilmar Padilla Santana
 
PDF
Infrastructure planning and resilience - Keith Hastings.pptx.pdf
Safe Software
 
PDF
Download iTop VPN Free 6.1.0.5882 Crack Full Activated Pre Latest 2025
imang66g
 
PDF
How Agentic AI Networks are Revolutionizing Collaborative AI Ecosystems in 2025
ronakdubey419
 
PDF
Virtual Threads in Java: A New Dimension of Scalability and Performance
Tier1 app
 
PPT
Why Reliable Server Maintenance Service in New York is Crucial for Your Business
Sam Vohra
 
Applitools Platform Pulse: What's New and What's Coming - July 2025
Applitools
 
Brief History of Python by Learning Python in three hours
adanechb21
 
How to Download and Install ADT (ABAP Development Tools) for Eclipse IDE | SA...
SAP Vista, an A L T Z E N Company
 
Activate_Methodology_Summary presentatio
annapureddyn
 
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
AI Image Enhancer: Revolutionizing Visual Quality”
docmasoom
 
AWS_Agentic_AI_in_Indian_BFSI_A_Strategic_Blueprint_for_Customer.pdf
siddharthnetsavvies
 
Step-by-Step Guide to Install SAP HANA Studio | Complete Installation Tutoria...
SAP Vista, an A L T Z E N Company
 
Salesforce Pricing Update 2025: Impact, Strategy & Smart Cost Optimization wi...
GetOnCRM Solutions
 
Presentation about variables and constant.pptx
kr2589474
 
On Software Engineers' Productivity - Beyond Misleading Metrics
Romén Rodríguez-Gil
 
New Download MiniTool Partition Wizard Crack Latest Version 2025
imang66g
 
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
What companies do with Pharo (ESUG 2025)
ESUG
 
Supabase Meetup: Build in a weekend, scale to millions
Carlo Gilmar Padilla Santana
 
Infrastructure planning and resilience - Keith Hastings.pptx.pdf
Safe Software
 
Download iTop VPN Free 6.1.0.5882 Crack Full Activated Pre Latest 2025
imang66g
 
How Agentic AI Networks are Revolutionizing Collaborative AI Ecosystems in 2025
ronakdubey419
 
Virtual Threads in Java: A New Dimension of Scalability and Performance
Tier1 app
 
Why Reliable Server Maintenance Service in New York is Crucial for Your Business
Sam Vohra
 

Compiler Construction | Lecture 5 | Transformation by Term Rewriting

  • 1. Eelco Visser CS4200 Compiler Construction TU Delft September 2018 Lecture 5: Transformation by Term Rewriting
  • 2. No deadlines - There are no deadlines for homework - I have removed the ‘advisory’ deadlines - Make at your own pace; but important to prepare for exam Reading material on parsing - Read sections 4.1, 4.2, 4.3, 4.5, 4.6 of ‘Dragon’ book - In particular: FIRST and FOLLOW set, constructing SLR table New assignments - Week 1.2: templates, completion - Week 1.3: LR parsing Slides on parsing extended with more examples !2 Notes on Homework
  • 3. Would you be interested in peer review of homework assignments? 3
  • 4. Channel on research group Slack Where many Spoofax users hang out Ask questions about Spoofax (Not answers to assignments) No guarantee to quick response, or answer at all Send me an email if you want an invitation !4 #spoofax-users
  • 6. Reading Material 6 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.
  • 7. !7 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
  • 8. !8 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
  • 9. !9 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 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.
  • 10. !10 Documentation for Stratego at the metaborg.org website. http://www.metaborg.org/en/latest/source/langdev/meta/lang/stratego/index.html
  • 11. !11 This paper defines the formal semantics of the full Stratego language, including its scoped dynamic rules feature. If you want to dig deeper These slides document most features of the base language without dynamic rules and without giving the formal semantics.
  • 12. Transformation Architecture 12 This presentation uses the Stratego Shell for explaining the behavior of Stratego programs. The Stratego Shell is currently not supported by Spoofax
  • 13. !13
  • 14. !14
  • 15. !15
  • 16. !16
  • 17. !17
  • 18. !18
  • 19. !19
  • 20. !20
  • 21. !21
  • 23. Parsing: From Text to Terms !23 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
  • 24. Syntax of Terms !24 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()))
  • 25. Syntax of Terms !25 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()]
  • 26. 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 !26 0 1 [A(), B()] Var(“x”) Let( [ Decl(“x”, IntT()), Decl(“y”, BoolT()) ] , Eq(Var(“x”), Int(0)) )
  • 27. Syntax of A(nnotated) Terms !27 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())}
  • 29. Signatures !29 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 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
  • 31. Desugaring !31 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 if x then printint(x)
  • 32. More Desugaring !32 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")) 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
  • 33. Constant Folding !33 x := 21 + 21 + x eval: 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") ) )
  • 34. More Constant Folding !34 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))
  • 36. Spoofax Builders !36 rules build : (node, _, ast, path, project-path) -> result with <some-transformation> ast => result Builder gets AST as parameter
  • 37. Tiger: AST Builder !37 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
  • 39. Tiger: Formatting Builder !39 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
  • 40. Tiger: Parenthesize !40 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 > …
  • 41. Tiger: Pretty-Print Rules !41 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
  • 43. Tiger: Desugaring !43 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++
  • 44. Tiger: Desugaring Builder !44 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
  • 45. Tiger: Desugaring Transformation !45 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"))) ] ) ) ] )
  • 48. Tiger: Outline View Builder !48 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
  • 49. Tiger: Outline View Rules !49 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.
  • 50. Outline View: Generic Strategy !50 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
  • 52. Tiger: Completion Rules !52 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
  • 53. Rewriting = Matching & Building 53
  • 54. !54
  • 55. !55
  • 56. !56
  • 57. !57
  • 58. !58
  • 59. !59
  • 60. !60
  • 61. !61
  • 62. !62
  • 63. !63
  • 64. !64
  • 65. !65
  • 66. !66
  • 67. !67
  • 68. !68
  • 69. !69
  • 70. !70
  • 72. !72
  • 73. !73
  • 74. !74
  • 75. !75
  • 76. !76
  • 77. !77
  • 78. !78
  • 79. !79
  • 80. !80
  • 81. !81
  • 82. !82
  • 83. !83
  • 85. f(x,y|a,b): lhs -> rhs - strategy or rule parameters x,y - term parameters a,b - no matching f(|a,b): lhs -> rhs - optional strategy parameters f(x,y): lhs -> rhs - optional term parameters f: lhs -> rhs !85 Parameterized Rewrite Rules
  • 86. Parameterized Rewrite Rules: Map !86 [ 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]
  • 87. Parameterized Rewrite Rules: Zip !87 [ 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)
  • 88. Parameterized Rewrite Rules: Fold !88 [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)
  • 89. Parameterized Rewrite Rules: Inverse !89 [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
  • 91. !91
  • 92. !92
  • 93. !93
  • 94. !94
  • 95. !95
  • 96. !96
  • 97. !97
  • 98. !98
  • 99. !99
  • 100. !100
  • 101. !101
  • 102. !102
  • 103. !103
  • 104. !104
  • 106. !106
  • 107. !107
  • 108. !108
  • 109. !109
  • 110. !110
  • 111. !111
  • 112. !112
  • 113. Traversal: Topdown !113 Const Mul Const 3 4 5 Const Add1 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) topdown(s) = s ; all(topdown(s)) topdown(switch)
  • 114. Traversal: Topdown !114 Mul Const 3 Const 4 5 Const Add1 2 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) topdown(s) = s ; all(topdown(s)) topdown(switch)
  • 115. Traversal: Topdown !115 Mul Const 3 Const 5 4 Const Add1 2 3 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) topdown(s) = s ; all(topdown(s)) topdown(switch)
  • 116. Traversal: Topdown/Try !116 Const Mul Const 3 4 5 Const Add1 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) topdown(s) = s ; all(topdown(s)) topdown(try(switch))
  • 117. Traversal: Topdown/Try !117 Mul Const 3 Const 4 5 Const Add1 2 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) topdown(s) = s ; all(topdown(s)) topdown(try(switch))
  • 118. Traversal: Topdown/Try !118 Mul Const 3 Const 5 4 Const Add1 2 3 4 5 6 7 8 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) topdown(s) = s ; all(topdown(s)) topdown(try(switch))
  • 119. Traversal: Alltd !119 Const Mul Const 3 4 5 Const Add1 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) alltd(s) = s <+ all(alltd(s)) alltd(switch)
  • 120. Traversal: Alltd !120 Mul Const 3 Const 4 5 Const Add1 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) alltd(s) = s <+ all(alltd(s)) alltd(switch)
  • 121. Traversal: bottomup !121 Const Mul Const 3 4 5 Const Add1 2 3 4 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(switch)
  • 122. Traversal: Bottomup !122 Const Mul Const 3 4 5 Const Add1 2 3 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(try(switch))
  • 123. Traversal: Bottomup !123 Const Mul Const 3 4 5 Const Add1 2 3 4 5 6 7 8 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(try(switch))
  • 124. Traversal: Bottomup !124 Const Mul Const 3 4 5 Const Add1 2 3 4 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(try(switch))
  • 125. Traversal: Bottomup !125 Const Mul Const 3 5 4 Const Add1 2 3 4 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(try(switch))
  • 126. Traversal: Bottomup !126 Const Mul Const 3 5 4 Const Add1 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(try(switch))
  • 127. Traversal: Bottomup !127 Mul Const 3 Const 5 4 Const Add1 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) bottomup(s) = all(bottomup(s)) ; s bottomup(try(switch))
  • 128. !128
  • 129. !129
  • 130. Traversal: Innermost !130 Const Mul Const 3 4 5 Const Add1 2 3 4 5 6 7 8 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) innermost(s) = bottomup(try(s ; innermost(s))) innermost(switch)
  • 131. Traversal: Innermost !131 Const Mul Const 3 4 5 Const Add1 2 3 4 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) innermost(s) = bottomup(try(s ; innermost(s))) innermost(switch)
  • 132. Traversal: Innermost !132 Const Mul Const 3 5 4 Const Add1 2 3 4 9 10 11 12 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) innermost(s) = bottomup(try(s ; innermost(s))) innermost(switch)
  • 133. Traversal: Innermost !133 Const Mul Const 3 5 4 Const Add1 2 3 4 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) innermost(s) = bottomup(try(s ; innermost(s))) innermost(switch)
  • 134. Traversal: Innermost !134 Const Mul Const 3 4 5 Const Add1 2 3 4 switch: Add(e1, e2) -> Add(e2, e1) switch: Mul(e1, e2) -> Mul(e2, e1) innermost(s) = bottomup(try(s ; innermost(s))) innermost(switch)
  • 135. !135
  • 136. !136
  • 137. !137
  • 138. !138
  • 139. !139
  • 140. !140
  • 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
  • 155. !155
  • 156. !156
  • 157. !157
  • 158. !158
  • 159. !159
  • 160. !160
  • 161. !161
  • 162. !162
  • 163. !163
  • 164. !164
  • 165. !165
  • 166. !166
  • 167. !167
  • 168. !168
  • 169. !169
  • 170. !170
  • 171. !171
  • 172. !172
  • 173. !173
  • 175. !175 Except where otherwise noted, this work is licensed under