1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- module Day7.Parser (
- parseTerminalLines,
- TerminalCommand (..),
- ListingEntry (..),
- DirName,
- FileName,
- Size
- ) where
-
- import Text.ParserCombinators.Parsec
-
- type DirName = String
- type FileName = String
- type Size = Int
-
- data ListingEntry = DirListing DirName | FileListing FileName Size
- deriving (Show, Eq)
-
- data TerminalCommand = In DirName | Out | Root | Listing [ListingEntry]
- deriving (Show, Eq)
-
- parseTerminalLines :: String -> Either ParseError [TerminalCommand]
- parseTerminalLines = parse terminal "(error)"
-
- terminal :: GenParser Char st [TerminalCommand]
- terminal = many command
-
- command :: GenParser Char st TerminalCommand
- command = do
- _ <- string "$ "
- cd <|> ls
-
- ls :: GenParser Char st TerminalCommand
- ls = do
- _ <- string "ls\n"
- entries <- many listingEntry
- return $ Listing entries
-
- listingEntry :: GenParser Char st ListingEntry
- listingEntry = dirListing <|> fileListing
-
- dirListing :: GenParser Char st ListingEntry
- dirListing = do
- _ <- string "dir "
- dirName <- many $ noneOf "\n"
- _ <- char '\n'
- return $ DirListing dirName
-
- fileListing :: GenParser Char st ListingEntry
- fileListing = do
- fileSize <- many1 digit
- _ <- char ' '
- fileName <- many $ noneOf "\n"
- _ <- char '\n'
- return $ FileListing fileName (read fileSize)
-
- cd :: GenParser Char st TerminalCommand
- cd = do
- _ <- string "cd "
- name <- many $ noneOf "\n"
- _ <- char '\n'
- return (nameToDir name)
-
- nameToDir :: DirName -> TerminalCommand
- nameToDir "/" = Root
- nameToDir ".." = Out
- nameToDir ds = In ds
|