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
.
- SExprParser.hs
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]]