====== Parsear S-Expr en Haskell ======
A continuación va la definición de un modulo Haskell para parsear s-expressions. No es necesario que entiendan su definición, pero sí deben saber usarlo. El tipo de dato para representar una s-expression es ''SExpr'', y la función de parsing se llama ''parseSExpr''.
module SExprParser (SExpr(..), parseSExpr) where
import Text.ParserCombinators.Parsec hiding (spaces)
import Control.Monad
-- representation of an s-expr
-- (improper lists are not supported)
data SExpr = Atom String
| List [SExpr]
| Number Integer
| Bool Bool
| String String
deriving Show
symbol :: Parser Char
symbol = oneOf "!#$%&|*+-/:<=>?@^_~"
spaces :: Parser ()
spaces = skipMany1 space
parseExpr = parseAtom
<|> parseNumber
<|> parseString
<|> do char '('
x <- parseList
char ')'
return x
parseAtom :: Parser SExpr
parseAtom = do first <- letter <|> symbol
rest <- many (letter <|> digit <|> symbol)
let atom = first:rest
return $ case atom of
"#t" -> Bool True
"#f" -> Bool False
_ -> Atom atom
parseList = liftM List $ sepBy parseExpr spaces
parseNumber = liftM (Number . read) $ many1 digit
parseString :: Parser SExpr
parseString = do char '"'
x <- many (noneOf "\"")
char '"'
return $ String x
parseSExpr :: String -> SExpr
parseSExpr prog = case (parse parseExpr "error" prog) of
Left e -> error $ show e
Right sexpr -> sexpr
Para usar el parser, simplemente importe ''SExprParser'' (en un archivo, o en ''ghci''):
> import SExprParser
> parseSExpr "(+ 1 (- 2 3))"
List [Atom "+",Number 1,List [Atom "-",Number 2,Number 3]]