import Control.Applicative ((<|>)) import Control.Monad (forM_) import Data.Char (isDigit, isLetter) import System.Environment (getArgs) import qualified Data.Attoparsec.Char8 as AB import qualified Data.ByteString.Char8 as B import qualified Data.Attoparsec.Text as A import qualified Data.Text as T import qualified Data.Text.IO as T import qualified Text.Parsec as P import qualified Text.Parsec.ByteString as P attoparsec_bytestring args = do forM_ args $ \arg -> do input <- B.readFile arg case AB.parse p input `AB.feed` B.empty of AB.Done _ xs -> print (length xs) what -> print what where slow = AB.many (AB.many1 AB.letter_ascii <|> AB.many1 AB.digit) fast = AB.many (AB.takeWhile1 isLetter <|> AB.takeWhile1 isDigit) isDigit c = c >= '0' && c <= '9' isLetter c = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') p = fast attoparsec_text args = do forM_ args $ \arg -> do input <- T.readFile arg case A.parse p input `A.feed` T.empty of A.Done _ xs -> print (length xs) what -> print what where p = A.many (A.takeWhile1 isLetter <|> A.takeWhile1 isDigit) parsec args = forM_ args $ \arg -> do input <- readFile arg case P.parse (P.many (P.many1 P.letter P.<|> P.many1 P.digit)) "" input of Left err -> print err Right xs -> print (length xs) main = do args <- getArgs case args of ("attoparsec_bytestring":xs) -> attoparsec_bytestring xs ("attoparsec_text":xs) -> attoparsec_text xs ("parsec":xs) -> parsec xs [] -> putStrLn "Usage: ... [parsec|attoparsec_text|attoparsec_bytestring] inputs"