170 likes | 286 Vues
Learn about the abstract syntax of the L6AST language for parsing lambda expressions. Understand concrete vs. abstract syntax, parsing techniques, interpreting results, and representing syntax with records. Discover examples with the Scheme language. Explore the role of induction, recursion, defining data structures, representing environments, and using alternative approaches.
E N D
Abstract Syntax L6AST
Language of l-expressions <exp> ::= <identifier> | (lambda( <identifier>)<exp>) | (<exp> <exp>) E.g.,concrete syntax Scheme S-expressions ( lambda (x) ( f ( f x ) ) ) L6AST
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 L6AST
Overview Parse-expression Concrete Syntax Abstract Syntax Unparse-expression Interpreter Results L6AST
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?))) L6AST
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)) ))) L6AST
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)) L6AST
Example (PLT Scheme) L6AST
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)) ) ))) L6AST
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. L6AST
Representing Environment L6AST
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))))) )) L6AST
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) ) ) L6AST
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)) L6AST
(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)))) ) )) L6AST
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)) L6AST
(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)) ))) L6AST