Advertisement
Guest User

Interpretador shido

a guest
Jun 24th, 2019
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 8.26 KB | None | 0 0
  1. #lang eopl
  2.  ;Agregar primitiva /
  3.  ;Que las primitivas numericas puedan trabajas con más de 2 números
  4.  
  5. ;******************************************************************************************
  6. ;;;;; Interpretador Simple
  7.  
  8. ;; La definición BNF para las expresiones del lenguaje:
  9. ;;
  10. ;;  <program>       ::= <expression>
  11. ;;                      <a-program (exp)>
  12. ;;  <expression>    ::= <number>
  13. ;;                      <lit-exp (datum)>
  14. ;;                  ::= <identifier>
  15. ;;                      <var-exp (id)>
  16. ;;                  ::= <primitive> ({<expression>}*(,))
  17. ;;                      <primapp-exp (prim rands)>
  18. ;;  <primitive>     ::= + | - | * | add1 | sub1
  19.  
  20. ;******************************************************************************************
  21.  
  22. ;******************************************************************************************
  23. ;Especificación Léxica
  24.  
  25. (define scanner-spec-simple-interpreter
  26.   '((white-sp
  27.      (whitespace) skip)
  28.     (comment
  29.      ("%" (arbno (not #\newline))) skip)
  30.     (identifier
  31.      (letter (arbno (or letter digit "?"))) symbol)
  32.     (number
  33.      (digit (arbno digit)) number)
  34.     (number
  35.      ("-" digit (arbno digit)) number)))
  36.  
  37. ;Especificación Sintáctica (gramática)
  38.  
  39. (define grammar-simple-interpreter
  40.   '((program (expression) a-program)
  41.     (expression (number) lit-exp)
  42.     (expression (identifier) var-exp)
  43.     (expression
  44.      (primitive "(" (separated-list expression ",")")")
  45.      primapp-exp)
  46.     (primitive ("+") add-prim)
  47.     (primitive ("-") substract-prim)
  48.     (primitive ("*") mult-prim)
  49.     (primitive ("add1") incr-prim)
  50.     (primitive ("sub1") decr-prim)
  51.     (primitive ("/") divide-prim)
  52.     )
  53.   )
  54.  
  55.  
  56.  
  57. ;Tipos de datos para la sintaxis abstracta de la gramática
  58.  
  59. ;Construidos manualmente:
  60.  
  61. ;(define-datatype program program?
  62. ;  (a-program
  63. ;   (exp expression?)))
  64. ;
  65. ;(define-datatype expression expression?
  66. ;  (lit-exp
  67. ;   (datum number?))
  68. ;  (var-exp
  69. ;   (id symbol?))
  70. ;  (primapp-exp
  71. ;   (prim primitive?)
  72. ;   (rands (list-of expression?))))
  73. ;
  74. ;(define-datatype primitive primitive?
  75. ;  (add-prim)
  76. ;  (substract-prim)
  77. ;  (mult-prim)
  78. ;  (incr-prim)
  79. ;  (decr-prim))
  80.  
  81. ;Construidos automáticamente:
  82.  
  83. (sllgen:make-define-datatypes scanner-spec-simple-interpreter grammar-simple-interpreter)
  84.  
  85. (define show-the-datatypes
  86.   (lambda () (sllgen:list-define-datatypes scanner-spec-simple-interpreter grammar-simple-interpreter)))
  87.  
  88. ;*******************************************************************************************
  89. ;Parser, Scanner, Interfaz
  90.  
  91. ;El FrontEnd (Análisis léxico (scanner) y sintáctico (parser) integrados)
  92.  
  93. (define scan&parse
  94.   (sllgen:make-string-parser scanner-spec-simple-interpreter grammar-simple-interpreter))
  95.  
  96. ;El Analizador Léxico (Scanner)
  97.  
  98. (define just-scan
  99.   (sllgen:make-string-scanner scanner-spec-simple-interpreter grammar-simple-interpreter))
  100.  
  101. ;El Interpretador (FrontEnd + Evaluación + señal para lectura )
  102.  
  103. (define interpretador
  104.   (sllgen:make-rep-loop "--> "
  105.                         (lambda (pgm) (eval-program  pgm))
  106.                         (sllgen:make-stream-parser
  107.                          scanner-spec-simple-interpreter
  108.                          grammar-simple-interpreter)))
  109.  
  110. ;*******************************************************************************************
  111. ;El Interprete
  112.  
  113. ;eval-program: <programa> -> numero
  114. ; función que evalúa un programa teniendo en cuenta un ambiente dado (se inicializa dentro del programa)
  115.  
  116. (define eval-program
  117.   (lambda (pgm)
  118.     (cases program pgm
  119.       (a-program (body)
  120.                  (eval-expression body (init-env))))))
  121.  
  122. ; Ambiente inicial
  123. (define init-env
  124.   (lambda ()
  125.     (extend-env
  126.      '(i v x)
  127.      '(1 5 10)
  128.      (empty-env))))
  129.  
  130. ;eval-expression: <expression> <enviroment> -> numero
  131. ; evalua la expresión en el ambiente de entrada
  132. (define eval-expression
  133.   (lambda (exp env)
  134.     (cases expression exp
  135.       (lit-exp (datum) datum)
  136.       (var-exp (id) (apply-env env id))
  137.       (primapp-exp (prim rands)
  138.                    (let ((args (eval-rands rands env)))
  139.                      (apply-primitive prim args))))))
  140.  
  141. ; funciones auxiliares para aplicar eval-expression a cada elemento de una
  142. ; lista de operandos (expresiones)
  143. (define eval-rands
  144.   (lambda (rands env)
  145.     (map (lambda (x) (eval-rand x env)) rands)))
  146.  
  147. (define eval-rand
  148.   (lambda (rand env)
  149.     (eval-expression rand env)))
  150.  
  151. ;apply-primitive: <primitiva> <list-of-expression> -> numero
  152. (define apply-primitive
  153.   (lambda (prim args)
  154.     (cases primitive prim
  155.       (add-prim () (n-elementos args + 0))
  156.       (substract-prim () (n-elementos args - 0))
  157.       (mult-prim () (n-elementos args * 1))
  158.       (incr-prim () (map (lambda (x) (+ x 1)) args))
  159.       (decr-prim () (map (lambda (x) (- x 1)) args))
  160.       (divide-prim () (n-elementos args / 1))
  161.       )
  162.     )
  163.   )
  164.  
  165. (define n-elementos (lambda (lista primitiva acumulador)
  166.                       (cond
  167.                         [(null? lista) acumulador]
  168.                         [else (n-elementos (cdr lista) primitiva (primitiva acumulador (car lista)))]
  169.                              
  170.                         )
  171.                       )
  172.   )
  173.                        
  174.                          
  175.  
  176. ;*******************************************************************************************
  177. ;Ambientes
  178.  
  179. ;definición del tipo de dato ambiente
  180. (define-datatype environment environment?
  181.   (empty-env-record)
  182.   (extended-env-record (syms (list-of symbol?))
  183.                        (vals (list-of scheme-value?))
  184.                        (env environment?)))
  185.  
  186. (define scheme-value? (lambda (v) #t))
  187.  
  188. ;empty-env:      -> enviroment
  189. ;función que crea un ambiente vacío
  190. (define empty-env  
  191.   (lambda ()
  192.     (empty-env-record)))       ;llamado al constructor de ambiente vacío
  193.  
  194.  
  195. ;extend-env: <list-of symbols> <list-of numbers> enviroment -> enviroment
  196. ;función que crea un ambiente extendido
  197. (define extend-env
  198.   (lambda (syms vals env)
  199.     (extended-env-record syms vals env)))
  200.  
  201. ;función que busca un símbolo en un ambiente
  202. (define apply-env
  203.   (lambda (env sym)
  204.     (cases environment env
  205.       (empty-env-record ()
  206.                         (eopl:error 'apply-env "No binding for ~s" sym))
  207.       (extended-env-record (syms vals env)
  208.                            (let ((pos (list-find-position sym syms)))
  209.                              (if (number? pos)
  210.                                  (list-ref vals pos)
  211.                                  (apply-env env sym)))))))
  212.  
  213.  
  214. ;****************************************************************************************
  215. ;Funciones Auxiliares
  216.  
  217. ; funciones auxiliares para encontrar la posición de un símbolo
  218. ; en la lista de símbolos de unambiente
  219.  
  220. (define list-find-position
  221.   (lambda (sym los)
  222.     (list-index (lambda (sym1) (eqv? sym1 sym)) los)))
  223.  
  224. (define list-index
  225.   (lambda (pred ls)
  226.     (cond
  227.       ((null? ls) #f)
  228.       ((pred (car ls)) 0)
  229.       (else (let ((list-index-r (list-index pred (cdr ls))))
  230.               (if (number? list-index-r)
  231.                   (+ list-index-r 1)
  232.                   #f))))))
  233.  
  234. ;******************************************************************************************
  235. ;Pruebas
  236.  
  237. (show-the-datatypes)
  238. just-scan
  239. scan&parse
  240. (just-scan "add1(x)")
  241. (just-scan "add1(   x   )%cccc")
  242. (just-scan "add1(  +(5, x)   )%cccc")
  243. (just-scan "add1(  +(5, %ccccc x) ")
  244. (scan&parse "add1(x)")
  245. (scan&parse "add1(   x   )%cccc")
  246. (scan&parse "add1(  +(5, x)   )%cccc")
  247. (scan&parse "add1(  +(5, %cccc
  248. x)) ")
  249.  
  250. (define caso1 (primapp-exp (incr-prim) (list (lit-exp 5))))
  251. (define exp-numero (lit-exp 8))
  252. (define exp-ident (var-exp 'c))
  253. (define exp-app (primapp-exp (add-prim) (list exp-numero exp-ident)))
  254. (define programa (a-program exp-app))
  255. (define una-expresion-dificil (primapp-exp (mult-prim)
  256.                                            (list (primapp-exp (incr-prim)
  257.                                                               (list (var-exp 'v)
  258.                                                                     (var-exp 'y)))
  259.                                                  (var-exp 'x)
  260.                                                  (lit-exp 200))))
  261. (define un-programa-dificil
  262.   (a-program una-expresion-dificil))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement