SlideShare ist ein Scribd-Unternehmen logo
1 von 52
Downloaden Sie, um offline zu lesen
TI1220 2012-2013
Concepts of Programming Languages
Eelco Visser / TU Delft
Lecture 9: Parsing & Interpretation
Syntax and Semantics
Names, Bindings, and Scopes
Storage
Data Types
Functional Programming
First-class Functions
Polymorphism
Traits & Type Parameterization
Parsing and Interpretation
Data Abstraction / Modular Programming
Functional Programming Redux
Concurrency
Concurrent Programming
Domain-Specific Languages
Quarter 3
Quarter 4
Basics of
Scala
JavaScript
C
eval(parse(exp)) == value
parser
interpreter
Syntax + Semantics
Parsing
“The syntax of a programming language is
the form of its expressions, statements,
and program units.”
Sebesta Ch3
let y = 3
in (let inc = fun(x){ x + y }
in (let y = 11
in (inc 2)))
let g = fun(f){ f(3) }
in (let h = fun(x){ x + 5 }
in (g h))
Example Language
Exp = Exp '+' Exp1 // addition
| Exp1
Exp1 = Exp1 Exp0 // function application
| Exp0
Exp0 = '(' Exp ') // parentheses
| 'fun' '(' ident ')' '{' // function literal
Exp
'}'
| 'let' ident '=' Exp // let binding
'in' Exp0
| ident // identifier
| number // number
Context-free Grammar
sealed abstract class Exp
case class Add(lhs: Exp, rhs: Exp) extends Exp
case class App(funExpr: Exp, arg: Exp) extends Exp
case class Fun(param: Symbol, body: Exp) extends Exp
case class Let(name: Symbol, bound: Exp, body: Exp) extends Exp
case class Id(name: Symbol) extends Exp
case class Num(n: Int) extends Exp
Exp = Exp '+' Exp1
| Exp1
Exp1 = Exp1 Exp0
| Exp0
Exp0 = '(' Exp ')
| 'fun' '(' ident ')' '{'
Exp
'}'
| 'let' ident '=' Exp
'in' Exp0
| ident
| number
From Concrete to
Abstract Syntax
Sentence AST
1 + 2 Add(Num(1),Num(2))
foo bar baz App(App(Id('foo), Id('bar)), Id('baz))
fun(foo){ bar baz } Fun('foo, App(Id('bar), Id('baz)))
fun(x){ x + 1 } Fun('x, Add(Id('x), Num(1)))
let inc = fun(x){
x + 1
}
in (inc 3)
Let('inc,
Fun('x, Add(Id('x), Num(1))),
App(Id('inc), Num(3)))
From Concrete to
Abstract Syntax
def parse(text: String): Exp
Parser
Approaches to constructing parsers
★ roll your own (recursive descent)
★ parser generator
★ parser combinators
Parser Combinators
Arithmetic Expressions
(1 + 4) * 7 / 34 - 3
expr ::= term { "+" term | "-" term }.
term ::= factor {"*" factor | "/" factor }.
factor ::= floatingPointNumber | "(" expr ")".
import scala.util.parsing.combinator._
class Arith extends JavaTokenParsers {
def expr: Parser[Any] = term~rep("+"~term | "-"~term)
def term: Parser[Any] = factor~rep("*"~factor | "/"~factor)
def factor: Parser[Any] = floatingPointNumber | "("~expr~")"
}
expr ::= term { "+" term | "-" term }.
term ::= factor {"*" factor | "/" factor }.
factor ::= floatingPointNumber | "(" expr ")".
Parser combinators
★ Sequential composition: p ~ q
★ Repetition: rep( p )
★ Alternative: p | q
Full API: http://www.scala-lang.org/api/current/index.html#scala.reflect.macros.Parsers
(1 + 4) * 7
[[1.12] parsed:
(((((~((1~List())~List((+~(4~List())))))~))~List((*~7)))~List())]
sealed abstract class Exp
case class Num(n: Double) extends Exp
case class Op(op: String, e: Exp) extends Exp
case class OpList(e: Exp, es: List[Exp]) extends Exp
import scala.util.parsing.combinator._
class Arith extends JavaTokenParsers {
def expr: Parser[Exp] =
term ~ rep( "+" ~> term ^^ { case e => Op("+", e) } ) ^^
{ case e~es => OpList(e, es) }
def term: Parser[Exp] =
factor ~ rep( "*" ~> factor ^^ { case e => Op("*", e) } ) ^^
{ case e~es => OpList(e, es) }
def factor: Parser[Exp] =
floatingPointNumber ^^ { case n => Num(n.toDouble) } |
"(" ~> expr <~ ")"
}
object ParseExpr extends Arith {
def parse(exp: String): Exp =
parseAll(expr, exp).get
}
Constructing ASTs
(1 + 3)
OpList(OpList(OpList(OpList(Num(1.0),List()),
List(Op(+,OpList(Num(3.0),List())))),List()),List())
sealed abstract class Exp
case class Num(n: Double) extends Exp
case class BinOp(op: String, l: Exp, r: Exp) extends Exp
import scala.util.parsing.combinator._
class Arith extends JavaTokenParsers {
def expr: Parser[Exp] =
expr ~ ("+" ~> term) ^^ { case e~t => BinOp("+", e, t) } | term
def term: Parser[Exp] =
term ~ ("*" ~> factor) ^^ { case e~t => BinOp("*", e, t) } | factor
def factor: Parser[Exp] =
floatingPointNumber ^^ { case n => Num(n.toDouble) } |
"(" ~> expr <~ ")"
}
(1 + 3)
Binary Productions
sealed abstract class Exp
case class Num(n: Double) extends Exp
case class BinOp(op: String, l: Exp, r: Exp) extends Exp
import scala.util.parsing.combinator._
class Arith extends JavaTokenParsers {
def expr: Parser[Exp] =
expr ~ ("+" ~> term) ^^ { case e~t => BinOp("+", e, t) } | term
def term: Parser[Exp] =
term ~ ("*" ~> factor) ^^ { case e~t => BinOp("*", e, t) } | factor
def factor: Parser[Exp] =
floatingPointNumber ^^ { case n => Num(n.toDouble) } |
"(" ~> expr <~ ")"
}
(1 + 3)
Status: RunningFailure
Test score: 0/-1
Binary Productions
sealed abstract class Exp
case class Num(n: Double) extends Exp
case class BinOp(op: String, l: Exp, r: Exp) extends Exp
import scala.util.parsing.combinator._
class Arith extends JavaTokenParsers with PackratParsers {
lazy val expr: PackratParser[Exp] =
expr ~ ("+" ~> term) ^^ { case e~t => BinOp("+", e, t) } | term
lazy val term: PackratParser[Exp] =
factor ~ ("*" ~> factor) ^^ { case e~t => BinOp("*", e, t) } | factor
lazy val factor: PackratParser[Exp] =
floatingPointNumber ^^ { case n => Num(n.toDouble) } |
"(" ~> expr <~ ")"
}
(1 + 4) * 7
BinOp(*,
BinOp(+,Num(1.0),Num(4.0)),
Num(7.0))
Packrat Parser
{
"address book": {
"name": "John Smith",
"address": {
"street": "10 Market Street",
"city" : "San Francisco, CA",
"zip" : 94111
},
"phone numbers": [
"408 3384238",
"408 1116892"
]
}
}
Map(
address book -> Map(
name -> John Smith,
address -> Map(
street -> 10 Market Street,
city -> San Francisco, CA,
zip -> 94111),
phone numbers ->
List(408 3384238, 408 1116892)
)
)
Parsing JSON
import scala.util.parsing.combinator._
class JSON1 extends JavaTokenParsers {
def obj: Parser[Map[String, Any]] =
"{" ~> repsep(member, ",") <~ "}" ^^ (Map() ++ _)
def arr: Parser[List[Any]] =
"[" ~> repsep(value, ",") <~ "]"
def member: Parser[(String, Any)] =
stringLiteral ~ ":" ~ value ^^
{ case name ~ ":" ~ value => (name, value) }
def value: Parser[Any] = (
obj
| arr
| stringLiteral
| floatingPointNumber ^^ (_.toDouble)
| "null" ^^ (x => null)
| "true" ^^ (x => true)
| "false" ^^ (x => false))
}
JSON Parser
Parser Combinators
✦ "..." literal
✦ "...".r regular expression
✦ P~Q sequential composition
✦ P <~ Q, P ~> Q sequential composition; keep left/right only
✦ P | Q alternative
✦ opt(P) option
✦ rep(P) repetition
✦ repsep(P, Q) interleaved repetition
✦ P ˆˆ f result conversion
Example Language
object ExpParser extends JavaTokenParsers with PackratParsers {
lazy val exp: PackratParser[Exp] =
(exp <~ "+") ~ exp1 ^^ { case lhs~rhs => Add(lhs, rhs) } |
exp1
lazy val exp1: PackratParser[Exp] =
(exp1 ~ exp0) ^^ { case lhs~rhs => App(lhs, rhs) } |
exp0
lazy val exp0: PackratParser[Exp] =
number | identifier | function | letBinding |
"(" ~> exp <~ ")"
// ...
def parse(text: String) = parseAll(exp, text)
}
def number: PackratParser[Exp] =
wholeNumber ^^ { x => Num(x.toInt) }
Numbers
def function: PackratParser[Exp] =
("fun" ~ "(") ~> ident ~ ((")" ~ "{") ~> (exp <~ "}")) ^^
{ case x~e => Fun(Symbol(x), e) }
Function Literal
def letBinding: PackratParser[Exp] =
(("let" ~> ident) ~ ("=" ~> exp)) ~ ("in" ~> exp0) ^^
{ case x~e1~e2 => Let(Symbol(x), e1, e2) }
Let Binding
Exercise
Reserved Words
def identifier: PackratParser[Exp] =
not(reserved) ~> ident ^^ { x => Id(Symbol(x)) }
def reserved: PackratParser[String] =
"letb".r | "inb".r | "funb".r
Implementing Parser
Combinators
package scala.util.parsing.combinator
trait Parsers {
type Parser[T] = Input => ParseResult[T]
type Input = Reader[Elem]
type Elem
// definition of parser combinators
}
Parser Trait
sealed abstract class ParseResult[+T]
case class Success[T](result: T, in: Input)
extends ParseResult[T]
case class Failure(msg: String, in: Input)
extends ParseResult[Nothing]
Parse Result
abstract class Parser[+T] extends (Input => ParseResult[T])
{ p =>
// An unspecified method that defines
// the behavior of this parser.
def apply(in: Input): ParseResult[T]
def ~ // ...
def | // ...
// ...
}
Parser
def elem(kind: String, p: Elem => Boolean) =
new Parser[Elem] {
def apply(in: Input) =
if (p(in.first)) Success(in.first, in.rest)
else Failure(kind + " expected", in)
}
Single Element Parser
abstract class Parser[+T] //...
{ p =>
//...
def ~ [U](q: => Parser[U]) = new Parser[T~U] {
def apply(in: Input) = p(in) match {
case Success(x, in1) =>
q(in1) match {
case Success(y, in2) => Success(new ~(x, y), in2)
case failure => failure
}
case failure => failure
}
}
Sequential Composition
def | (q: => Parser[T]) = new Parser[T] {
def apply(in: Input) = p(in) match {
case s1 @ Success(_, _) => s1
case failure => q(in)
}
}
Alternative Composition
def ^^ [U](f: T => U): Parser[U] = new Parser[U] {
def apply(in: Input) = p(in) match {
case Success(x, in1) => Success(f(x), in1)
case failure => failure
}
}
Result Conversion
Chapter 33: more combinators
Interpreting
“The semantics of a programming language
is the meaning of its expressions,
statements, and program units.”
Sebesta Ch3
Static Semantics: (context-senstive)
restriction of the set of valid programs
Dynamic Semantics: run-time
behaviour of a program
def eval(exp: Exp): Value
dynamic behaviour of Exp programs
Calculator
def testCalc {
expect(numV(48)) {
eval(parse("""
42 + 2 + 4
"""))
}
}
sealed abstract class Exp
case class Num(n: Int) extends Exp
case class Add(lhs: Exp, rhs: Exp) extends Exp
sealed abstract class Value
case class numV(n: Int) extends Value
def plus(l: Value, r: Value) = l match {
case numV(n) => r match {
case numV(m) => numV(n + m)
case _ => sys.error("Cannot add non-number")
}
}
def eval(exp: Exp): Value = exp match {
case Num(v) => numV(v)
case Add(l, r) => plus(eval(l), eval(r))
}
Calculator
Let Bindingdef testLet {
expect(numV(42)) {
eval(parse("""
let x = 40
in (x + 2)
"""))
}
}
def testLetShadow {
expect(numV(?)) {
eval(parse("""
let x = 40
in (let y = 4
in (let x = 3 in (x + y)))
"""))
}
}
sealed abstract class Env
case class mtEnv() extends Env
case class bind(boundName: Symbol, boundValue: Value, rest: Env)
extends Env
def lookup(name: Symbol, env: Env): Value = env match {
case mtEnv() =>
sys.error("Lookup of " + name + " in empty environment")
case bind(boundName, boundValue, rest) =>
if(boundName == name) boundValue else lookup(name, rest)
}
Environment
def eval(exp: Exp): Value = eval(exp, mtEnv())
def eval(exp: Exp, env: Env): Value = exp match {
case Num(v) => numV(v)
case Add(l, r) => plus(eval(l, env), eval(r, env))
case Id(name) => lookup(name, env)
case Let(name, e1, e2) =>
eval(e2, bind(name, eval(e1, env), env))
}
Evaluating Let Bindings
def testFun1 {
expect(numV(5)) {
eval(parse("""
let inc = fun(x){ x + 1 }
in (inc 4)
"""))
}
}
def testFun2 {
expect(numV(5)) {
eval(parse("""
let y = 3
in (let inc = fun(x){ x + y }
in (let y = 11 in (inc 2)))
"""))
}
}
Functions
sealed abstract class Value
case class numV(n: Int) extends Value
case class funV(param: Symbol, body: Exp) extends Value
def eval(exp: Exp, env: Env): Value = exp match {
case Num(v) => numV(v)
case Add(l, r) => plus(eval(l, env), eval(r, env))
case Id(name) => lookup(name, env)
case Let(name, e1, e2) =>
eval(e2, bind(name, eval(e1, env), env))
case Fun(name, body) => funV(name, body)
case App(fun, arg) => eval(fun, env) match {
case funV(name, body) =>
eval(body, bind(name, eval(arg, env), env))
case _ => sys.error("Function expected")
}
}
Functions
sealed abstract class Value
case class numV(n: Int) extends Value
case class funV(param: Symbol, body: Exp) extends Value
def eval(exp: Exp, env: Env): Value = exp match {
case Num(v) => numV(v)
case Add(l, r) => plus(eval(l, env), eval(r, env))
case Id(name) => lookup(name, env)
case Let(name, e1, e2) =>
eval(e2, bind(name, eval(e1, env), env))
case Fun(name, body) => funV(name, body)
case App(fun, arg) => eval(fun, env) match {
case funV(name, body) =>
eval(body, bind(name, eval(arg, env), env))
case _ => sys.error("Function expected")
}
}
FunctionsDynamic Scoping
sealed abstract class Value
case class numV(n: Int) extends Value
case class closureV(param: Symbol, body: Exp, env: Env)
extends Value
def eval(exp: Exp, env: Env): Value = exp match {
case Num(v) => numV(v)
case Add(l, r) => plus(eval(l, env), eval(r, env))
case Id(name) => lookup(name, env)
case Let(name, e1, e2) =>
eval(e2, bind(name, eval(e1, env), env))
case Fun(name, body) => closureV(name, body, env)
case App(fun, arg) => eval(fun, env) match {
case closureV(name, body, env2) =>
eval(body, bind(name, eval(arg, env), env2))
case _ => sys.error("Closure expected")
}
}
Functions with Closures
Reading & Programming in Week 9
Reading
Sebesta Chapter 4: Lexical and Syntactic Analysis
Scala Chapter 33: Combinator Parsing
Week 10: Components
WebLab:
Graded Assignment 2: (deadline 14 May 2013, 23:59)
Graded Assignment 3: (deadline 31 May 2013, 23:59)

Weitere ähnliche Inhalte

Was ist angesagt?

Regular expressions in Python
Regular expressions in PythonRegular expressions in Python
Regular expressions in PythonSujith Kumar
 
Compiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint ResolutionCompiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint ResolutionEelco Visser
 
Python Programming - XI. String Manipulation and Regular Expressions
Python Programming - XI. String Manipulation and Regular ExpressionsPython Programming - XI. String Manipulation and Regular Expressions
Python Programming - XI. String Manipulation and Regular ExpressionsRanel Padon
 
Use PEG to Write a Programming Language Parser
Use PEG to Write a Programming Language ParserUse PEG to Write a Programming Language Parser
Use PEG to Write a Programming Language ParserYodalee
 
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingCS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingEelco Visser
 
CS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definitionCS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definitionEelco Visser
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, SwiftYandex
 
Thinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in PythonThinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in PythonAnoop Thomas Mathew
 
Declare Your Language: Transformation by Strategic Term Rewriting
Declare Your Language: Transformation by Strategic Term RewritingDeclare Your Language: Transformation by Strategic Term Rewriting
Declare Your Language: Transformation by Strategic Term RewritingEelco Visser
 
FParsec Hands On - F#unctional Londoners 2014
FParsec Hands On -  F#unctional Londoners 2014FParsec Hands On -  F#unctional Londoners 2014
FParsec Hands On - F#unctional Londoners 2014Phillip Trelford
 
An Annotation Framework for Statically-Typed Syntax Trees
An Annotation Framework for Statically-Typed Syntax TreesAn Annotation Framework for Statically-Typed Syntax Trees
An Annotation Framework for Statically-Typed Syntax TreesRay Toal
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardMario Fusco
 
FUNDAMENTALS OF PYTHON LANGUAGE
 FUNDAMENTALS OF PYTHON LANGUAGE  FUNDAMENTALS OF PYTHON LANGUAGE
FUNDAMENTALS OF PYTHON LANGUAGE Saraswathi Murugan
 
Functional programming in Python
Functional programming in PythonFunctional programming in Python
Functional programming in PythonColin Su
 

Was ist angesagt? (20)

First steps in PERL
First steps in PERLFirst steps in PERL
First steps in PERL
 
Regular expressions in Python
Regular expressions in PythonRegular expressions in Python
Regular expressions in Python
 
Python : Functions
Python : FunctionsPython : Functions
Python : Functions
 
Compiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint ResolutionCompiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint Resolution
 
Python Programming - XI. String Manipulation and Regular Expressions
Python Programming - XI. String Manipulation and Regular ExpressionsPython Programming - XI. String Manipulation and Regular Expressions
Python Programming - XI. String Manipulation and Regular Expressions
 
Python ppt
Python pptPython ppt
Python ppt
 
Use PEG to Write a Programming Language Parser
Use PEG to Write a Programming Language ParserUse PEG to Write a Programming Language Parser
Use PEG to Write a Programming Language Parser
 
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingCS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
 
CS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definitionCS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definition
 
Python
PythonPython
Python
 
From OOP To FP Through A Practical Case
From OOP To FP Through A Practical CaseFrom OOP To FP Through A Practical Case
From OOP To FP Through A Practical Case
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, Swift
 
Thinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in PythonThinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in Python
 
Declare Your Language: Transformation by Strategic Term Rewriting
Declare Your Language: Transformation by Strategic Term RewritingDeclare Your Language: Transformation by Strategic Term Rewriting
Declare Your Language: Transformation by Strategic Term Rewriting
 
FParsec Hands On - F#unctional Londoners 2014
FParsec Hands On -  F#unctional Londoners 2014FParsec Hands On -  F#unctional Londoners 2014
FParsec Hands On - F#unctional Londoners 2014
 
An Annotation Framework for Statically-Typed Syntax Trees
An Annotation Framework for Statically-Typed Syntax TreesAn Annotation Framework for Statically-Typed Syntax Trees
An Annotation Framework for Statically-Typed Syntax Trees
 
python codes
python codespython codes
python codes
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
 
FUNDAMENTALS OF PYTHON LANGUAGE
 FUNDAMENTALS OF PYTHON LANGUAGE  FUNDAMENTALS OF PYTHON LANGUAGE
FUNDAMENTALS OF PYTHON LANGUAGE
 
Functional programming in Python
Functional programming in PythonFunctional programming in Python
Functional programming in Python
 

Andere mochten auch

如何建立企業級應用的商業規則引擎
如何建立企業級應用的商業規則引擎如何建立企業級應用的商業規則引擎
如何建立企業級應用的商業規則引擎CodeData
 
Static name resolution
Static name resolutionStatic name resolution
Static name resolutionEelco Visser
 
Software languages
Software languagesSoftware languages
Software languagesEelco Visser
 
Garbage Collection
Garbage CollectionGarbage Collection
Garbage CollectionEelco Visser
 

Andere mochten auch (6)

如何建立企業級應用的商業規則引擎
如何建立企業級應用的商業規則引擎如何建立企業級應用的商業規則引擎
如何建立企業級應用的商業規則引擎
 
Dynamic Semantics
Dynamic SemanticsDynamic Semantics
Dynamic Semantics
 
Static name resolution
Static name resolutionStatic name resolution
Static name resolution
 
Type analysis
Type analysisType analysis
Type analysis
 
Software languages
Software languagesSoftware languages
Software languages
 
Garbage Collection
Garbage CollectionGarbage Collection
Garbage Collection
 

Ähnlich wie TI1220 Lecture 9: Parsing & interpretation

Transform your State \/ Err
Transform your State \/ ErrTransform your State \/ Err
Transform your State \/ ErrGermán Ferrari
 
Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011Tudor Girba
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming iiPrashant Kalkar
 
Implementing External DSLs Using Scala Parser Combinators
Implementing External DSLs Using Scala Parser CombinatorsImplementing External DSLs Using Scala Parser Combinators
Implementing External DSLs Using Scala Parser CombinatorsTim Dalton
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meetMario Fusco
 
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...adrianoalmeida7
 
Build a compiler in 2hrs - NCrafts Paris 2015
Build a compiler in 2hrs -  NCrafts Paris 2015Build a compiler in 2hrs -  NCrafts Paris 2015
Build a compiler in 2hrs - NCrafts Paris 2015Phillip Trelford
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecLoïc Descotte
 
Scope Graphs: A fresh look at name binding in programming languages
Scope Graphs: A fresh look at name binding in programming languagesScope Graphs: A fresh look at name binding in programming languages
Scope Graphs: A fresh look at name binding in programming languagesEelco Visser
 
Declare Your Language: Name Resolution
Declare Your Language: Name ResolutionDeclare Your Language: Name Resolution
Declare Your Language: Name ResolutionEelco Visser
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala Knoldus Inc.
 

Ähnlich wie TI1220 Lecture 9: Parsing & interpretation (20)

Transform your State \/ Err
Transform your State \/ ErrTransform your State \/ Err
Transform your State \/ Err
 
Ch2
Ch2Ch2
Ch2
 
Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011
 
Scala Paradigms
Scala ParadigmsScala Paradigms
Scala Paradigms
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
Implementing External DSLs Using Scala Parser Combinators
Implementing External DSLs Using Scala Parser CombinatorsImplementing External DSLs Using Scala Parser Combinators
Implementing External DSLs Using Scala Parser Combinators
 
Ch2 (1).ppt
Ch2 (1).pptCh2 (1).ppt
Ch2 (1).ppt
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...
 
Build a compiler in 2hrs - NCrafts Paris 2015
Build a compiler in 2hrs -  NCrafts Paris 2015Build a compiler in 2hrs -  NCrafts Paris 2015
Build a compiler in 2hrs - NCrafts Paris 2015
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
FYP Final Presentation
FYP Final PresentationFYP Final Presentation
FYP Final Presentation
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
Scope Graphs: A fresh look at name binding in programming languages
Scope Graphs: A fresh look at name binding in programming languagesScope Graphs: A fresh look at name binding in programming languages
Scope Graphs: A fresh look at name binding in programming languages
 
Declare Your Language: Name Resolution
Declare Your Language: Name ResolutionDeclare Your Language: Name Resolution
Declare Your Language: Name Resolution
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
Grammarware Memes
Grammarware MemesGrammarware Memes
Grammarware Memes
 
Meet scala
Meet scalaMeet scala
Meet scala
 
Frp2016 3
Frp2016 3Frp2016 3
Frp2016 3
 
Functional Programming Advanced
Functional Programming AdvancedFunctional Programming Advanced
Functional Programming Advanced
 

Mehr von Eelco Visser

CS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic ServicesCS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic ServicesEelco Visser
 
CS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | ParsingCS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | ParsingEelco Visser
 
CS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: IntroductionCS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: IntroductionEelco Visser
 
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 RulesEelco Visser
 
Declarative Type System Specification with Statix
Declarative Type System Specification with StatixDeclarative Type System Specification with Statix
Declarative Type System Specification with StatixEelco Visser
 
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 ConstructionEelco Visser
 
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)Eelco Visser
 
Compiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory ManagementCompiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory ManagementEelco Visser
 
Compiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersCompiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersEelco Visser
 
Compiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code GenerationCompiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code GenerationEelco Visser
 
Compiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual MachinesCompiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual MachinesEelco Visser
 
Compiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone FrameworksCompiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone FrameworksEelco Visser
 
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 AnalysisEelco Visser
 
Compiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type ConstraintsCompiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type ConstraintsEelco Visser
 
Compiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type CheckingCompiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type CheckingEelco Visser
 
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 AnalysisEelco Visser
 
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term RewritingCompiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term RewritingEelco Visser
 
Compiler Construction | Lecture 4 | Parsing
Compiler Construction | Lecture 4 | Parsing Compiler Construction | Lecture 4 | Parsing
Compiler Construction | Lecture 4 | Parsing Eelco Visser
 
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 ServicesEelco Visser
 
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 DefinitionEelco Visser
 

Mehr von Eelco Visser (20)

CS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic ServicesCS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic Services
 
CS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | ParsingCS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | Parsing
 
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
 
Declarative Type System Specification with Statix
Declarative Type System Specification with StatixDeclarative Type System Specification with Statix
Declarative Type System Specification with Statix
 
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 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersCompiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | Interpreters
 
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 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual MachinesCompiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual Machines
 
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 8 | Type Constraints
Compiler Construction | Lecture 8 | Type ConstraintsCompiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type Constraints
 
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 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term RewritingCompiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
 
Compiler Construction | Lecture 4 | Parsing
Compiler Construction | Lecture 4 | Parsing Compiler Construction | Lecture 4 | Parsing
Compiler Construction | Lecture 4 | Parsing
 
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
 
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
 

TI1220 Lecture 9: Parsing & interpretation

  • 1. TI1220 2012-2013 Concepts of Programming Languages Eelco Visser / TU Delft Lecture 9: Parsing & Interpretation
  • 2. Syntax and Semantics Names, Bindings, and Scopes Storage Data Types Functional Programming First-class Functions Polymorphism Traits & Type Parameterization Parsing and Interpretation Data Abstraction / Modular Programming Functional Programming Redux Concurrency Concurrent Programming Domain-Specific Languages Quarter 3 Quarter 4 Basics of Scala JavaScript C
  • 5. “The syntax of a programming language is the form of its expressions, statements, and program units.” Sebesta Ch3
  • 6. let y = 3 in (let inc = fun(x){ x + y } in (let y = 11 in (inc 2))) let g = fun(f){ f(3) } in (let h = fun(x){ x + 5 } in (g h)) Example Language
  • 7. Exp = Exp '+' Exp1 // addition | Exp1 Exp1 = Exp1 Exp0 // function application | Exp0 Exp0 = '(' Exp ') // parentheses | 'fun' '(' ident ')' '{' // function literal Exp '}' | 'let' ident '=' Exp // let binding 'in' Exp0 | ident // identifier | number // number Context-free Grammar
  • 8. sealed abstract class Exp case class Add(lhs: Exp, rhs: Exp) extends Exp case class App(funExpr: Exp, arg: Exp) extends Exp case class Fun(param: Symbol, body: Exp) extends Exp case class Let(name: Symbol, bound: Exp, body: Exp) extends Exp case class Id(name: Symbol) extends Exp case class Num(n: Int) extends Exp Exp = Exp '+' Exp1 | Exp1 Exp1 = Exp1 Exp0 | Exp0 Exp0 = '(' Exp ') | 'fun' '(' ident ')' '{' Exp '}' | 'let' ident '=' Exp 'in' Exp0 | ident | number From Concrete to Abstract Syntax
  • 9. Sentence AST 1 + 2 Add(Num(1),Num(2)) foo bar baz App(App(Id('foo), Id('bar)), Id('baz)) fun(foo){ bar baz } Fun('foo, App(Id('bar), Id('baz))) fun(x){ x + 1 } Fun('x, Add(Id('x), Num(1))) let inc = fun(x){ x + 1 } in (inc 3) Let('inc, Fun('x, Add(Id('x), Num(1))), App(Id('inc), Num(3))) From Concrete to Abstract Syntax
  • 11. Approaches to constructing parsers ★ roll your own (recursive descent) ★ parser generator ★ parser combinators
  • 13. Arithmetic Expressions (1 + 4) * 7 / 34 - 3 expr ::= term { "+" term | "-" term }. term ::= factor {"*" factor | "/" factor }. factor ::= floatingPointNumber | "(" expr ")".
  • 14. import scala.util.parsing.combinator._ class Arith extends JavaTokenParsers { def expr: Parser[Any] = term~rep("+"~term | "-"~term) def term: Parser[Any] = factor~rep("*"~factor | "/"~factor) def factor: Parser[Any] = floatingPointNumber | "("~expr~")" } expr ::= term { "+" term | "-" term }. term ::= factor {"*" factor | "/" factor }. factor ::= floatingPointNumber | "(" expr ")". Parser combinators ★ Sequential composition: p ~ q ★ Repetition: rep( p ) ★ Alternative: p | q Full API: http://www.scala-lang.org/api/current/index.html#scala.reflect.macros.Parsers
  • 15. (1 + 4) * 7 [[1.12] parsed: (((((~((1~List())~List((+~(4~List())))))~))~List((*~7)))~List())]
  • 16. sealed abstract class Exp case class Num(n: Double) extends Exp case class Op(op: String, e: Exp) extends Exp case class OpList(e: Exp, es: List[Exp]) extends Exp import scala.util.parsing.combinator._ class Arith extends JavaTokenParsers { def expr: Parser[Exp] = term ~ rep( "+" ~> term ^^ { case e => Op("+", e) } ) ^^ { case e~es => OpList(e, es) } def term: Parser[Exp] = factor ~ rep( "*" ~> factor ^^ { case e => Op("*", e) } ) ^^ { case e~es => OpList(e, es) } def factor: Parser[Exp] = floatingPointNumber ^^ { case n => Num(n.toDouble) } | "(" ~> expr <~ ")" } object ParseExpr extends Arith { def parse(exp: String): Exp = parseAll(expr, exp).get } Constructing ASTs
  • 18. sealed abstract class Exp case class Num(n: Double) extends Exp case class BinOp(op: String, l: Exp, r: Exp) extends Exp import scala.util.parsing.combinator._ class Arith extends JavaTokenParsers { def expr: Parser[Exp] = expr ~ ("+" ~> term) ^^ { case e~t => BinOp("+", e, t) } | term def term: Parser[Exp] = term ~ ("*" ~> factor) ^^ { case e~t => BinOp("*", e, t) } | factor def factor: Parser[Exp] = floatingPointNumber ^^ { case n => Num(n.toDouble) } | "(" ~> expr <~ ")" } (1 + 3) Binary Productions
  • 19. sealed abstract class Exp case class Num(n: Double) extends Exp case class BinOp(op: String, l: Exp, r: Exp) extends Exp import scala.util.parsing.combinator._ class Arith extends JavaTokenParsers { def expr: Parser[Exp] = expr ~ ("+" ~> term) ^^ { case e~t => BinOp("+", e, t) } | term def term: Parser[Exp] = term ~ ("*" ~> factor) ^^ { case e~t => BinOp("*", e, t) } | factor def factor: Parser[Exp] = floatingPointNumber ^^ { case n => Num(n.toDouble) } | "(" ~> expr <~ ")" } (1 + 3) Status: RunningFailure Test score: 0/-1 Binary Productions
  • 20. sealed abstract class Exp case class Num(n: Double) extends Exp case class BinOp(op: String, l: Exp, r: Exp) extends Exp import scala.util.parsing.combinator._ class Arith extends JavaTokenParsers with PackratParsers { lazy val expr: PackratParser[Exp] = expr ~ ("+" ~> term) ^^ { case e~t => BinOp("+", e, t) } | term lazy val term: PackratParser[Exp] = factor ~ ("*" ~> factor) ^^ { case e~t => BinOp("*", e, t) } | factor lazy val factor: PackratParser[Exp] = floatingPointNumber ^^ { case n => Num(n.toDouble) } | "(" ~> expr <~ ")" } (1 + 4) * 7 BinOp(*, BinOp(+,Num(1.0),Num(4.0)), Num(7.0)) Packrat Parser
  • 21. { "address book": { "name": "John Smith", "address": { "street": "10 Market Street", "city" : "San Francisco, CA", "zip" : 94111 }, "phone numbers": [ "408 3384238", "408 1116892" ] } } Map( address book -> Map( name -> John Smith, address -> Map( street -> 10 Market Street, city -> San Francisco, CA, zip -> 94111), phone numbers -> List(408 3384238, 408 1116892) ) ) Parsing JSON
  • 22. import scala.util.parsing.combinator._ class JSON1 extends JavaTokenParsers { def obj: Parser[Map[String, Any]] = "{" ~> repsep(member, ",") <~ "}" ^^ (Map() ++ _) def arr: Parser[List[Any]] = "[" ~> repsep(value, ",") <~ "]" def member: Parser[(String, Any)] = stringLiteral ~ ":" ~ value ^^ { case name ~ ":" ~ value => (name, value) } def value: Parser[Any] = ( obj | arr | stringLiteral | floatingPointNumber ^^ (_.toDouble) | "null" ^^ (x => null) | "true" ^^ (x => true) | "false" ^^ (x => false)) } JSON Parser
  • 23. Parser Combinators ✦ "..." literal ✦ "...".r regular expression ✦ P~Q sequential composition ✦ P <~ Q, P ~> Q sequential composition; keep left/right only ✦ P | Q alternative ✦ opt(P) option ✦ rep(P) repetition ✦ repsep(P, Q) interleaved repetition ✦ P ˆˆ f result conversion
  • 25. object ExpParser extends JavaTokenParsers with PackratParsers { lazy val exp: PackratParser[Exp] = (exp <~ "+") ~ exp1 ^^ { case lhs~rhs => Add(lhs, rhs) } | exp1 lazy val exp1: PackratParser[Exp] = (exp1 ~ exp0) ^^ { case lhs~rhs => App(lhs, rhs) } | exp0 lazy val exp0: PackratParser[Exp] = number | identifier | function | letBinding | "(" ~> exp <~ ")" // ... def parse(text: String) = parseAll(exp, text) }
  • 26. def number: PackratParser[Exp] = wholeNumber ^^ { x => Num(x.toInt) } Numbers
  • 27. def function: PackratParser[Exp] = ("fun" ~ "(") ~> ident ~ ((")" ~ "{") ~> (exp <~ "}")) ^^ { case x~e => Fun(Symbol(x), e) } Function Literal
  • 28. def letBinding: PackratParser[Exp] = (("let" ~> ident) ~ ("=" ~> exp)) ~ ("in" ~> exp0) ^^ { case x~e1~e2 => Let(Symbol(x), e1, e2) } Let Binding Exercise
  • 29. Reserved Words def identifier: PackratParser[Exp] = not(reserved) ~> ident ^^ { x => Id(Symbol(x)) } def reserved: PackratParser[String] = "letb".r | "inb".r | "funb".r
  • 31. package scala.util.parsing.combinator trait Parsers { type Parser[T] = Input => ParseResult[T] type Input = Reader[Elem] type Elem // definition of parser combinators } Parser Trait
  • 32. sealed abstract class ParseResult[+T] case class Success[T](result: T, in: Input) extends ParseResult[T] case class Failure(msg: String, in: Input) extends ParseResult[Nothing] Parse Result
  • 33. abstract class Parser[+T] extends (Input => ParseResult[T]) { p => // An unspecified method that defines // the behavior of this parser. def apply(in: Input): ParseResult[T] def ~ // ... def | // ... // ... } Parser
  • 34. def elem(kind: String, p: Elem => Boolean) = new Parser[Elem] { def apply(in: Input) = if (p(in.first)) Success(in.first, in.rest) else Failure(kind + " expected", in) } Single Element Parser
  • 35. abstract class Parser[+T] //... { p => //... def ~ [U](q: => Parser[U]) = new Parser[T~U] { def apply(in: Input) = p(in) match { case Success(x, in1) => q(in1) match { case Success(y, in2) => Success(new ~(x, y), in2) case failure => failure } case failure => failure } } Sequential Composition
  • 36. def | (q: => Parser[T]) = new Parser[T] { def apply(in: Input) = p(in) match { case s1 @ Success(_, _) => s1 case failure => q(in) } } Alternative Composition
  • 37. def ^^ [U](f: T => U): Parser[U] = new Parser[U] { def apply(in: Input) = p(in) match { case Success(x, in1) => Success(f(x), in1) case failure => failure } } Result Conversion
  • 38. Chapter 33: more combinators
  • 40. “The semantics of a programming language is the meaning of its expressions, statements, and program units.” Sebesta Ch3
  • 41. Static Semantics: (context-senstive) restriction of the set of valid programs Dynamic Semantics: run-time behaviour of a program
  • 42. def eval(exp: Exp): Value dynamic behaviour of Exp programs
  • 43. Calculator def testCalc { expect(numV(48)) { eval(parse(""" 42 + 2 + 4 """)) } }
  • 44. sealed abstract class Exp case class Num(n: Int) extends Exp case class Add(lhs: Exp, rhs: Exp) extends Exp sealed abstract class Value case class numV(n: Int) extends Value def plus(l: Value, r: Value) = l match { case numV(n) => r match { case numV(m) => numV(n + m) case _ => sys.error("Cannot add non-number") } } def eval(exp: Exp): Value = exp match { case Num(v) => numV(v) case Add(l, r) => plus(eval(l), eval(r)) } Calculator
  • 45. Let Bindingdef testLet { expect(numV(42)) { eval(parse(""" let x = 40 in (x + 2) """)) } } def testLetShadow { expect(numV(?)) { eval(parse(""" let x = 40 in (let y = 4 in (let x = 3 in (x + y))) """)) } }
  • 46. sealed abstract class Env case class mtEnv() extends Env case class bind(boundName: Symbol, boundValue: Value, rest: Env) extends Env def lookup(name: Symbol, env: Env): Value = env match { case mtEnv() => sys.error("Lookup of " + name + " in empty environment") case bind(boundName, boundValue, rest) => if(boundName == name) boundValue else lookup(name, rest) } Environment
  • 47. def eval(exp: Exp): Value = eval(exp, mtEnv()) def eval(exp: Exp, env: Env): Value = exp match { case Num(v) => numV(v) case Add(l, r) => plus(eval(l, env), eval(r, env)) case Id(name) => lookup(name, env) case Let(name, e1, e2) => eval(e2, bind(name, eval(e1, env), env)) } Evaluating Let Bindings
  • 48. def testFun1 { expect(numV(5)) { eval(parse(""" let inc = fun(x){ x + 1 } in (inc 4) """)) } } def testFun2 { expect(numV(5)) { eval(parse(""" let y = 3 in (let inc = fun(x){ x + y } in (let y = 11 in (inc 2))) """)) } } Functions
  • 49. sealed abstract class Value case class numV(n: Int) extends Value case class funV(param: Symbol, body: Exp) extends Value def eval(exp: Exp, env: Env): Value = exp match { case Num(v) => numV(v) case Add(l, r) => plus(eval(l, env), eval(r, env)) case Id(name) => lookup(name, env) case Let(name, e1, e2) => eval(e2, bind(name, eval(e1, env), env)) case Fun(name, body) => funV(name, body) case App(fun, arg) => eval(fun, env) match { case funV(name, body) => eval(body, bind(name, eval(arg, env), env)) case _ => sys.error("Function expected") } } Functions
  • 50. sealed abstract class Value case class numV(n: Int) extends Value case class funV(param: Symbol, body: Exp) extends Value def eval(exp: Exp, env: Env): Value = exp match { case Num(v) => numV(v) case Add(l, r) => plus(eval(l, env), eval(r, env)) case Id(name) => lookup(name, env) case Let(name, e1, e2) => eval(e2, bind(name, eval(e1, env), env)) case Fun(name, body) => funV(name, body) case App(fun, arg) => eval(fun, env) match { case funV(name, body) => eval(body, bind(name, eval(arg, env), env)) case _ => sys.error("Function expected") } } FunctionsDynamic Scoping
  • 51. sealed abstract class Value case class numV(n: Int) extends Value case class closureV(param: Symbol, body: Exp, env: Env) extends Value def eval(exp: Exp, env: Env): Value = exp match { case Num(v) => numV(v) case Add(l, r) => plus(eval(l, env), eval(r, env)) case Id(name) => lookup(name, env) case Let(name, e1, e2) => eval(e2, bind(name, eval(e1, env), env)) case Fun(name, body) => closureV(name, body, env) case App(fun, arg) => eval(fun, env) match { case closureV(name, body, env2) => eval(body, bind(name, eval(arg, env), env2)) case _ => sys.error("Closure expected") } } Functions with Closures
  • 52. Reading & Programming in Week 9 Reading Sebesta Chapter 4: Lexical and Syntactic Analysis Scala Chapter 33: Combinator Parsing Week 10: Components WebLab: Graded Assignment 2: (deadline 14 May 2013, 23:59) Graded Assignment 3: (deadline 31 May 2013, 23:59)