Tree Oriented Programming. Jeroen Fokker

Similar documents
INTRODUCTION TO HASKELL

Introduction to Functional Programming in Haskell 1 / 56

A general introduction to Functional Programming using Haskell

Haskell 98 in short! CPSC 449 Principles of Programming Languages

Haskell Introduction Lists Other Structures Data Structures. Haskell Introduction. Mark Snyder

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

CS 457/557: Functional Languages

CITS3211 FUNCTIONAL PROGRAMMING. 6. Folding operators

An introduction introduction to functional functional programming programming using usin Haskell

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

These notes are intended exclusively for the personal usage of the students of CS352 at Cal Poly Pomona. Any other usage is prohibited without

CSC312 Principles of Programming Languages : Functional Programming Language. Copyright 2006 The McGraw-Hill Companies, Inc.

Haskell Overview II (2A) Young Won Lim 8/9/16

Practical Haskell. An introduction to functional programming. July 21, Practical Haskell. Juan Pedro Villa-Isaza. Introduction.

Haskell Overview II (2A) Young Won Lim 8/23/16

Functional Programming and Haskell

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Haskell Functions

It is better to have 100 functions operate one one data structure, than 10 functions on 10 data structures. A. Perlis

Haskell Overview II (2A) Young Won Lim 9/26/16

Haskell 101. (Version 1 (July 18, 2012)) Juan Pedro Villa Isaza

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

PROGRAMMING IN HASKELL. Chapter 5 - List Comprehensions

CSCE 314 Programming Languages

CSE 3302 Programming Languages Lecture 8: Functional Programming

Thoughts on Assignment 4 Haskell: Flow of Control

Lecture 19: Functions, Types and Data Structures in Haskell

(ii) Define a function ulh that takes a list xs, and pairs each element with all other elements in xs.

INTRODUCTION TO FUNCTIONAL PROGRAMMING

Lecture 4: Higher Order Functions

Shell CSCE 314 TAMU. Functions continued

Lecture C-10: Parser Combinators - Introduction

PROGRAMMING IN HASKELL. CS Chapter 6 - Recursive Functions

Recap: Functions as first-class values

CSCE 314 Programming Languages

Overview. Declarative Languages D7012E. Overloading. Overloading Polymorphism Subtyping

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example

PROGRAMMING IN HASKELL. Chapter 2 - First Steps

Haskell: Lists. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Friday, February 24, Glenn G.

CSCE 314 Programming Languages. Functional Parsers

Processadors de Llenguatge II. Functional Paradigm. Pratt A.7 Robert Harper s SML tutorial (Sec II)

Course year Typeclasses and their instances

CPS 506 Comparative Programming Languages. Programming Language Paradigm

Monad Background (3A) Young Won Lim 11/8/17

301AA - Advanced Programming

CSci 450: Org. of Programming Languages Overloading and Type Classes

Introduction to Functional Programming

COP 3402 Systems Software Syntax Analysis (Parser)

Functional abstraction. What is abstraction? Eating apples. Readings: HtDP, sections Language level: Intermediate Student With Lambda

Functional abstraction

Functional Programming in Haskell Part I : Basics

Standard prelude. Appendix A. A.1 Classes

CSc 372 Comparative Programming Languages

Monad Background (3A) Young Won Lim 11/18/17

Programming Language Concepts, CS2104 Lecture 7

Introduction to Haskell

Lecture 2: List algorithms using recursion and list comprehensions

Higher Order Functions in Haskell

The Haskell HOP: Higher-order Programming

An introduction to functional programming. July 23, 2010

CS 4240: Compilers and Interpreters Project Phase 1: Scanner and Parser Due Date: October 4 th 2015 (11:59 pm) (via T-square)

CSc 372. Comparative Programming Languages. 8 : Haskell Function Examples. Department of Computer Science University of Arizona

Overloading, Type Classes, and Algebraic Datatypes

Parser Combinators 11/3/2003 IPT, ICS 1

INFOB3TC Solutions for the Exam

COMP 181. Prelude. Prelude. Summary of parsing. A Hierarchy of Grammar Classes. More power? Syntax-directed translation. Analysis

Applicative, traversable, foldable

Programming Languages Fall 2013

Haskell: From Basic to Advanced. Part 2 Type Classes, Laziness, IO, Modules

CSci 4223 Principles of Programming Languages

Programming with Math and Logic

Declarative Programming with Function Patterns

CSE 130: Programming Languages. Polymorphism. Ranjit Jhala UC San Diego

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Functional Parsers

Applicative, traversable, foldable

Chapter 15. Functional Programming Languages

Informatics 1 Functional Programming 19 Tuesday 23 November IO and Monads. Philip Wadler University of Edinburgh

Reasoning About Imperative Programs. COS 441 Slides 10

Monad Background (3A) Young Won Lim 10/5/17

CMSC330 Spring 2014 Midterm 2 Solutions

INTRODUCTION TO SCHEME

Talen en Compilers. Jurriaan Hage , period 2. November 13, Department of Information and Computing Sciences Utrecht University

CS 242. Fundamentals. Reading: See last slide

Programming Languages Fall Prof. Liang Huang

FUNCTIONAL AND LOGIC PROGRAMS

Functional Programming. Pure Functional Programming

EECS 700 Functional Programming

Haskell Making Our Own Types and Typeclasses

Functional Programming. Big Picture. Design of Programming Languages

CS664 Compiler Theory and Design LIU 1 of 16 ANTLR. Christopher League* 17 February Figure 1: ANTLR plugin installer

Principles of Programming Languages

Haskell through HUGS THE BASICS

Semantic analysis and intermediate representations. Which methods / formalisms are used in the various phases during the analysis?

To figure this out we need a more precise understanding of how ML works

The List Datatype. CSc 372. Comparative Programming Languages. 6 : Haskell Lists. Department of Computer Science University of Arizona

CS 320: Concepts of Programming Languages

CS 360: Programming Languages Lecture 10: Introduction to Haskell

Programming Lecture 3

A tour of the Haskell Prelude

CPS 506 Comparative Programming Languages. Syntax Specification

Undergraduate Compilers in a Day

Transcription:

Tree Oriented Programming Jeroen Fokker

Tree oriented programming Many problems are like: Input text transform process unparse Output text

Tree oriented programming Many problems are like: Input text parse transform prettyprint unparse Output text internal tree representation

Tree oriented programming tools should facilitate: Defining trees Parsing Transforming Prettyprinting

Mainstream approach to tree oriented programming Defining trees Parsing Transforming Prettyprinting OO programming language preprocessor clever hacking library

Our approach to tree oriented programming Defining trees Parsing Transforming Prettyprinting functional language Haskell library preprocessor library

This morning s programme A crash course in Functional programming using Haskell Defining trees in Haskell The parsing library Transforming trees using the UU Attribute Grammar Compiler Prettyprinting Epilogue: Research opportunities

Language evolution: Imperative & Functional 50 years ago Now Haskell

Part I A crash course in Functional programming using Haskell

Function definition fac :: Int Int fac n = product [1..n] Haskell static int fac (int n) { int count, res; res = 1; for (count=1; count<=n; count++) res *= count; return res; }

Definition forms Function fac :: Int Int fac n = product [1..n] Constant pi :: Float pi = 3.1415926535 Operator (!^! ) :: Int Int Int n!^! k = fac n / (fac k * fac (n-k))

Case distinction with guards abs :: Int Int abs x x>=0 x<0 = x = -x guards

Case distinction with patterns day :: Int String day 1 = Monday day 2 = Tuesday day 3 = Wednesday day 4 = Thursday day 5 = Friday day 6 = Saturday day 7 = Sunday constant as formal parameter!

Iteration fac :: Int Int fac n n==0 = 1 n>0 = n * fac (n-1) without using standard function product recursion

List: a built-in data structure List: 0 or more values of the same type empty list constant put in front operator [ ] :

Shorthand notation for lists enumeration [ 1, 3, 8, 2, 5] > 1 : [2, 3, 4] [1, 2, 3, 4] range [ 4.. 9 ] > 1 : [4..6] [1, 4, 5, 6]

Functions on lists sum :: [Int] Int sum [ ] = 0 sum (x:xs) = x + sum xs length :: [Int] Int length [ ] = 0 length (x:xs) = 1 + length xs patterns recursion

Standard library of functions on lists null ++ take > null [ ] True > [1,2] ++ [3,4,5] [1, 2, 3, 4, 5] > take 3 [2..10] [2, 3, 4] challenge: Define these functions, using pattern matching and recursion

Functions on lists null :: [a] Bool null [ ] = True null (x:xs) = False (++) :: [a] [a] [a] [ ] ++ ys = ys (x:xs) ++ ys = x : (xs++ys) take :: Int [a] [a] take 0 xs = [ ] take n [ ] = [ ] take n (x:xs) = x : take (n-1) xs

Polymorphic type Type involving type variables take :: Int [a] [a] Why did it take 10 years and 5 versions to put this in Java?

Functions as parameter Apply a function to all elements of a list map > map fac [1, 2, 3, 4, 5] [1, 2, 6, 24, 120] > map sqrt [1.0, 2.0, 3.0, 4.0] [1.0, 1.41421, 1.73205, 2.0] > map even [1.. 6] [False, True, False, True, False, True]

Challenge What is the type of map? map :: (a b) [a] [b] What is the definition of map? map f [ ] = map f (x:xs) = [ ] f x : map f xs

Another list function: filter Selects list elements that fulfill a given predicate > filter even [1.. 10] [2, 4, 6, 8, 10] filter :: (a Bool) [a] [a] filter p [ ] = [ ] filter p (x:xs) p x = x : filter p xs True = filter p xs

Higher order functions: repetitive pattern? Parameterize! product :: [Int] Int product [ ] = 1 product (x:xs) = x * product xs and :: [Bool] Bool and [ ] = True and (x:xs) = x && and xs sum :: [Int] Int sum [ ] = 0 sum (x:xs) = x + sum xs

Universal list traversal: foldr foldr :: (a b b) (a a a) b a [a] ba combining function start value foldr (#) e [ ] = foldr (#) e (x:xs)= e x # foldr (#) e xs

Partial parameterization foldr is a generalization of sum, product, and and... thus sum, product, and and are special cases of foldr product = foldr (*) 1 and = foldr (&&) True sum = foldr (+) 0 or = foldr ( ) False

Example: sorting (1/2) insert :: Ord a a [a] [a] insert e [ ] = [ e ] insert e (x:xs) e x = e : x : xs e x = x : insert e xs isort :: Ord a [a] [a] isort [ ] = [ ] isort (x:xs) = insert x (isort xs) isort = foldr insert [ ]

Example: sorting (2/2) qsort :: Ord a [a] [a] [a] qsort [ ] = [ ] qsort (x:xs) = qsort (filter (<x) xs) ++ [x] ++ qsort (filter ( x) xs) (Why don t they teach it like that in the algorithms course?)

Infinite lists repeat :: a [a] repeat x = x : repeat x > repeat 3 [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 replicate :: Int a [a] replicate n x = take n (repeat x) > concat (replicate 5 IPA ) IPA IPA IPA IPA IPA

Lazy evaluation Parameter evaluation is postponed until they are really needed Also for the (:) operator so only the part of the list that is needed is evaluated

Generic iteration iterate :: (a a) a [a] iterate f x = x : iterate f (f x) > iterate (+1) 3 [3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20

Convenient notations (borrowed from mathematics) Lambda abstraction \x x*x List comprehension [ x*y x [1..10], even x, y [1..x] ] for creating anonymous functions more intuitive than equivalent expression using map, filter & concat

Part II Defining trees in Haskell

Binary trees with internal labels 14 4 23 3 10 15 29 1 6 11 18 26 34 5 8 How would you do this in Java/C++/C# etc?

The OO approach to trees class Tree { private Tree left, right; private int value; // constructor public Tree(Tree al, Tree ar, int av) { left = al; right=ar; value=av; } } // leafs are represented as null

The OO approach to trees: binary trees with external labels class Tree { // empty superclass } class Leaf extends Tree { int value } class Node extends Tree { Tree left,right }

Functional approach to trees I need a polymorphic type and constructor functions Tree a Leaf :: a Tree a Node :: Tree a Tree a Tree a Haskell notation: data Tree a = Leaf a Node (Tree a) (Tree a)

Example Data types needed in a compiler for a simple imperative language data Stat = Assign Name Expr Call Name [Expr] If Expr Stat While Expr Stat Block [Stat] type Name = String data Expr = Const Int Var Name Form Expr Op Expr data Op = Plus Min Mul Div

Functions on trees In analogy to functions on lists length :: [a] Int length [ ] = 0 length (x:xs) = 1 + length xs we can define functions on trees size :: Tree a Int size (Leaf v) = 1 size (Node lef rit) = size lef + size rit

Challenge: write tree functions elem tests element occurrence in tree elem :: Eq a a Tree a Bool elem x (Leaf y) = x==y elem x (Node lef rit) = elem x lef elem x rit front collects all values in a list front :: Tree a [a] front (Leaf y) = [ y ] front (Node lef rit) = front lef ++ front rit

A generic tree traversal In analogy to foldr on lists foldr :: (a b b) -- for (:) b -- for [ ] [a] b we can define foldt on trees foldt :: (a b) -- for Leaf (b b b) -- for Node Tree a b

Challenge: rewrite elem and front using foldt foldt :: (a b) -- for Leaf (b b b) -- for Node Tree a b elem x (Leaf y) = x==y elem x (Node lef rit) = elem x lef elem x rit elem x = foldt (==x) ( ) front (Leaf y) = [ y ] front (Node lef rit) = front lef ++ front rit front = foldt (\y [y]) :[] ) (++) (++)

Part III A Haskell Parsing library

Approaches to parsing Mainstream approach (imperative) Special notation for grammars Preprocessor translates grammar to C/Java/ -YACC (Yet Another Compiler Compiler) -ANTLR (ANother Tool for Language Recognition) Our approach (functional) Library of grammar-manipulating functions

ANTLR generates Java from grammar Expr : Term ( PLUS Term MINUS Term ) * ; Term : NUMBER OPEN Expr CLOSE ; public void expr () { term (); loop1: while (true) { switch(sym) { case PLUS: match(plus); term (); break; case MINUS: match(minus); term (); break; default: break loop1; } } } public void term() { switch(sym) { case INT: match(number); break; case LPAREN: match(open); expr (); match(close); break; default: throw new ParseError(); } }

ANTLR: adding semantics Expr returns [int x=0] { int y; } : x= Term ( PLUS y= Term { x += y; } MINUS y= Term { x = y; } ) * ; Term returns [int x=0] : n: NUMBER { x = str2int(n.gettext(); } OPEN x= Expr CLOSE ; Yacc notation: { $$ += $1; }

A Haskell parsing library type Parser Building blocks symbol :: a satisfy :: (a Bool) Combinators epsilon :: Parser Parser Parser ( ) :: Parser Parser Parser ( ) :: Parser Parser Parser

A Haskell parsing library type Parser a b Building blocks symbol :: a satisfy :: (a Bool) Combinators start :: Parser a b [a] b epsilon :: Parser a () Parser a a Parser a a ( ) :: Parser a b Parser a b Parser a b ( ) :: Parser a b Parser a c Parser a (b,c) ( ) :: (b c) Parser a b Parser a c

Domainspecific Combinator Language vs. Library New notation and semantics Preprocessing phase What you got is all you get Familiar syntax, just new functions Link & go Extensible at will using existing function abstraction mechnism

Expression parser open = symbol ( close = symbol ) plus = symbol + minus = symbol data Tree = Leaf Int Node Tree Op Tree type Op = Char expr, term :: Parser Char Tree expr = Node term (plus minus) expr term term = Leaf number middle open expr close where middle (x,(y,z)) = y

Example of extensibility Shorthand open = symbol ( close = symbol ) Parameterized shorthand pack :: Parser a b Parser a b pack p = open p close middle New combinators many :: Parser a b Parser a [b]

The real type of ( ) How to combine b and c? ( ) :: Parser a b Parser a b Parser a b ( ) :: Parser a b Parser a c Parser a (b,c) ( ) :: (b c) Parser a b Parser a c ( ) ( ) :: Parser a b Parser a c (b c d) Parser a d :: Parser a (c d) Parser a c Parser a d pack p = open p close middle where middle x y z = y

Another parser example; design of a new combinator many :: Parser a b Parser a [b] many p = (\b bs b:bs) p many p (\e [ ]) epsilon many p = (:) p many p succeed [ ]

Challenge: parser combinator design EBNF * EBNF + Beyond EBNF many :: Parser a b Parser a [b] many1 :: Parser a b Parser a [b] sequence :: [ Parser a b ] Parser a [b] many1 p = sequence [ ] = sequence (p:ps) = (:) p many p sequence = foldr f (succeed []) where f p r = (:) p r succeed [ ] (:) p sequence ps

More parser combinators sequence :: [ Parser a b ] Parser a [b] choice :: [ Parser a b ] Parser a [b] listof :: Parser a b Parser a s Parser a [b] chain :: Parser a b Parser a (b b b) Parser a b choice = foldr ( ) fail listof p s = (:) p many ( ) separator (\s b b) s p

Example: Expressions with precedence data Expr = Con Int Var String Fun String [Expr] Expr :+: Expr Expr : : Expr Expr :*: Expr Expr :/: Expr Method call Parser should resolve precedences

Parser for Expressions (with precedence) expr = chain term ( (\o (:+:)) (symbol + ) (\o (: :)) (symbol ) ) term = chain fact ( (\o (:*:)) (symbol * ) (\o (:/:)) (symbol / ) ) fact = Con number pack expr Var name Fun name pack (listof expr (symbol, ) )

A programmers reflex: Generalize! expr = chain term ( (:+:) + (: :) ) term = chain fact ( (:*:) * (:/:) / ) gen ops next = chain next ( choice ops ) fact = basiccases pack expr

Expression parser (many precedence levels) expr = gen ops1 term1 term1= gen ops2 term2 term2= gen ops3 term3 term3= gen ops4 term4 term4= gen ops5 fact fact = basiccases pack expr expr = foldr gen fact [ops5,ops4,ops3,ops2,ops1] gen ops next = chain next ( choice ops )

Library implementation type Parser = String X type Parser b = String b polymorphic result type type Parser b = String (b, String) rest string type Parser a b = [a] (b, [a]) type Parser a b = [a] [ (b, [a]) ] polymorphic alfabet list of successes for ambiguity

Library implementation ( ) :: Parser a b Parser a b Parser a b (p q) xs = p xs ++ q xs ( ) :: Parser a (c d) Parser a c Parser a d (p q) xs = [ ( f c, zs ) (f,ys) p xs, (c,zs) q ys ] ( ) :: (b c) Parser a b Parser a c (f p) xs = [ ( f b, ys ) (b,ys) p xs ]

Part IV Techniques for Transforming trees

Data structure traversal In analogy to foldr on lists foldr :: (a b b) -- for (:) b -- for [ ] [a] b we can define foldt on binary trees foldt :: (a b) -- for Leaf (b b b) -- for Node Tree a b

Traversal of Expressions data Expr = Add Expr Expr Mul Expr Expr Con Int type ESem b = ( b b b, b b b, Int b ) folde :: (b b b) (b b b) (Int b) Expr b -- for Add -- for Mul -- for Con

Traversal of Expressions data Expr = Add Expr Expr Mul Expr Expr Con Int type ESem b = ( b b b, b b b, Int b ) folde :: ESem b Expr b folde (a,m,c) = f where f (Add e1 e2) = a (f e1) (f e2) f (Mul e1 e2) = m (f e1) (f e2) f (Con n) = c n

Using and defining Semantics data Expr = Add Expr Expr Mul Expr Expr Con Int type ESem b = ( b b b, b b b, Int b ) evalexpr :: Expr Int evalexpr = folde evalsem evalsem :: ESem Int evalsem = ( (+), (*), id )

Syntax and Semantics 3 + 4 * 5 parseexpr Add (Con 3) (Mul (Con 4) (Con 5)) = start p where p = 23 evalexpr = folde s where s = (,,, )

Multiple Semantics 3 + 4 * 5 parseexpr :: String Add (Con 3) (Mul (Con 4) (Con 5)) :: Expr evalexpr 23 = folde s where s = (,,, ) s::esem Int compileexpr Push 3 Push 4 Push 5 Apply (*) runcode :: Int :: Code Apply (+) = folde s where s = (,,, ) s::esem Code

A virtual machine What is machine code? type Code = [ Instr ] What is an instruction? data Instr = Push Int Apply (Int Int Int)

Compiler generates Code data Expr = Add Expr Expr Mul Expr Expr Con Int type ESem b = ( b b b, b b b, Int b ) evalexpr compexpr :: Expr Code Int evalexpr compexpr = folde compsem evalsem where evalsem compsem :: :: ESemInt Code evalsem compsem = = ( ((+) add, (*), mul, id, con ) ) mul :: Code Code Code mul c1 c2 = c1 ++ c2 ++ [Apply (*)] con n = [ Push n ]

Compiler correctness 3 + 4 * 5 parseexpr Add (Con 3) (Mul (Con 4) (Con 5)) evalexpr compileexpr 23 runcode Push 3 Push 4 Push 5 Apply (*) Apply (+) runcode (compileexpr e) = evalexpr e

runcode: virtual machine specification run :: Code Stack Stack run [ ] stack = stack run (instr:rest) stack = run rest ( exec instr stack ) exec :: Instr Stack Stack exec (Push x) stack = x : stack exec (Apply f) (x:y:stack) = f x y : stack runcode :: Code Int runcode prog = run prog [ ] hd ( )

Extending the example: variables and local def s data Expr = Add Expr Expr Mul Expr Expr Con Int Var String Def String Expr Expr type ESem b = ( b b b, b b b, Int b ), String b, String b b b ) evalexpr :: Expr Int evalexpr = folde evalsem where evalsem :: ESem Int evalsem = ( add, mul, con ), var, def )

Any semantics for Expression add :: b b b add x y = mul :: b b b mul x y = con :: Int b con n = var :: String b var x = def :: String b b b def x d b =

Evaluation semantics for Expression add :: b b b add x y = x + y Int Int (Env Int) mul :: b b b mul x y = x * y Int Int (Env Int) con :: Int b con n = n var :: String b var x = Int Int def :: String Int b Int b b def x d b = Int

Evaluation semantics for Expression add :: b b b add x y = x + y Int Int (Env Int) mul :: b b b mul x y = x * y Int Int (Env Int) con :: Int b con n = n (Env Int) var :: String b var x = \e lookup e x (Env Int) def :: String Int b Int b b def x d b = (EnvInt

Evaluation semantics for Expression add ::(Env Int) b (Env Int) b b add x y = \e x e + y e Int Int (Env Int) mul :: (Env Int) b (Env Int) b b mul x y = \e x e * y e Int Int (Env Int) con :: Int b con n = \e n (Env Int) var :: String b var x = \e lookup e x (Env Int) def :: String (Env Int) b (Env Int) b b def x d b = \e b ((x,d e) : e ) (Env Int)

Extending the virtual machine What is machine code? type Code = [ Instr ] What is an instruction? data Instr = Push Int data Instr Push Int Apply (Int Int Int) Apply (Int Int Int) Load Adress Store Adress

Compilation semantics for Expression add ::(Env Code) b (Env Code) b Env b Code add x y = \e x e ++ y e ++ [Apply (+)] mul ::(Env Code) b (Env Code) b Env b Code mul x y = \e x e ++ y e ++ [Apply (*)] con :: Int b con n = \e [Push n] Env Code var :: String b var x = \e [Load (lookup e x)] Env Code where a = length e def :: String (Env Code) b (Env Code) b Env b Code def x d b = \e d e++ [Store a]++ b ((x,a) : e )

Language: syntax and semantics data Expr = Add Expr Expr Mul Expr Expr Con Int Var String Def String Expr Expr type ESem b = ( b b b, b b b, Int b, String b, String b b b ) compsem :: ESem (Env Code) compsem = (f1, f2, f3, f4, f5) where compile t = folde compsem t [ ]

Language: syntax and semantics data Expr = Add Expr Expr Mul Expr Expr Con Int Var String data DefStat String Expr Expr = Assign String Expr While Expr Stat If Expr Stat Stat Block [Stat] type ESem b c = ( ( b b b, b b b, Int b, String b,) String b b b, () String b c, b c c, b c c c, [ c ] c ) ) compsem :: ESem (Env Code) (Env Code) compsem = (f1, ((f1, f2, f3, f4, f4), f5) (f5, where f6, f7, f8)) compile t = folde compsem t [ ]

Real-size example data Module = data Class = data Method = data Stat = data Expr = data Decl = data Type = type ESem a b c d e f = ( (,, ), (,...), (,,,,, ), compsem :: ESem ( ) ( ) ( ) Attributes that are passed ( ) top-down ( ) ( ) ( ) compsem = ( dozens of functions ) Attributes that are generated bottom-up

Tree semantics generated by Attribute Grammar data Expr = Add Expr Expr Var String codesem = ( \ a b \ e a e ++ b e ++ [Apply (+)], \ x \ e [Load (lookup e x)], DATA Expr = Add a: Expr b: Expr Var x: String ATTR Expr inh e: Env syn c: Code Explicit names for fields and attributes SEM Expr Add this.code = a.code ++ b.code ++ [Apply (+)] a.e = this.e b.e = this.e Var this.code = [Load (lookup e x)] Attribute value equations instead of functions

UU-AGC Attribute Grammar Compiler Preprocessor to Haskell Takes: Attribute grammar Attribute value definitions Generates: datatype, fold function and Sem type Semantic function (many-tuple of functions) Automatically inserts trival def s a.e = this.e

UU-AGC Attribute Grammar Compiler Advantages: Very intuitive view on trees no need to handle 27-tuples of functions Still full Haskell power in attribute def s Attribute def s can be arranged modularly No need to write trivial attribute def s Disadvantages: Separate preprocessing phase

Part IV Pretty printing

Tree oriented programming Input text parse transform prettyprint Output text internal tree representation

Prettyprinting is just another tree transformation Example: transformation from Stat to String DATA Stat = Assign a: Expr b: Expr While e: Expr s: Stat Block body: [Stat] ATTR Expr Stat [Stat] syn code: String inh indent: Int SEM Stat Assign this.code = x.code ++ = ++ e.code ++ ; While this.code = while ( ++ e.code ++ ) ++ s.code Block this.code = { ++ body.code ++ } SEM Stat While s.indent = this.indent + 4 But how to handle newlines & indentation?

A combinator library for prettyprinting Type Building block Combinators type PPDoc text :: String PPDoc Observer (> <) :: PPDoc PPDoc PPDoc (> <) :: PPDoc PPDoc PPDoc indent :: Int PPDoc PPDoc render :: Int PPDoc String

Epilogue Research opportunities

Research opportunities (1/4) Parsing library: API-compatible to naïve library, but With error-recovery etc. Optimized Implemented using the Attribute Grammar way of thinking

Research opportunities (2/4) UU - Attribute Grammar Compiler More automatical insertions Pass analysis optimisation

Research opportunities (3/4) A real large compiler (for Haskell) 6 intermediate datatypes 5 transformations + many more Learn about software engineering aspects of our methodology

Reasearch opportunities (4/4) Generate as much as possible with preprocessors Attribute Grammar Compiler Shuffle extract multiple views & docs from the same source Ruler generate proof rules checked & executable.rul.cag.ag.hs.o.exe