parsergen 0.2.0.4 → 0.2.0.6
raw patch · 5 files changed
+62/−5 lines, 5 filesnew-uploader
Files
- parsergen.cabal +1/−1
- src/ParserGen/Auto.hs +6/−2
- src/ParserGen/Gen.hs +35/−1
- src/ParserGen/ParseQuote.hs +1/−1
- src/ParserGen/Parser.hs +19/−0
parsergen.cabal view
@@ -1,5 +1,5 @@ Name: parsergen-Version: 0.2.0.4+Version: 0.2.0.6 Synopsis: TH parser generator for splitting bytestring into fixed-width fields Description:
src/ParserGen/Auto.hs view
@@ -7,8 +7,9 @@ import Control.Applicative (pure, (<$>), (<*>)) import Control.Monad (liftM2, mplus, replicateM)-import qualified Data.ByteString.Char8 as BC+import Data.Char (ord) import Language.Haskell.TH+import qualified Data.ByteString.Char8 as BC import ParserGen.Common import ParserGen.Types@@ -32,6 +33,7 @@ UnsignedParser -> case nameBase ftyname of "AlphaNum" -> wj [|unsafeAlphaNum fwidth|] [|putAlphaNum|] "ByteString" -> wj [|P.unsafeTake fwidth|] [|id|]+ "Char" | fwidth == 1 -> wj [|P.anyChar |] [|id|] "Int" -> wj (unsafeDecimalXTH fwidth) [|putDecimalX fwidth|] x -> recurse x SignedParser -> case nameBase ftyname of@@ -42,7 +44,9 @@ | length s /= fwidth -> fail $ "Width of " ++ show s ++ " is not " ++ show fwidth ++ "!" -- if string value is ignored - no need to return it- | fignored -> wn [|P.string (BC.pack s)|]+ | fignored -> wn [| P.string (BC.pack s) |]+ | length s == 1 -> wn [| let w = fromIntegral (ord . head $ s)+ in P.word8 w >> return w |] | otherwise -> wn [|P.string (BC.pack s) >> return (BC.pack s)|] where
src/ParserGen/Gen.hs view
@@ -5,13 +5,18 @@ ( genDataTypeFromFile , genParserFromFile , genWidthFromFile+ , genDataTypeFromFile'+ , genParserFromFile'+ , genWidthFromFile' ) where -import Language.Haskell.TH as TH import Control.Applicative import Control.Monad import Data.Char (isUpper, toLower)+import Data.List (isSuffixOf) import Data.Maybe (catMaybes)+import Language.Haskell.TH as TH+import System.Directory (doesFileExist) import ParserGen.Auto import ParserGen.ParseQuote@@ -26,6 +31,35 @@ genWidthFromFile :: FilePath -> Q [Dec] genWidthFromFile = getDatatypes >=> fmap concat . mapM mkWidthDecls++genDataTypeFromFile' :: FilePath -> Q [Dec]+genDataTypeFromFile' f = appendDependency f >> genDataTypeFromFile f++genParserFromFile' :: FilePath -> Q [Dec]+genParserFromFile' f = appendDependency f >> genParserFromFile f++genWidthFromFile' :: FilePath -> Q [Dec]+genWidthFromFile' f = appendDependency f >> genWidthFromFile f++appendDependency :: FilePath -> Q ()+appendDependency tpl = do+ hsFile <- TH.loc_filename `fmap` TH.location+ let depFile = mkDepName hsFile+ depLine = tpl ++ "\n"++ runIO $ do+ depExists <- doesFileExist depFile+ if depExists+ then do oldDeps <- lines `fmap` readFile depFile+ when (notElem tpl oldDeps) $ do+ appendFile depFile depLine+ else writeFile depFile depLine++ where+ mkDepName :: FilePath -> FilePath+ mkDepName f = let toBase = if ".hs" `isSuffixOf` f+ then reverse . drop 3 . reverse else id+ in toBase f ++ ".dep" mkDataDecl :: Datatype -> Q Dec mkDataDecl (Datatype {..}) = do
src/ParserGen/ParseQuote.hs view
@@ -87,7 +87,7 @@ fieldRepeat <- optionMaybe (try $ repeatFactor <* spaces) fieldName <- fieldNameParser _ <- spaces- fieldStrict <- try (char '!' *> return True <* spaces) <|> return False+ fieldStrict <- try (char '!' *> return True <* optional spaces) <|> return False fieldType <- typeParser _ <- spaces signed <- option False (True <$ char '+')
src/ParserGen/Parser.hs view
@@ -12,6 +12,8 @@ , ensureBytesLeft , atEnd , string+ , anyChar+ , word8 , take , unsafeTake , skip@@ -163,9 +165,26 @@ else fail $ "string" {-# INLINE string #-} +anyChar :: Parser Char+anyChar = do+ s <- gets input+ put (S (B.unsafeDrop 1 s))+ return (w2c $! B.unsafeHead s)++word8 :: Word8 -> Parser ()+word8 w = do+ i <- gets input+ if B.unsafeHead i == w+ then put (S (B.unsafeDrop 1 i))+ else fail "word8"+ -- | Indicate whether the end of the input has been reached. atEnd :: Parser Bool atEnd = do i <- gets input return $! B.null i {-# INLINE atEnd #-}++w2c :: Word8 -> Char+w2c = toEnum . fromEnum+{-# INLINE w2c #-}