Abstract vs. Concrete Syntax in L7AST for Lambda Calculus Expressions
170 likes | 289 Vues
This document explores the syntax of L7AST, contrasting abstract and concrete representations of lambda expressions. We define the structure of l-expressions, including identifiers, lambda expressions, and application expressions. The parsing and un-parsing mechanisms between concrete syntax (such as Scheme S-expressions) and abstract syntax trees (ASTs) are elaborated. Real-world examples are provided using Scheme, illustrating operations like parsing expressions and managing environments through closures, recursion, and induction in the context of abstract syntax representation.
Abstract vs. Concrete Syntax in L7AST for Lambda Calculus Expressions
E N D
Presentation Transcript
Abstract Syntax L7AST
Language of l-expressions <exp> ::= <identifier> | (lambda( <identifier>)<exp>) | (<exp> <exp>) E.g.,concrete syntax Scheme S-expressions ( lambda (x) ( f ( f x ) ) ) L7AST
Abstract Syntax (vs Concrete Syntax) lambda-exp id body app-exp rand rator var-exp app-exp rator rand id var-exp var-exp id id L7AST
Overview Parse-expression Concrete Syntax Abstract Syntax Unparse-expression Interpreter Results L7AST
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?))) L7AST
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)) ))) L7AST
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)) L7AST
Example (PLT Scheme) L7AST
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)) ) ))) L7AST
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. L7AST
Representing Environment L7AST
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))))) )) L7AST
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) ) ) L7AST
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)) L7AST
(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)))) ) )) L7AST
Queue (define reset (lambda (q) (vector-ref q 0))) (define empty? (lambda (q) (vector-ref q 1))) (define enqueue (lambda (q) (vector-ref q 2))) (define dequeue (lambda (q) (vector-ref q 3))) (define Q (create-queue)) ((enqueue Q) 55) ((empty? Q)) ((dequeue Q)) ((empty? Q)) ((reset Q)) ((dequeue Q)) L7AST
(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)) ))) L7AST