Advertisement
cardel

Interpreptador simple

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