Advertisement
Guest User

interpretador_mod

a guest
Feb 28th, 2019
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 17.03 KB | None | 0 0
  1. #lang eopl
  2.  
  3. ;******************************************************************************************
  4. ;;;;; Interpretador para lenguaje con condicionales, ligadura local y procedimientos
  5.  
  6. ;; La definición BNF para las expresiones del lenguaje:
  7. ;;
  8. ;;  <program>       ::= <expression>
  9. ;;                      <a-program (exp)>
  10. ;;  <expression>    ::= <number>
  11. ;;                      <lit-exp (datum)>
  12. ;;                  ::= <identifier>
  13. ;;                      <var-exp (id)>
  14. ;;                  ::= <primitive> ({<expression>}*(,))
  15. ;;                      <primapp-exp (prim rands)>
  16. ;;                  ::= if <expresion> then <expresion> else <expression>
  17. ;;                      <if-exp (exp1 exp2 exp23)>
  18. ;;                  ::= let {identifier = <expression>}* in <expression>
  19. ;;                      <let-exp (ids rands body)>
  20. ;;                  ::= proc({<identificador>}*(,)) <expression>
  21. ;;                      <proc-exp (ids body)>
  22. ;;                  ::= (<expression> {<expression>}*)
  23. ;;                      <app-exp proc rands>
  24. ;;  <primitive>     ::= + | - | * | add1 | sub1
  25.  
  26. ;******************************************************************************************
  27.  
  28. ;******************************************************************************************
  29. ;Especificación Léxica
  30.  
  31. (define scanner-spec-simple-interpreter
  32. '((white-sp
  33.    (whitespace) skip)
  34.   (comment
  35.    ("%" (arbno (not #\newline))) skip)
  36.   (identifier
  37.    (letter (arbno (or letter digit "?"))) symbol)
  38.   (number
  39.    (digit (arbno digit)) number)
  40.   (number
  41.    ("-" digit (arbno digit)) number)))
  42.  
  43. ;Especificación Sintáctica (gramática)
  44.  
  45. (define grammar-simple-interpreter
  46.   '((program (expression) a-program)
  47.     (expression (number) lit-exp)
  48.     (expression (identifier) var-exp)
  49.     (expression
  50.      (primitive "(" (separated-list expression ",")")")
  51.      primapp-exp)
  52.     (expression ("if" expression "then" expression "else" expression)
  53.                 if-exp)
  54.     (expression ("let" (arbno identifier "=" expression) "in" expression)
  55.                 let-exp)
  56.     (expression
  57.         ("atLeast" "(" expression "," (separated-list expression ",") ")" )
  58.         atleast-exp
  59.     )
  60.     (expression
  61.         ("arity" "(" expression  ")" )
  62.         arity-exp
  63.     )
  64.     (expression ("abb" abb "end") bst-exp)
  65.     (abb ("empty-bst") empty)
  66.     (abb ("leaf" "(" number ")") leaf)
  67.     (abb ("node" "(" number "," abb "," abb ")") node)
  68.     (expression ("push" number "to" expression) bst-push-exp) ; Punto 5.2.a) push <number> to <abb>
  69.     (expression ("preorder" expression) preorder-bst-exp)     ; Punto 5.2.b) preorder <abb>
  70.     (expression ("is" number "in" expression) in-bst-exp)     ; Punto 5.2.c) is <number> in <abb>
  71.     ; características adicionales
  72.     (expression ("proc" "(" (separated-list identifier ",") ")" expression)
  73.                 proc-exp)
  74.     (expression ( "(" expression (arbno expression) ")")
  75.                 app-exp)
  76.     (expression ( "eclipse" "(" identifier ")" )
  77.       eclipse-exp
  78.     )
  79.     ;;;;;;
  80.  
  81.     (primitive ("+") add-prim)
  82.     (primitive ("-") substract-prim)
  83.     (primitive ("*") mult-prim)
  84.     (primitive ("add1") incr-prim)
  85.     (primitive ("sub1") decr-prim)))
  86.  
  87.  
  88. ;Tipos de datos para la sintaxis abstracta de la gramática
  89.  
  90. ;Construidos manualmente:
  91.  
  92. ;(define-datatype program program?
  93. ;  (a-program
  94. ;   (exp expression?)))
  95. ;
  96. ;(define-datatype expression expression?
  97. ;  (lit-exp
  98. ;   (datum number?))
  99. ;  (var-exp
  100. ;   (id symbol?))
  101. ;  (primapp-exp
  102. ;   (prim primitive?)
  103. ;   (rands (list-of expression?)))
  104. ;  (if-exp
  105. ;   (test-exp expression?)
  106. ;   (true-exp expression?)
  107. ;   (false-exp expression?))
  108. ;  (let-exp
  109. ;   (ids (list-of symbol?))
  110. ;   (rans (list-of expression?))
  111. ;   (body expression?))
  112. ;  (proc-exp
  113. ;   (ids (list-of symbol?))
  114. ;   (body expression?))
  115. ;  (app-exp
  116. ;   (proc expression?)
  117. ;   (args (list-of expression?))))
  118.  
  119. ;
  120. ;(define-datatype primitive primitive?
  121. ;  (add-prim)
  122. ;  (substract-prim)
  123. ;  (mult-prim)
  124. ;  (incr-prim)
  125. ;  (decr-prim))
  126.  
  127. ;Construidos automáticamente:
  128.  
  129. (sllgen:make-define-datatypes scanner-spec-simple-interpreter grammar-simple-interpreter)
  130.  
  131. (define show-the-datatypes
  132.   (lambda () (sllgen:list-define-datatypes scanner-spec-simple-interpreter grammar-simple-interpreter)))
  133.  
  134. ;*******************************************************************************************
  135. ;Parser, Scanner, Interfaz
  136.  
  137. ;El FrontEnd (Análisis léxico (scanner) y sintáctico (parser) integrados)
  138.  
  139. (define scan&parse
  140.   (sllgen:make-string-parser scanner-spec-simple-interpreter grammar-simple-interpreter))
  141.  
  142. ;El Analizador Léxico (Scanner)
  143.  
  144. (define just-scan
  145.   (sllgen:make-string-scanner scanner-spec-simple-interpreter grammar-simple-interpreter))
  146.  
  147. ;El Interpretador (FrontEnd + Evaluación + señal para lectura )
  148.  
  149. (define interpretador
  150.   (sllgen:make-rep-loop  "--> "
  151.     (lambda (pgm) (eval-program  pgm))
  152.     (sllgen:make-stream-parser
  153.       scanner-spec-simple-interpreter
  154.       grammar-simple-interpreter)))
  155.  
  156. ;*******************************************************************************************
  157. ;El Interprete
  158.  
  159. ;eval-program: <programa> -> numero
  160. ; función que evalúa un programa teniendo en cuenta un ambiente dado (se inicializa dentro del programa)
  161.  
  162. (define eval-program
  163.   (lambda (pgm)
  164.     (cases program pgm
  165.       (a-program (body)
  166.                  (eval-expression body (init-env))))))
  167.  
  168. ; Ambiente inicial
  169. ;(define init-env
  170. ;  (lambda ()
  171. ;    (extend-env
  172. ;     '(x y z)
  173. ;     '(4 2 5)
  174. ;     (empty-env))))
  175. (define init-env
  176.     (lambda ()
  177.         (empty-env)
  178.     )
  179. )
  180.  
  181. ;eval-expression: <expression> <enviroment> -> numero
  182. ; evalua la expresión en el ambiente de entrada
  183. (define eval-expression
  184.     (lambda (exp env)
  185.         (cases expression exp
  186.  
  187.             (lit-exp (datum) datum)
  188.  
  189.             (var-exp (id)
  190.                 (if  (procval? (apply-env env id))
  191.                     (list id (apply-env env id))
  192.                     (apply-env env id)
  193.                 )
  194.             )
  195.  
  196.             (primapp-exp (prim rands)
  197.                 (let (  
  198.                         [args (eval-rands rands env) ]
  199.                     )
  200.                     (apply-primitive prim args)
  201.                 )
  202.             )
  203.  
  204.             (if-exp (test-exp true-exp false-exp)
  205.  
  206.                 (if (true-value? (eval-expression test-exp env  ) )
  207.                     (eval-expression true-exp env)
  208.                     (eval-expression false-exp env)
  209.                 )
  210.  
  211.             )
  212.  
  213.             (atleast-exp (number-at-least list-of-expressions)
  214.  
  215.                 (define x 0)
  216.                 (for-each
  217.                     (lambda (arg)
  218.                         (if (true-value? (eval-expression arg env))
  219.                             (set! x (+ x 1))
  220.                             #f
  221.                         )
  222.                     )
  223.                     list-of-expressions
  224.                 )
  225.                 (if (or (> x (eval-expression number-at-least env)) (= x (eval-expression number-at-least env)))
  226.                     #t
  227.                     #f
  228.                 )
  229.  
  230.             )
  231.  
  232.             (arity-exp (proc)
  233.                 (if (procval? (eval-expression proc env) )
  234.                     (cases procval (eval-expression proc env )
  235.                         (closure (ids body env)
  236.                             (length ids)
  237.                         )
  238.                     )
  239.                     (eopl:error "No corresponde a un procedimiento")
  240.                 )
  241.             )
  242.  
  243.             (let-exp (ids rands body)
  244.                 (let (  
  245.                         [args (eval-rands rands env) ]
  246.                     )
  247.                     (eval-expression body (extend-env ids args env))
  248.                 )
  249.             )
  250.  
  251.             (proc-exp (ids body)
  252.                 (closure ids body env)
  253.             )
  254.  
  255.             (app-exp (rator rands)
  256.                 (let (
  257.                         [proc (cadr (eval-expression rator env))]
  258.                         [args (eval-rands rands env)]
  259.                     )
  260.                     (if (procval? proc)
  261.                         (cases procval proc
  262.                             (closure (ids body env)
  263.                                 (if (= (length ids) (length args))
  264.                                     (apply-procedure proc args)
  265.                                     (apply-procedure (apply-env env (car (eval-expression rator env) )) args)
  266.                                 )
  267.                             )
  268.                         )
  269.                         (eopl:error 'eval-expression "Attempt to apply non-procedure ~s" proc)
  270.                     )
  271.                 )
  272.             )
  273.  
  274.             (bst-exp (abb) (if (abb-order? abb) abb (eopl:error 'eval-expression
  275.                                  "Not an ABB")))
  276.             (bst-push-exp (number abb) (abb-insert number (eval-expression abb env))) ; Punto 5.2.a) push <number> to <abb>
  277.             (preorder-bst-exp (abb) (pre-order (eval-expression abb env)))            ; punto 5.2.b) preorder <abb>
  278.             (in-bst-exp (number abb) (in-abb? number (eval-expression abb env)))
  279.  
  280.             (eclipse-exp (sym)
  281.               (eclipse env sym )
  282.             )
  283.  
  284.         )
  285.     )
  286. )
  287.  
  288. ; funciones auxiliares para aplicar eval-expression a cada elemento de una
  289. ; lista de operandos (expresiones)
  290. (define eval-rands
  291.   (lambda (rands env)
  292.     (map (lambda (x) (eval-rand x env)) rands)))
  293.  
  294. (define eval-rand
  295.   (lambda (rand env)
  296.     (eval-expression rand env)))
  297.  
  298. ;apply-primitive: <primitiva> <list-of-expression> -> numero
  299. (define apply-primitive
  300.   (lambda (prim args)
  301.     (cases primitive prim
  302.       (add-prim () (+ (car args) (cadr args)))
  303.       (substract-prim () (- (car args) (cadr args)))
  304.       (mult-prim () (* (car args) (cadr args)))
  305.       (incr-prim () (+ (car args) 1))
  306.       (decr-prim () (- (car args) 1)))))
  307.  
  308. ;true-value?: determina si un valor dado corresponde a un valor booleano falso o verdadero
  309. (define true-value?
  310.   (lambda (x)
  311.     (not (zero? x))))
  312.  
  313. ;*******************************************************************************************
  314. ;Procedimientos
  315. (define-datatype procval procval?
  316.   (closure
  317.    (ids (list-of symbol?))
  318.    (body expression?)
  319.    (env environment?)))
  320.  
  321. ;apply-procedure: evalua el cuerpo de un procedimientos en el ambiente extendido correspondiente
  322. (define apply-procedure
  323.   (lambda (proc args)
  324.     (cases procval proc
  325.       (closure (ids body env)
  326.                (eval-expression body (extend-env ids args env))))))
  327.  
  328. ;*******************************************************************************************
  329. ;Ambientes
  330.  
  331. ;definición del tipo de dato ambiente
  332. (define-datatype environment environment?
  333.   (empty-env-record)
  334.   (extended-env-record (syms (list-of symbol?))
  335.                        (vals (list-of scheme-value?))
  336.                        (env environment?)))
  337.  
  338. (define scheme-value? (lambda (v) #t))
  339.  
  340. ;empty-env:      -> enviroment
  341. ;función que crea un ambiente vacío
  342. (define empty-env  
  343.   (lambda ()
  344.     (empty-env-record)))       ;llamado al constructor de ambiente vacío
  345.  
  346.  
  347. ;extend-env: <list-of symbols> <list-of numbers> enviroment -> enviroment
  348. ;función que crea un ambiente extendido
  349. (define extend-env
  350.     (lambda (syms vals env)
  351.         (extended-env-record syms vals env)
  352.     )
  353. )
  354.  
  355. ;función que busca un símbolo en un ambiente
  356. (define apply-env
  357.     (lambda (env sym)
  358.         (cases environment env
  359.             (empty-env-record ()
  360.                 (eopl:error 'apply-env "No binding for ~s" sym)
  361.             )
  362.             (extended-env-record (syms vals env)
  363.                 (let (  (pos (list-find-position sym syms) ) )
  364.                     (if (number? pos)
  365.                         (list-ref vals pos)
  366.                         (apply-env env sym)
  367.                     )
  368.                 )
  369.             )
  370.         )
  371.     )
  372. )
  373.  
  374. (define eclipse
  375.     (lambda (env sym)
  376.         (cases environment env
  377.             (empty-env-record ()
  378.                 0
  379.             )
  380.             (extended-env-record (syms vals env)
  381.                 (let (  (pos (list-find-position sym syms) ) )
  382.                     (if (number? pos)
  383.                         (+ 1 (eclipse env sym))
  384.                         (+ 0 (eclipse env sym))
  385.                     )
  386.                 )
  387.             )
  388.         )
  389.     )
  390. )
  391.  
  392. ;****************************************************************************************
  393. ;Funciones Auxiliares
  394.  
  395. ; funciones auxiliares para encontrar la posición de un símbolo
  396. ; en la lista de símbolos de unambiente
  397.  
  398. (define list-find-position
  399.   (lambda (sym los)
  400.     (list-index (lambda (sym1) (eqv? sym1 sym)) los)))
  401.  
  402. (define list-index
  403.   (lambda (pred ls)
  404.     (cond
  405.       ((null? ls) #f)
  406.       ((pred (car ls)) 0)
  407.       (else (let ((list-index-r (list-index pred (cdr ls))))
  408.               (if (number? list-index-r)
  409.                 (+ list-index-r 1)
  410.                 #f))))))
  411.  
  412. ;---------------------------------------------------------------------------------------------------------------
  413. ; Añadiendo BST al Interpretador - Funciones Auxiliares - Inicio
  414.  
  415. ; Propiedad de orden abb-order-aux?: valida que una determinada raiz
  416. ; sea mayor o menor, según operador ingresado, a todos los nodos de un lado
  417. (define abb-order-aux?
  418.   (lambda (op root tree)
  419.     (cases abb tree
  420.       (empty () #t)
  421.       (leaf (value) (op root value))
  422.       (node (value l-node r-node)
  423.             (if (op root value)
  424.                 (and (abb-order-aux? op root l-node) (abb-order-aux? op root r-node))
  425.                 #f)))))
  426.  
  427.  
  428. ; Propiedad de orden abb-order?: valida la propiedad de orden de un arbol binario de busqueda
  429. (define abb-order?
  430.   (lambda (tree)
  431.     (cases abb tree
  432.       (empty () #t)
  433.       (leaf (value) #t)
  434.       (node (value l-node r-node)
  435.             (and
  436.              (and (abb-order-aux? > value l-node)
  437.                   (abb-order? l-node))
  438.              (and (abb-order-aux? < value r-node)
  439.                   (abb-order? r-node)))))))
  440.  
  441.  
  442. ; Funcion abb-insert: inserta un elemento en un ABB, valida la propiedad de orden del ABB
  443. (define abb-insert
  444.   (lambda (elem tree)
  445.     (cond
  446.       [(abb-order? tree) (abb-insert-aux elem tree)]
  447.       [else (eopl:error 'abb-insert "Expected Binary Search Tree, given ~s" tree)])))
  448.  
  449.  
  450. ; Funcion auxiliar abb-insert-aux: inserta un elemento a un ABB una vez validada su propiedad de orden
  451. (define abb-insert-aux
  452.   (lambda (elem tree)
  453.     (cases abb tree
  454.       (empty () (leaf elem))
  455.       (leaf (value) (if (< elem value)
  456.                         (node value (leaf elem) (empty))
  457.                         (node value (empty) (leaf elem))))
  458.       (node (value l-node r-node) (if (eqv? elem value) tree
  459.                                              (if (< elem value)
  460.                                                  (node value (abb-insert-aux elem l-node) r-node)
  461.                                                  (node value l-node (abb-insert-aux elem r-node))))))))
  462.  
  463.  
  464. ; Recorrido pre-orden: root-left-right
  465. (define pre-order
  466.   (lambda (tree)
  467.     (cases abb tree
  468.       (empty () '())
  469.       (leaf (value) (list value))
  470.       (node (value l-node r-node) (append (list value) (pre-order l-node) (pre-order r-node))))))
  471.  
  472.  
  473. ; Verificar si un número (elemento) está en un ABB:
  474. (define in-abb?
  475.   (lambda (number tree)
  476.     (cases abb tree
  477.       (empty () #f)
  478.       (leaf (value) (if (eqv? number value) #t #f))
  479.       (node (value l-node r-node) (if (eqv? number value) #t (if (< number value)
  480.                                                                  (in-abb? number l-node)
  481.                                                                  (in-abb? number r-node)))))))
  482.  
  483.  
  484. ; Añadiendo BST al Interpretador - Funciones Auxiliares - Final
  485. ;---------------------------------------------------------------------------------------------------------------
  486.  
  487. ;******************************************************************************************
  488. ;Pruebas
  489.  
  490. (show-the-datatypes)
  491. just-scan
  492. scan&parse
  493. (just-scan "add1(x)")
  494. (just-scan "add1(   x   )%cccc")
  495. (just-scan "add1(  +(5, x)   )%cccc")
  496. (just-scan "add1(  +(5, %ccccc x) ")
  497. (scan&parse "add1(x)")
  498. (scan&parse "add1(   x   )%cccc")
  499. (scan&parse "add1(  +(5, x)   )%cccc")
  500. (scan&parse "add1(  +(5, %cccc
  501. x)) ")
  502. (scan&parse "if -(x,4) then +(y,11) else *(y,10)")
  503. (scan&parse "let
  504. x = -(y,1)
  505. in
  506. let
  507. x = +(x,2)
  508. in
  509. add1(x)")
  510.  
  511. (define caso1 (primapp-exp (incr-prim) (list (lit-exp 5))))
  512. (define exp-numero (lit-exp 8))
  513. (define exp-ident (var-exp 'c))
  514. (define exp-app (primapp-exp (add-prim) (list exp-numero exp-ident)))
  515. (define programa (a-program exp-app))
  516. (define una-expresion-dificil (primapp-exp (mult-prim)
  517.                                            (list (primapp-exp (incr-prim)
  518.                                                               (list (var-exp 'v)
  519.                                                                     (var-exp 'y)))
  520.                                                  (var-exp 'x)
  521.                                                  (lit-exp 200))))
  522. (define un-programa-dificil
  523.     (a-program una-expresion-dificil))
  524.  
  525. (interpretador)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement