Kawaii-Parser 4.0.0 → 5.0.0
raw patch · 5 files changed
+82/−74 lines, 5 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
- Parser.Files: Unexpected_file_extension :: Ext -> Error
- Parser.Files: data Error
- Parser.Files: instance GHC.Show.Show Parser.Files.Error
- Parser.Files: parse_file_path :: Ext -> String -> Either Error File_path
+ Parser.Files: Unexpected_extension :: Ext -> File_error
+ Parser.Files: data File_error
+ Parser.Files: instance GHC.Show.Show Parser.Files.File_error
+ Parser.Files: parse_file_path' :: (File_error -> error) -> Ext -> String -> Either error File_path
+ Parser.Files: write_file_path :: File_path -> FilePath
+ Parser.Parser: (<+) :: Monoid output => Parser token output error t -> Parser token output error t -> Parser token output error t
- Parser.Files: Failed_to_find_the_file :: FilePath -> Error
+ Parser.Files: Failed_to_find_the_file :: FilePath -> File_error
- Parser.Files: Invalid_file_path :: Error
+ Parser.Files: Invalid_file_path :: File_error
- Parser.Files: read_file :: Ext -> File_path -> ExceptT Error IO String
+ Parser.Files: read_file :: Ext -> (FilePath -> IO file) -> (File_error -> error) -> File_path -> ExceptT error IO file
- Parser.Files: write_file :: Ext -> File_path -> String -> ExceptT Error IO ()
+ Parser.Files: write_file :: Ext -> (FilePath -> file -> IO ()) -> (File_error -> error) -> File_path -> file -> ExceptT error IO ()
Files
- Kawaii-Parser.cabal +2/−2
- Parser/Files.hs +49/−40
- Parser/Locations.hs +2/−4
- Parser/Parser.hs +23/−4
- Parser/Utilities.hs +6/−24
Kawaii-Parser.cabal view
@@ -11,9 +11,9 @@ maintainer: liisikerik@hotmail.com name: Kawaii-Parser synopsis: A simple parsing library and some additional utilities.-version: 4.0.0+version: 5.0.0 library- build-depends: base < 4.21, containers, directory, mtl, transformers+ build-depends: base < 4.22, containers, directory, mtl, transformers default-extensions: FlexibleContexts, ScopedTypeVariables, StandaloneDeriving default-language: Haskell2010 exposed-modules: Parser.Files, Parser.Locations, Parser.Parser, Parser.Utilities
Parser/Files.hs view
@@ -1,24 +1,24 @@ {-|-Description: Relative directories and file paths.--* Relative directories and file paths.+Relative directories and file paths. -} module Parser.Files ( Back (..), Directory (..),- Error (..), Ext,+ File_error (..), File_path (..), File_path_and_location (..), (<//>), drop_file_name,- parse_file_path,+ parse_file_path', read_file, write_file,+ write_file_path, write_file_path_and_location) where import Control.Monad import Control.Monad.Except import Control.Monad.IO.Class+ import Data.Bifunctor import Data.Char import Data.Maybe import Parser.Locations@@ -31,15 +31,16 @@ -- | Relative directory. data Directory = Directory [Back] [String] -- | Errors.- data Error = Failed_to_find_the_file FilePath | Invalid_file_path | Unexpected_file_extension Ext+ data File_error = Failed_to_find_the_file FilePath | Invalid_file_path | Unexpected_extension Ext+ -- | File extensions. type Ext = String -- | Relative file path. data File_path = File_path Directory String Ext -- | Locations with a file path. data File_path_and_location = File_path_and_location File_path Location- type Parser = Parser' Token Error+ type Parser = Parser' Token File_error data Token = Dot_token | Name_token String | Slash_token- type Tokeniser = Tokeniser' Char_class Token Error+ type Tokeniser = Tokeniser' Char_class Token File_error -- | Prepend a directory to file path. infixr 6 <//> (<//>) :: Directory -> File_path -> File_path@@ -63,13 +64,13 @@ deriving instance Show Back deriving instance Show Char_class deriving instance Show Directory- deriving instance Show Error+ deriving instance Show File_error deriving instance Show File_path deriving instance Show File_path_and_location deriving instance Show Token- check_ext :: (MonadError Error f) => Ext -> File_path -> f ()- check_ext expected_ext (File_path _ _ actual_ext) = check (Unexpected_file_extension actual_ext) (expected_ext == actual_ext)- check_file_path :: (MonadError Error f) => Ext -> File_path -> f ()+ check_ext :: (MonadError File_error f) => Ext -> File_path -> f ()+ check_ext expected_ext (File_path _ _ actual_ext) = check (Unexpected_extension actual_ext) (expected_ext == actual_ext)+ check_file_path :: (MonadError File_error f) => Ext -> File_path -> f () check_file_path ext file_path = do check Invalid_file_path (valid_file_path file_path)@@ -108,21 +109,23 @@ parse_directory = Directory <$> parse_many (parse_with_slash parse_back) <*> parse_many (parse_with_slash parse_name) parse_dot :: Parser () parse_dot = parse_token Dot_token- -- | Parse a file path and check the extension.- parse_file_path :: Ext -> String -> Either Error File_path- parse_file_path expected_ext file_path =+ parse_file_path :: Parser File_path+ parse_file_path = do- file_path' <- fromJust (parse' classify_char (\ _ -> id) tokenise parse_file_path' (\ _ -> Invalid_file_path) file_path)- check_ext expected_ext file_path'- return file_path' where- parse_file_path' :: Parser File_path- parse_file_path' =- do- directory <- parse_directory- file_name <- parse_name- parse_dot- actual_ext <- parse_name- return (File_path directory file_name actual_ext)+ directory <- parse_directory+ file_name <- parse_name+ parse_dot+ actual_ext <- parse_name+ return (File_path directory file_name actual_ext)+ -- | Parse a file path and check the extension.+ parse_file_path' :: (File_error -> error) -> Ext -> String -> Either error File_path+ parse_file_path' transform_error expected_ext file_path =+ first+ transform_error+ (do+ file_path' <- fromJust (parse' classify_char (\ _ -> id) tokenise parse_file_path (\ _ -> Invalid_file_path) file_path)+ check_ext expected_ext file_path'+ return file_path') parse_name :: Parser String parse_name = parse_token' name_token parse_with_slash :: Parser t -> Parser t@@ -132,15 +135,17 @@ parse_token Slash_token return x -- | Check the extension and read the file.- read_file :: Ext -> File_path -> ExceptT Error IO String- read_file ext file_path =- do- check_file_path ext file_path- let file_path' = write_file_path file_path- file_exits <- liftIO (doesPathExist file_path')- case file_exits of- False -> throwError (Failed_to_find_the_file file_path')- True -> liftIO (readFile file_path')+ read_file :: Ext -> (FilePath -> IO file) -> (File_error -> error) -> File_path -> ExceptT error IO file+ read_file ext read_file' transform_error file_path =+ withExceptT+ transform_error+ (do+ check_file_path ext file_path+ let file_path' = write_file_path file_path+ file_exits <- liftIO (doesPathExist file_path')+ case file_exits of+ False -> throwError (Failed_to_find_the_file file_path')+ True -> liftIO (read_file' file_path')) tokenise :: Tokeniser () tokenise = void (parse_many tokenise_1) tokenise_1 :: Tokeniser ()@@ -163,13 +168,17 @@ write_directory :: Directory -> FilePath write_directory (Directory back directories) = join (write_with_slash <$> ((write_back <$> back) <> directories)) -- | Check the extension and write to the file.- write_file :: Ext -> File_path -> String -> ExceptT Error IO ()- write_file ext file_path file =- do- check_file_path ext file_path- liftIO (writeFile (write_file_path file_path) file)+ write_file :: Ext -> (FilePath -> file -> IO ()) -> (File_error -> error) -> File_path -> file -> ExceptT error IO ()+ write_file ext write_file' transform_error file_path file =+ withExceptT+ transform_error+ (do+ check_file_path ext file_path+ liftIO (write_file' (write_file_path file_path) file))+ -- | Write file path. write_file_path :: File_path -> FilePath write_file_path (File_path directory file_name ext) = write_directory directory <> file_name <> "." <> ext+ -- | Write file path and location. write_file_path_and_location :: File_path -> Location -> String write_file_path_and_location file_path location = write_file_path file_path <> ":" <> write_location location write_with_slash :: String -> String
Parser/Locations.hs view
@@ -1,7 +1,5 @@ {-|-Description: Locations.--* Locations.+Locations. -} module Parser.Locations ( Location,@@ -13,7 +11,7 @@ deriving instance Eq Location deriving instance Ord Location deriving instance Show Location- deriving instance Show t => Show (With_location t)+ deriving instance (Show t) => Show (With_location t) -- | Locations. data Location = Location Integer Integer -- | Add a location to any type.
Parser/Parser.hs view
@@ -1,11 +1,10 @@ {-|-Description: Combinator-based tokeniser and parser with symmetric choice and location tracking.--* Combinator-based tokeniser and parser with symmetric choice and location tracking.+Combinator-based tokeniser and parser with symmetric choice and location tracking. -} module Parser.Parser ( Parser', Tokeniser',+ (<+), (<+>), add_location, add_token,@@ -37,7 +36,27 @@ -- classify characters before tokenisation to simplify patternmatching. type Tokeniser' char_class token error = Parser char_class [With_location token] error data Tokens token = Tokens [With_location token] Location- -- | Symmetric choice between two parsers.+ -- | Asymmetric choice between two parsers. Picks the longer match but, unlike @<+@, picks the first result if both parsers+ -- match the same number of tokens. Use this operator if you need to choose between two parsers that can match the same+ -- number of tokens.+ infixr 3 <++ (<+) :: (Monoid output) => Parser token output error t -> Parser token output error t -> Parser token output error t+ Parser parse_0 <+ Parser parse_1 =+ Parser+ (\ tokens ->+ do+ result_0 <- parse_0 tokens+ result_1 <- parse_1 tokens+ return+ (case (result_0, result_1) of+ (Nothing, _) -> result_1+ (_, Nothing) -> result_0+ (Just (_, tokens_0), Just (_, tokens_1)) ->+ case compare (count_tokens tokens_0) (count_tokens tokens_1) of+ LT -> result_0+ EQ -> result_0+ GT -> result_1))+ -- | Symmetric choice between two parsers. Ambiguous parsing will result in an error if it's not resolved by the end. infixr 3 <+> (<+>) :: (Monoid output) => Parser token output error t -> Parser token output error t -> Parser token output error t Parser parse_0 <+> Parser parse_1 =
Parser/Utilities.hs view
@@ -1,7 +1,5 @@ {-|-Description: Assorted utilities.--* Assorted utilities.+Assorted utilities. -} module Parser.Utilities ( (<->),@@ -21,7 +19,7 @@ s <-> t = s <> " " <> t -- | Checks if all elements of a list are equal. Returns @Nothing@ if all elements aren't equal, @Just Nothing@ if the list is -- empty and @Just (Just x)@ if all elements are equal to @x@.- all_equal :: Eq t => [t] -> Maybe (Maybe t)+ all_equal :: (Eq t) => [t] -> Maybe (Maybe t) all_equal x = case x of [] -> Just Nothing@@ -30,44 +28,28 @@ check () (all ((==) y) x') Just (Just y) -- | Check if the value is in bounds.- between :: Ord t => t -> t -> t -> Bool+ between :: (Ord t) => t -> t -> t -> Bool between lowest highest x = lowest <= x && highest >= x -- | Throw an error if the condition is not satisfied.- check :: MonadError error f => error -> Bool -> f ()+ check :: (MonadError error f) => error -> Bool -> f () check err condition = case condition of False -> throwError err True -> return () -- | Construct a map if all keys are different. Otherwise return @Nothing@.- construct_map :: Ord t => [(t, u)] -> Maybe (Map t u)+ construct_map :: (Ord t) => [(t, u)] -> Maybe (Map t u) construct_map x = do let y = Map.fromList x check () (Foldable.length x == Map.size y) Just y -- | Construct a set if all elements are different. Otherwise return @Nothing@.- construct_set :: Ord t => [t] -> Maybe (Set t)+ construct_set :: (Ord t) => [t] -> Maybe (Set t) construct_set x = do let y = Set.fromList x check () (Foldable.length x == Set.size y) Just y-{-- -- | Safe list indexation.- element_at :: Int -> [t] -> Maybe t- element_at j x =- do- check () (between 0 (Foldable.length x - 1) j)- return (x !! j)--} -- | Aggregate least common denominator. lcm_all :: (Foldable f, Integral t) => f t -> t lcm_all = Foldable.foldr lcm 1-{-- -- | Swap Left and Right.- swap_either :: Either t u -> Either u t- swap_either x =- case x of- Left y -> Right y- Right y -> Left y--}