Abstract Syntax

Abstract Syntax
cs784 (Prasad)
L6AST
1
Language of l-expressions
<exp>
::=
<identifier>
| (lambda (
<identifier>
)<exp>)
| (<exp> <exp>)
E.g., concrete syntax Scheme S-expressions
( lambda (x) ( f ( f x ) ) )
cs784 (Prasad)
L6AST
2
Abstract Syntax
(vs Concrete Syntax)
lambda-exp
id
body
app-exp
rand
rator
var-exp
app-exp
rator
id
rand
var-exp
id
cs784 (Prasad)
var-exp
id
L6AST
3
Overview
Parse-expression
Concrete
Syntax
Abstract
Syntax
Unparse-expression
Interpreter
Results
cs784 (Prasad)
L6AST
4
Representing Abstract Syntax with
Records
(define-datatype expression expression?
(var-exp
(id symbol?))
(lambda-exp
(id symbol?)
(body expression?))
(app-exp
(rator expression?)
(rand expression?)))
cs784 (Prasad)
L6AST
5
Parse: Concrete to Abstract Syntax
(define parse-expression
(lambda (datum)
(cond
((symbol? datum) (var-exp datum))
((pair? datum)
(if (eqv? (car datum) 'lambda)
(lambda-exp (caadr datum)
(parse-expression (caddr datum)))
(app-exp
(parse-expression (car datum))
(parse-expression (cadr datum)))
)
)
(else (eopl:error 'parse-expression
"Invalid concrete syntax ~s" datum))
)))
cs784 (Prasad)
L6AST
6
Example (Petite Scheme)
> (current-directory
“I:\\tkprasad\\cs784\\EOPL-CODE\\interps")
> (load "chez-init.scm")
> (load "2-2-2.scm")
> (parse-expression 'x)
(var-exp x)
> (parse-expression '(lambda (x) (f x)))
(lambda-exp x (app-exp (var-exp f) (var-exp x)))
> (parse-expression 45)
Error reported by parse-expression:
Invalid concrete syntax 45
debug>e
>(unparse-expression
'(lambda-exp x (app-exp
(var-exp f) (var-exp x))))
(lambda (x) (f x))
cs784 (Prasad)
L6AST
7
Example (PLT Scheme)
cs784 (Prasad)
L6AST
8
Unparse: Abstract to Concrete Syntax
(define unparse-expression
(lambda (exp)
(cases expression exp
(var-exp (id) id)
(lambda-exp (id body)
(list 'lambda (list id)
(unparse-expression body)) )
(app-exp (rator rand)
(list (unparse-expression rator)
(unparse-expression rand)) )
)))
cs784 (Prasad)
L6AST
9
Role of Induction and Recursion
• Define data structures (infinite values) by
induction.
• Seed elements.
• Closure operations.
• Define functions (operations) by recursion.
• Boundary/Basis case.
• Composite/Recursive case.
• Prove properties using structural induction.
• Basis case.
• Inductive step.
cs784 (Prasad)
L6AST
10
Representing Environment
cs784 (Prasad)
L6AST
11
Alternative 1
(define empty-env
(lambda () '()))
(define extend-env
(lambda (syms vals env)
(cons (list syms vals) env) ))
(define apply-env
(lambda (env sym)
(if (null? env)
(eopl:error 'apply-env "No binding for ~s" sym)
(let ((syms (car (car env)))
(vals (cadr (car env)))
(env (cdr env)))
(let ((pos (rib-find-position sym syms)))
(if (number? pos)
(list-ref vals pos)
(apply-env env sym)))))
))
cs784 (Prasad)
L6AST
12
Alternative 2
(define empty-env
(lambda ()
(lambda (sym)
(eopl:error 'apply-env "No binding for ~s" sym)) )
)
(define extend-env
(lambda (syms vals env)
(lambda (sym)
(let ((pos (list-find-position sym syms)))
(if (number? pos)
(list-ref vals pos)
(apply-env env sym)))) )
)
(define apply-env
(lambda (env sym)
(env sym) )
)
cs784 (Prasad)
L6AST
13
Alternative 3
(define-datatype environment environment?
(empty-env-record)
(extended-env-record
(syms (list-of symbol?))
(vals (list-of scheme-value?))
(env environment?)))
(define scheme-value? (lambda (v) #t))
cs784 (Prasad)
L6AST
14
(cont’d)
(define empty-env
(lambda ()
(empty-env-record) ))
(define extend-env
(lambda (syms vals env)
(extended-env-record syms vals env)))
(define apply-env
(lambda (env sym)
(cases environment env
(empty-env-record ()
(eopl:error 'apply-env "No binding for ~s" sym))
(extended-env-record (syms vals env)
(let ((pos (list-find-position sym syms)))
(if (number? pos)
(list-ref vals pos)
(apply-env env sym)))) )
))
cs784 (Prasad)
L6AST
15
Queue
(define
(define
(define
(define
(define
reset (lambda (q) (vector-ref q 0)))
empty? (lambda (q) (vector-ref q 1)))
enqueue (lambda (q) (vector-ref q 2)))
dequeue (lambda (q) (vector-ref q 3)))
Q
(create-queue))
((enqueue Q) 55)
((empty? Q))
((dequeue Q))
((empty? Q))
((reset Q))
((dequeue Q))
cs784 (Prasad)
L6AST
16
(define create-queue
(lambda ()
(let ((q-in '()) (q-out '()))
(letrec
((reset-queue
(lambda ()
(set! q-in '()) (set! q-out '())) )
(empty-queue?
(lambda ()
(and (null? q-in) (null? q-out))) )
(enqueue
(lambda (x)
(set! q-in (cons x q-in))) )
(dequeue
(lambda ()
(if (empty-queue?)
(eopl:error 'dequeue "Not on an empty queue")
(begin
(if (null? q-out)
(begin
(set! q-out (reverse q-in)) (set! q-in '())))
(let ((ans (car q-out)))
(set! q-out (cdr q-out))
ans))))) )
(vector reset-queue empty-queue? enqueue dequeue))
)))
cs784 (Prasad)
L6AST
17