Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Ernesto Z. Maya Díaz
- --Lenguajes de Programación
- {-
- E::= N |E Ope E|(E)
- N::= D|N
- D::= 0|1|2|3|4|5|6|7|8|9
- Ope::= +|*|-|/
- -}
- import Data.Char
- type ID = String
- --Tipo de dato para generar el arbol de Sintaxis abstracta de los parentesis balanceados
- data Tokens = ParA
- | ParC
- | Var ID
- | Num Int
- | Ope Char
- | PReser String
- deriving (Show,Eq)
- -- Transforma una cadena en tokens que nuestro programa sabra interpretar
- lexer :: String -> [Tokens]
- lexer [] = []
- lexer ('(' : xs) = ParA: (lexer xs)
- lexer (')' : xs) = ParC: (lexer xs)
- lexer ('+' : xs) = Ope '+': (lexer xs)
- lexer ('-' : xs) = Ope '-': (lexer xs)
- lexer ('*' : xs) = Ope '*': (lexer xs)
- lexer ('/' : xs) = Ope '/': (lexer xs)
- lexer ('^' : xs) = Ope '^': (lexer xs)
- lexer ('<' : xs) = Ope '<': (lexer xs)
- lexer ('>' : xs) = Ope '>': (lexer xs)
- lexer ('=' : xs) = Ope '=': (lexer xs)
- lexer ('&' : xs) = Ope '&': (lexer xs)
- lexer ('!' : xs) = Ope '!': (lexer xs)
- lexer ('|' : '|' : xs) = Ope '|': (lexer xs)
- lexer ('%' : '&' : xs) = Ope '%': (lexer xs)
- --Ahora las palabras reservadas como tokens
- lexer ('i':'f': xs) = PReser "if":(lexer xs)
- lexer ('t':'h':'e':'n': xs) = PReser "then":(lexer xs)
- lexer ('e':'l': 's':'e': xs) = PReser "else":(lexer xs)
- lexer ('l':'e':'t' : xs) = PReser "let":(lexer xs)
- lexer ('i': 'n' : xs) = PReser "in":(lexer xs)
- lexer ('t': 'r' : 'u' : 'e' :xs) = PReser "true":(lexer xs)
- lexer ('f': 'a' : 'l' : 's' : 'e' : xs) = PReser "false":(lexer xs)
- --Se toma si es variable (puede ser un numero, una variable)
- --Si es digito entonces lo transforma en entero con Num "Num 2" y
- --el resto se verifica con más numeros
- lexer (x:xs)
- --Los espacios en blanco dan una excepcion asi que tambien se toman en cuenta
- -- lexer (" ")
- | isSpace x = lexer xs
- |isAlpha x = Var v : (lexer c)
- |isDigit x = Num (string2int n1):(lexer c1)
- where (v,c) = leeVar(x:xs)
- (n1, c1) = leeNum(x:xs)
- --Leer Variable busca si es una char con función isLetter
- leeVar::String->(String, String)
- leeVar [] = ("","")
- leeVar (x:xs) = (takeWhile (isLetter) (x:xs), dropWhile (isLetter) (x:xs))
- --Leer Una cadena y transformarla en entero
- string2int::String->Int
- string2int [] = 0
- --con la funcion char-> a entero lo multiplica por unidades, decenas, centenas...
- string2int (x:xs) = (char2int x)*(10^(length xs)) + string2int xs
- --Función para convertir un char en numero entero
- --Pruebas
- --char2int '7' -> 7
- char2int::Char->Int
- 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
- --Solamente toma digitos
- leeNum::String->(String, String)
- leeNum [] = ("","")
- leeNum (x:xs)= (takeWhile (isDigit) (x:xs), dropWhile (isDigit) (x:xs))
- --Pruebas
- --lexer "+" -> [Ope]
- --lexer ")" -> [ParC]
- --lexer "osino" -> [PReser "osino"]
- --lexer "7" -> [Num 7]
- -- lexer "(3+4)" ->[ParA,Num 3,Ope,Num 4,ParC]
- --Definimos la Exp Aritmetica
- --18/11/2018 se ingresaon AND, OR, NOT
- --And exp exp, Or exp exp, Not exp exp
- 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
- deriving (Show,Eq)
- --Puede ser una exp (Exp), termino (T)
- {-
- Exp :: = N | (Exp + Exp) | (Exp - Exp) | (Exp * Exp) |
- tres opciones
- E :: = N | (E) | + E E | * E E
- E :: = N | (+ E E) | (* E E)
- E :: = V | N | (E + E) | (E * E) | (let E ID E) | (NameF E) Se escogio esta forma
- -}
- parser::[Tokens]->EA
- parser t = case (parseParen t) of
- (exp,[]) -> exp
- _ -> error "faltan parentesis o la expresion es nula"
- --Funcion parserAux que verifica las operaciones con Ope
- parseAux::[Tokens]->(EA,[Tokens])
- parseAux t = let (e1,token1) = parseParen t
- in case token1 of
- [] -> (e1 , [])
- (Ope '+':xs) -> let(e2,token2) = parseParen xs
- in (Suma e1 e2, token2)
- (Ope '-':xs) -> let(e2,token2) = parseParen xs
- in (Resta e1 e2, token2)
- (Ope '*':xs) -> let(e2,token2) = parseParen xs
- in (Mult e1 e2, token2)
- (Ope '/':xs) -> let(e2,token2) = parseParen xs
- in (Div e1 e2, token2)
- (Ope '^':xs) -> let(e2,token2) = parseParen xs
- in (Potencia e1 e2, token2)
- (Ope '&':xs) -> let(e2,token2) = parseParen xs
- in (And e1 e2, token2)
- (Ope '|':xs) -> let(e2,token2) = parseParen xs
- in (Or e1 e2, token2)
- (Ope '!':xs) -> let(e2,token2) = parseParen xs
- in (Not e1 e2, token2)
- _ -> (e1 , token1)
- --Funcion parser para los parentesis
- parseParen::[Tokens]-> (EA,[Tokens])
- parseParen (Var id:xs) = (Vari id , xs)
- parseParen (ParA:Var v:xs) = let(e1,token1) = parseAux xs
- in case token1 of
- (ParC:token2) -> (Invo v e1,token2)
- parseParen (Num n:xs) = (Constante n , xs)
- parseParen (ParA:xs) = let(e1,resto) = parseAux xs
- in case resto of
- (ParC:resto) -> (e1,resto)
- _ -> (e1,resto)--error("falta un ParC" ++ show resto)
- parseParen (PReser "let":Var id:Ope '=':xs) = let(e1, token1) = parseAux xs
- in case token1 of
- --Si contiene palabra reservada
- (PReser "in":xs) -> let (e2, token3) = parseAux xs
- in (Let e1 id e2, token3)
- --parse if, palabras reservadas if then else idea igual que let, dos casos
- parseParen(PReser "if":xs) = let (e,token) = parseAux xs
- in case token of
- (PReser "then":token1) -> let (body, token2) = parseAux token1
- --Ahora si no se cumple va con else
- in case token2 of
- (PReser "else":token3) -> let (body1,token4) = parseAux token3 in (If e body body1, token4)
- --Pruebas
- {-
- parser (lexer "6")
- Constante 6
- parser (lexer "(6 + (8+9))")
- Suma (Constante 6) (Suma (Constante 8) (Constante 9))
- lexer "(let x=5 in x*x)"
- [ParA,PReser "let",Var "x",Ope '=',Num 5,PReser "in",Var "x",Ope '*',Var "x",ParC]
- parser (lexer "(let x=5 in x*x)")
- Let (Constante 5) "x" (Mult (Vari "x") (Vari "x"))
- --Prueba con Invo
- *Main> parser (lexer "(cubo x+x)")
- Invo "cubo" (Suma (Vari "x") (Vari "x"))
- --Pruebas parser booleanos
- *Main> parser(lexer"(5 & 7)")
- And (Constante 5) (Constante 7)
- *Main> parser(lexer"(5 || 7)")
- Or (Constante 5) (Constante 7)
- *Main> parser(lexer"(5 ! 7)")
- Not (Constante 5) (Constante 7)
- -}
- --interprete
- interp::EA -> Int
- interp (Constante n) = n
- interp (Vari v) = error "La variable no fue declarada"
- interp (Suma e1 e2) = interp e1 + interp e2
- interp (Mult e1 e2) = interp e1 * interp e2
- interp (Resta e1 e2) = interp e1 - interp e2
- interp (Potencia e1 e2) = interp e1 ^ interp e2
- interp (Let e1 x e2) = interp (sust e2 x (Constante (interp e1)))
- --interp (If e1 e2 e3) = if ((interp e1) == (Constante 1)) then interp e2 else interp e3
- interp (If e1 e2 e3) = if (interp e1) == 1 then interp e2 else interp e3
- {-
- interp (Let variable expAcotada cuerpo) =
- ...
- Pruebas
- *Main> interp (parser (lexer "(8+9)"))
- 17
- *Main> interp (parser (lexer "(8*9)"))
- 72
- *Main> interp (parser (lexer "(let x=5 in x+x)"))
- 10
- -}
- sust::EA -> ID -> EA -> EA
- ---sust expr x valor devuelve exp[x:=valor],
- --Nota, se espera que valor sea un asas del tipo Num n
- sust (Constante n) _ _ = (Constante n)
- sust (Vari v) x t = if (v == x) then t
- else (Vari v)
- sust (Suma e1 e2) x t = Suma (sust e1 x t)(sust e2 x t)
- sust (Resta e1 e2) x t = Resta (sust e1 x t)(sust e2 x t)
- --(x+4)[x:=5] -> (x[x:=5] + 4[x:=5]) -> (5+4)
- sust (Mult e1 e2) x t = Mult (sust e1 x t)(sust e2 x t)
- sust (Div e1 e2) x t = Div (sust e1 x t)(sust e2 x t)
- sust (Let e1 x e2) x1 e3 =
- if x1 == x then (Let (sust e1 x1 e3) x e2)
- else
- (Let (sust e1 x1 e3) x (sust e2 x1 e3))
- sust (If e1 e2 e3) x e = If (sust e1 x e) (sust e2 x e) (sust e3 x e)
- {-Repositorio
- --newType Rep = [(String, Int )]
- -}
- data R = EstaVacio | Repo ID Int R
- searchR:: ID -> R -> Int
- searchR n EstaVacio = error ("No se hallo la variable" ++n++ "n")
- searchR n (Repo v valor rep)= if (n == v) then valor else searchR n rep
- {-Interprete con repositorios-}
- interpR::EA -> R -> Int
- interpR (Constante n) rep = n
- interpR (Vari v) rep = searchR v rep
- interpR (Suma e1 e2) rep = (interpR e1 rep) + (interpR e2 rep)
- interpR (Mult e1 e2) rep= (interpR e1 rep) * (interpR e2 rep)
- interpR (Resta e1 e2) rep= (interpR e1 rep) - (interpR e2 rep)
- interpR (Potencia e1 e2) rep= (interpR e1 rep) ^ (interpR e2 rep)
- interpR (Let ea v body) rep =
- let valor = (interpR ea rep) in
- interpR body (Repo v valor rep)
- --interpR (If e1 e2 e3) = if ((interp e1) == (Constante 1)) then interp e2 else interp e3
- --interpR (If e1 e2 e3) rep = if (interp e1 rep) == 1 then (interp e2 rep) else (interp e3 rep)
- {-
- Pruebas
- *Main> interpR (parser (lexer "(let x=5 in x+x)")) EstaVacio
- 10
- -}
- {-Repositorios con funciones-}
- --Tipo de dato para funciones
- data Fun_Def = Fun ID EA EA
- deriving (Show)
- --Nombre de la función
- funN :: Fun_Def -> ID
- funN (Fun funN _ _) = funN
- --Busqueda de función
- sFun :: [Fun_Def]->ID -> Fun_Def
- sFun [] nf = error ("No se encuentra la funcion")
- sFun (f:fs) nf = if(nf == funN(f)) then f else sFun fs nf
- --Funciones agregadas
- f2=Fun "potencia" (Vari "x") (Potencia (Vari "x") (Vari "x"))
- f1=Fun "doble" (Vari "x") (Suma (Vari "x")(Vari "x"))
- f3=Fun "cubo" (Vari "x") (Mult (Vari "x")(Mult(Vari "x")(Vari "x")))
- --Se realiza una lista de las funciones agregadas manualmente
- fs = [f1 , f2 , f3]
- interpRF:: EA -> R -> [Fun_Def] -> Int
- interpRF (Constante n) rep fs = n
- interpRF (Vari v) rep fs= searchR v rep
- interpRF (Suma e1 e2) rep fs= (interpRF e1 rep fs) + (interpRF e2 rep fs)
- interpRF (Mult e1 e2) rep fs= (interpRF e1 rep fs) * (interpRF e2 rep fs)
- interpRF (Resta e1 e2) rep fs= (interpRF e1 rep fs) - (interpRF e2 rep fs)
- interpRF (Potencia e1 e2) rep fs= (interpRF e1 rep fs) ^ (interpRF e2 rep fs)
- interpRF (Let e1 var e2) rep fs =
- let valor = (interpRF e1 rep fs)
- rep1=(Repo var valor rep) in
- interpRF e2 rep1 fs
- interpRF (Invo f x) r fs =
- let valorPara = interpRF x r fs
- (Fun nombreF (Vari nombreV) cuerpoFun) = (sFun fs f)
- in
- (interpRF cuerpoFun (Repo nombreV valorPara EstaVacio) fs)
- interpRF (If e1 e2 e3) rep fs = if (interpRF e1 rep fs) == 1 then interpRF e2 rep fs else interpRF e3 rep fs
- {-
- pruebas
- *Main> interpRF(parser (lexer "(doble 5)"))EstaVacio fs
- 10
- *Main> interpRF(parser (lexer "(cubo 5)"))EstaVacio fs
- 125
- *Main> interpRF(parser (lexer "(potencia 5)"))EstaVacio fs
- 3125
- -}
Add Comment
Please, Sign In to add comment