[Haskell-beginners] parsec question
Michael Mossey
mpm at alumni.caltech.edu
Mon Jul 19 03:41:01 EDT 2010
Here's what I eventually came up with. I decided to make a function
parseArg that can parse either "v" args or "c" args, and use
sepBy parseArg space
to parse all the args on the command line. I created the algebraic type
Arg to express both kinds of args, which I call Verts and Chans, so that
parseArg can have the signature
parseArg :: Parser Arg
and parsing the whole command line:
parseArgs :: Parser [Arg]
Then I grab the first Verts and first Chans from the resulting list, and
ignore the other ones (if any others are present). I use fromMaybe to
supply a default value.
data Command = Forward Int
| Backward Int
| Jump Int
| Play Int [Int]
| Quit
deriving (Show)
data Arg = Verts Int
| Chans [Int]
deriving (Show)
integer :: Parser Int
integer = do ds <- many1 digit
return (read ds)
digitList :: Parser [Int]
digitList = do d <- digit
remainder <- digitList
return $ read [d] : remainder
<|>
return []
-- Parse an argument for the p command.
-- Note that so-called "v" args are now just bare integers.
-- "c" args are still prefaced with a "c"
parseArg :: Parser Arg
parseArg = do fmap Verts integer
<|>
do char 'c'
fmap Chans digitList
parseArgs :: Parser [Arg]
parseArgs = sepBy parseArg space
parseP :: Parser Command
parseP = (do many space
-- Zero or more arguments may be present.
-- We will consider at most one "v" argument
-- and at most one "c" argument. There are
-- default values for the "V" and "C" arguments
-- when none are present.
args <- parseArgs
let vArgs = [i | Verts i <- args]
cArgs = [c | Chans c <- args]
singleV = fromMaybe 1 (listToMaybe vArgs)
singleC = fromMaybe [] (listToMaybe cArgs)
return $ Play singleV singleC)
<|>
(return $ Play 1 [])
parseCommand :: Parser Command
parseCommand = do char 'j'
fmap Jump integer
<|>
do char 'f'
fmap Forward (option 1 integer)
<|>
do char 'b'
fmap Backward (option 1 integer)
<|>
do char 'p'
parseP
<|>
do char 'q'
return Quit
runParse :: String -> Either String Command
runParse s = case parse parseCommand "" s of
Left err -> Left $ show err
Right x -> Right x
More information about the Beginners
mailing list