Guest User

Untitled

a guest
Nov 18th, 2018
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.34 KB | None | 0 0
  1. --Ernesto Z. Maya Díaz
  2. --Lenguajes de Programación
  3.  
  4.  
  5. {-
  6. E::= N |E Ope E|(E)
  7. N::= D|N
  8. D::= 0|1|2|3|4|5|6|7|8|9
  9. Ope::= +|*|-|/
  10. -}
  11.  
  12. import Data.Char
  13. type ID = String
  14.  
  15. --Tipo de dato para generar el arbol de Sintaxis abstracta de los parentesis balanceados
  16. data Tokens = ParA
  17. | ParC
  18. | Var ID
  19. | Num Int
  20. | Ope Char
  21. | PReser String
  22. deriving (Show,Eq)
  23.  
  24. -- Transforma una cadena en tokens que nuestro programa sabra interpretar
  25.  
  26. lexer :: String -> [Tokens]
  27. lexer [] = []
  28. lexer ('(' : xs) = ParA: (lexer xs)
  29. lexer (')' : xs) = ParC: (lexer xs)
  30. lexer ('+' : xs) = Ope '+': (lexer xs)
  31. lexer ('-' : xs) = Ope '-': (lexer xs)
  32. lexer ('*' : xs) = Ope '*': (lexer xs)
  33. lexer ('/' : xs) = Ope '/': (lexer xs)
  34. lexer ('^' : xs) = Ope '^': (lexer xs)
  35. lexer ('<' : xs) = Ope '<': (lexer xs)
  36. lexer ('>' : xs) = Ope '>': (lexer xs)
  37. lexer ('=' : xs) = Ope '=': (lexer xs)
  38. lexer ('&' : xs) = Ope '&': (lexer xs)
  39. lexer ('!' : xs) = Ope '!': (lexer xs)
  40. lexer ('|' : '|' : xs) = Ope '|': (lexer xs)
  41. lexer ('%' : '&' : xs) = Ope '%': (lexer xs)
  42. --Ahora las palabras reservadas como tokens
  43. lexer ('i':'f': xs) = PReser "if":(lexer xs)
  44. lexer ('t':'h':'e':'n': xs) = PReser "then":(lexer xs)
  45. lexer ('e':'l': 's':'e': xs) = PReser "else":(lexer xs)
  46. lexer ('l':'e':'t' : xs) = PReser "let":(lexer xs)
  47. lexer ('i': 'n' : xs) = PReser "in":(lexer xs)
  48. lexer ('t': 'r' : 'u' : 'e' :xs) = PReser "true":(lexer xs)
  49. lexer ('f': 'a' : 'l' : 's' : 'e' : xs) = PReser "false":(lexer xs)
  50. --Se toma si es variable (puede ser un numero, una variable)
  51. --Si es digito entonces lo transforma en entero con Num "Num 2" y
  52. --el resto se verifica con más numeros
  53. lexer (x:xs)
  54. --Los espacios en blanco dan una excepcion asi que tambien se toman en cuenta
  55. -- lexer (" ")
  56. | isSpace x = lexer xs
  57. |isAlpha x = Var v : (lexer c)
  58. |isDigit x = Num (string2int n1):(lexer c1)
  59. where (v,c) = leeVar(x:xs)
  60. (n1, c1) = leeNum(x:xs)
  61.  
  62. --Leer Variable busca si es una char con función isLetter
  63. leeVar::String->(String, String)
  64. leeVar [] = ("","")
  65. leeVar (x:xs) = (takeWhile (isLetter) (x:xs), dropWhile (isLetter) (x:xs))
  66.  
  67.  
  68. --Leer Una cadena y transformarla en entero
  69. string2int::String->Int
  70. string2int [] = 0
  71. --con la funcion char-> a entero lo multiplica por unidades, decenas, centenas...
  72. string2int (x:xs) = (char2int x)*(10^(length xs)) + string2int xs
  73.  
  74. --Función para convertir un char en numero entero
  75. --Pruebas
  76. --char2int '7' -> 7
  77.  
  78. char2int::Char->Int
  79. char2int x | x == '0' = 0 | x == '1' = 1 | x == '2' = 2 | x == '3' = 3 | x == '4' = 4 | x == '5' = 5 | x == '6' = 6 | x == '7' = 7 | x == '8' = 8 | x == '9' = 9
  80.  
  81. --Solamente toma digitos
  82. leeNum::String->(String, String)
  83. leeNum [] = ("","")
  84. leeNum (x:xs)= (takeWhile (isDigit) (x:xs), dropWhile (isDigit) (x:xs))
  85.  
  86.  
  87. --Pruebas
  88. --lexer "+" -> [Ope]
  89. --lexer ")" -> [ParC]
  90. --lexer "osino" -> [PReser "osino"]
  91. --lexer "7" -> [Num 7]
  92. -- lexer "(3+4)" ->[ParA,Num 3,Ope,Num 4,ParC]
  93.  
  94. --Definimos la Exp Aritmetica
  95. --18/11/2018 se ingresaon AND, OR, NOT
  96. --And exp exp, Or exp exp, Not exp exp
  97. data EA = Constante Int | Resta EA EA | Suma EA EA| Mult EA EA | Div EA EA | Let EA ID EA | If EA EA EA | Vari ID | Potencia EA EA | Invo ID EA | And EA EA | Or EA EA | Not EA EA
  98. deriving (Show,Eq)
  99.  
  100. --Puede ser una exp (Exp), termino (T)
  101. {-
  102. Exp :: = N | (Exp + Exp) | (Exp - Exp) | (Exp * Exp) |
  103. tres opciones
  104. E :: = N | (E) | + E E | * E E
  105. E :: = N | (+ E E) | (* E E)
  106. E :: = V | N | (E + E) | (E * E) | (let E ID E) | (NameF E) Se escogio esta forma
  107. -}
  108.  
  109. parser::[Tokens]->EA
  110. parser t = case (parseParen t) of
  111. (exp,[]) -> exp
  112. _ -> error "faltan parentesis o la expresion es nula"
  113. --Funcion parserAux que verifica las operaciones con Ope
  114. parseAux::[Tokens]->(EA,[Tokens])
  115. parseAux t = let (e1,token1) = parseParen t
  116. in case token1 of
  117. [] -> (e1 , [])
  118. (Ope '+':xs) -> let(e2,token2) = parseParen xs
  119. in (Suma e1 e2, token2)
  120. (Ope '-':xs) -> let(e2,token2) = parseParen xs
  121. in (Resta e1 e2, token2)
  122. (Ope '*':xs) -> let(e2,token2) = parseParen xs
  123. in (Mult e1 e2, token2)
  124. (Ope '/':xs) -> let(e2,token2) = parseParen xs
  125. in (Div e1 e2, token2)
  126. (Ope '^':xs) -> let(e2,token2) = parseParen xs
  127. in (Potencia e1 e2, token2)
  128. (Ope '&':xs) -> let(e2,token2) = parseParen xs
  129. in (And e1 e2, token2)
  130. (Ope '|':xs) -> let(e2,token2) = parseParen xs
  131. in (Or e1 e2, token2)
  132. (Ope '!':xs) -> let(e2,token2) = parseParen xs
  133. in (Not e1 e2, token2)
  134. _ -> (e1 , token1)
  135.  
  136. --Funcion parser para los parentesis
  137. parseParen::[Tokens]-> (EA,[Tokens])
  138. parseParen (Var id:xs) = (Vari id , xs)
  139. parseParen (ParA:Var v:xs) = let(e1,token1) = parseAux xs
  140. in case token1 of
  141. (ParC:token2) -> (Invo v e1,token2)
  142. parseParen (Num n:xs) = (Constante n , xs)
  143. parseParen (ParA:xs) = let(e1,resto) = parseAux xs
  144. in case resto of
  145. (ParC:resto) -> (e1,resto)
  146. _ -> (e1,resto)--error("falta un ParC" ++ show resto)
  147. parseParen (PReser "let":Var id:Ope '=':xs) = let(e1, token1) = parseAux xs
  148. in case token1 of
  149. --Si contiene palabra reservada
  150. (PReser "in":xs) -> let (e2, token3) = parseAux xs
  151. in (Let e1 id e2, token3)
  152. --parse if, palabras reservadas if then else idea igual que let, dos casos
  153. parseParen(PReser "if":xs) = let (e,token) = parseAux xs
  154. in case token of
  155. (PReser "then":token1) -> let (body, token2) = parseAux token1
  156. --Ahora si no se cumple va con else
  157. in case token2 of
  158. (PReser "else":token3) -> let (body1,token4) = parseAux token3 in (If e body body1, token4)
  159.  
  160. --Pruebas
  161. {-
  162. parser (lexer "6")
  163. Constante 6
  164.  
  165. parser (lexer "(6 + (8+9))")
  166. Suma (Constante 6) (Suma (Constante 8) (Constante 9))
  167. lexer "(let x=5 in x*x)"
  168. [ParA,PReser "let",Var "x",Ope '=',Num 5,PReser "in",Var "x",Ope '*',Var "x",ParC]
  169. parser (lexer "(let x=5 in x*x)")
  170. Let (Constante 5) "x" (Mult (Vari "x") (Vari "x"))
  171. --Prueba con Invo
  172. *Main> parser (lexer "(cubo x+x)")
  173. Invo "cubo" (Suma (Vari "x") (Vari "x"))
  174.  
  175.  
  176. --Pruebas parser booleanos
  177. *Main> parser(lexer"(5 & 7)")
  178. And (Constante 5) (Constante 7)
  179.  
  180. *Main> parser(lexer"(5 || 7)")
  181. Or (Constante 5) (Constante 7)
  182.  
  183. *Main> parser(lexer"(5 ! 7)")
  184. Not (Constante 5) (Constante 7)
  185.  
  186. -}
  187. --interprete
  188.  
  189. interp::EA -> Int
  190. interp (Constante n) = n
  191. interp (Vari v) = error "La variable no fue declarada"
  192. interp (Suma e1 e2) = interp e1 + interp e2
  193. interp (Mult e1 e2) = interp e1 * interp e2
  194. interp (Resta e1 e2) = interp e1 - interp e2
  195. interp (Potencia e1 e2) = interp e1 ^ interp e2
  196. interp (Let e1 x e2) = interp (sust e2 x (Constante (interp e1)))
  197. --interp (If e1 e2 e3) = if ((interp e1) == (Constante 1)) then interp e2 else interp e3
  198. interp (If e1 e2 e3) = if (interp e1) == 1 then interp e2 else interp e3
  199.  
  200. {-
  201. interp (Let variable expAcotada cuerpo) =
  202. ...
  203. Pruebas
  204. *Main> interp (parser (lexer "(8+9)"))
  205. 17
  206. *Main> interp (parser (lexer "(8*9)"))
  207. 72
  208. *Main> interp (parser (lexer "(let x=5 in x+x)"))
  209. 10
  210. -}
  211.  
  212. sust::EA -> ID -> EA -> EA
  213. ---sust expr x valor devuelve exp[x:=valor],
  214. --Nota, se espera que valor sea un asas del tipo Num n
  215. sust (Constante n) _ _ = (Constante n)
  216. sust (Vari v) x t = if (v == x) then t
  217. else (Vari v)
  218. sust (Suma e1 e2) x t = Suma (sust e1 x t)(sust e2 x t)
  219. sust (Resta e1 e2) x t = Resta (sust e1 x t)(sust e2 x t)
  220. --(x+4)[x:=5] -> (x[x:=5] + 4[x:=5]) -> (5+4)
  221. sust (Mult e1 e2) x t = Mult (sust e1 x t)(sust e2 x t)
  222. sust (Div e1 e2) x t = Div (sust e1 x t)(sust e2 x t)
  223. sust (Let e1 x e2) x1 e3 =
  224. if x1 == x then (Let (sust e1 x1 e3) x e2)
  225. else
  226. (Let (sust e1 x1 e3) x (sust e2 x1 e3))
  227. sust (If e1 e2 e3) x e = If (sust e1 x e) (sust e2 x e) (sust e3 x e)
  228.  
  229.  
  230. {-Repositorio
  231. --newType Rep = [(String, Int )]
  232. -}
  233. data R = EstaVacio | Repo ID Int R
  234.  
  235. searchR:: ID -> R -> Int
  236. searchR n EstaVacio = error ("No se hallo la variable" ++n++ "n")
  237. searchR n (Repo v valor rep)= if (n == v) then valor else searchR n rep
  238.  
  239. {-Interprete con repositorios-}
  240.  
  241. interpR::EA -> R -> Int
  242. interpR (Constante n) rep = n
  243. interpR (Vari v) rep = searchR v rep
  244. interpR (Suma e1 e2) rep = (interpR e1 rep) + (interpR e2 rep)
  245. interpR (Mult e1 e2) rep= (interpR e1 rep) * (interpR e2 rep)
  246. interpR (Resta e1 e2) rep= (interpR e1 rep) - (interpR e2 rep)
  247. interpR (Potencia e1 e2) rep= (interpR e1 rep) ^ (interpR e2 rep)
  248. interpR (Let ea v body) rep =
  249. let valor = (interpR ea rep) in
  250. interpR body (Repo v valor rep)
  251. --interpR (If e1 e2 e3) = if ((interp e1) == (Constante 1)) then interp e2 else interp e3
  252. --interpR (If e1 e2 e3) rep = if (interp e1 rep) == 1 then (interp e2 rep) else (interp e3 rep)
  253.  
  254.  
  255. {-
  256. Pruebas
  257. *Main> interpR (parser (lexer "(let x=5 in x+x)")) EstaVacio
  258. 10
  259. -}
  260.  
  261.  
  262. {-Repositorios con funciones-}
  263. --Tipo de dato para funciones
  264.  
  265. data Fun_Def = Fun ID EA EA
  266. deriving (Show)
  267.  
  268. --Nombre de la función
  269. funN :: Fun_Def -> ID
  270. funN (Fun funN _ _) = funN
  271.  
  272. --Busqueda de función
  273. sFun :: [Fun_Def]->ID -> Fun_Def
  274. sFun [] nf = error ("No se encuentra la funcion")
  275. sFun (f:fs) nf = if(nf == funN(f)) then f else sFun fs nf
  276.  
  277. --Funciones agregadas
  278. f2=Fun "potencia" (Vari "x") (Potencia (Vari "x") (Vari "x"))
  279. f1=Fun "doble" (Vari "x") (Suma (Vari "x")(Vari "x"))
  280. f3=Fun "cubo" (Vari "x") (Mult (Vari "x")(Mult(Vari "x")(Vari "x")))
  281.  
  282. --Se realiza una lista de las funciones agregadas manualmente
  283. fs = [f1 , f2 , f3]
  284.  
  285. interpRF:: EA -> R -> [Fun_Def] -> Int
  286. interpRF (Constante n) rep fs = n
  287. interpRF (Vari v) rep fs= searchR v rep
  288. interpRF (Suma e1 e2) rep fs= (interpRF e1 rep fs) + (interpRF e2 rep fs)
  289. interpRF (Mult e1 e2) rep fs= (interpRF e1 rep fs) * (interpRF e2 rep fs)
  290. interpRF (Resta e1 e2) rep fs= (interpRF e1 rep fs) - (interpRF e2 rep fs)
  291. interpRF (Potencia e1 e2) rep fs= (interpRF e1 rep fs) ^ (interpRF e2 rep fs)
  292. interpRF (Let e1 var e2) rep fs =
  293. let valor = (interpRF e1 rep fs)
  294. rep1=(Repo var valor rep) in
  295. interpRF e2 rep1 fs
  296. interpRF (Invo f x) r fs =
  297. let valorPara = interpRF x r fs
  298. (Fun nombreF (Vari nombreV) cuerpoFun) = (sFun fs f)
  299. in
  300. (interpRF cuerpoFun (Repo nombreV valorPara EstaVacio) fs)
  301. interpRF (If e1 e2 e3) rep fs = if (interpRF e1 rep fs) == 1 then interpRF e2 rep fs else interpRF e3 rep fs
  302.  
  303.  
  304.  
  305. {-
  306. pruebas
  307. *Main> interpRF(parser (lexer "(doble 5)"))EstaVacio fs
  308. 10
  309. *Main> interpRF(parser (lexer "(cubo 5)"))EstaVacio fs
  310. 125
  311. *Main> interpRF(parser (lexer "(potencia 5)"))EstaVacio fs
  312. 3125
  313. -}
Add Comment
Please, Sign In to add comment