Skip to content

Instantly share code, notes, and snippets.

@saevarb
Created July 14, 2015 15:44
Show Gist options
  • Save saevarb/28254de02670065dc785 to your computer and use it in GitHub Desktop.
Save saevarb/28254de02670065dc785 to your computer and use it in GitHub Desktop.
import Text.Parsec
import Text.Parsec.String
import Control.Monad
-- Below is the Augmented BNF description of the IRC protocol,
-- according to RFC 2812, along with parsers written using Parsec
-- in Haskell
-- Let's start with something simple
-- letter = %x41-5A / %x61-7A ; A-Z / a-z
-- Letter is either A-Z or a-z
letterP :: Parser Char
letterP = oneOf $ ['A' .. 'Z'] ++ ['a' .. 'z']
-- digit = %x30-39 ; 0-9
-- Digit is just 0-9
digitP :: Parser Char
digitP = oneOf ['0' .. '9']
-- command = 1*letter / 3digit
-- A command however is one or more letter or 3 digits.
commandP :: Parser String
commandP = (try (many1 letter) -- Try the letter parser. If it fails, backtrack.
<|> (count 3 digit)) <* eof -- If it fails, this parser is used instead.
-- The eof is there to specify that there may not be anything left in the input
-- Output from running below:
-- λ> main
-- 363
-- PRIVMSG
-- privmsg
-- PING
-- 123
-- Could not parse:
-- as123123
-- Could not parse:
-- 123123
main :: IO ()
main = do
forM_ commands $ \cmd -> do
let result = parse commandP cmd cmd
case result of
Left _ -> do
putStrLn "Could not parse:"
putStrLn $ "\t" ++ cmd
Right res' ->
putStrLn res'
return ()
where
commands =
[ "363"
, "PRIVMSG"
, "privmsg"
, "PING"
, "123"
, "as123123" -- Bad
, "123123" -- Bad
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment