Finish implementing parsing

This commit is contained in:
Joscha 2018-01-05 12:02:19 +00:00
parent 266acbe93d
commit df3adf5ca4

View file

@ -27,9 +27,11 @@ import Control.Monad
import Data.List import Data.List
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Data.Time import Data.Time
import Data.Time.Clock.POSIX
import Data.Void import Data.Void
import Text.Megaparsec import Text.Megaparsec
import Text.Megaparsec.Char import Text.Megaparsec.Char
import qualified Text.Megaparsec.Char.Lexer as L
-- | Contains 'Card's and comments with a certain ordering. -- | Contains 'Card's and comments with a certain ordering.
-- --
@ -222,7 +224,7 @@ elementToString (ECard card) = cardToString card
cardToString :: Card -> String cardToString :: Card -> String
cardToString Card{sides=s, tier=t, lastChecked=lc, offset=o} = cardToString Card{sides=s, tier=t, lastChecked=lc, offset=o} =
let info = ":: {\"level\": " ++ (show $ fromEnum t) ++ let info = ":: {\"level\": " ++ (show $ fromEnum t) ++
", \"last_checked\": " ++ (show $ formatTime defaultTimeLocale "%s" lc) ++ ", \"last_checked\": " ++ formatTime defaultTimeLocale "%s" lc ++
", \"delay\": " ++ (show $ fromEnum o) ++ ", \"delay\": " ++ (show $ fromEnum o) ++
"}" "}"
in unlines $ info : intersperse "::" s in unlines $ info : intersperse "::" s
@ -234,6 +236,12 @@ cardToString Card{sides=s, tier=t, lastChecked=lc, offset=o} =
-- | Not yet implemented. -- | Not yet implemented.
type Parser = Parsec Void String type Parser = Parsec Void String
sc :: Parser ()
sc = L.space space1 empty empty
symbol :: String -> Parser String
symbol = L.symbol sc
-- useful parsers -- useful parsers
followedBy :: Parser a -> Parser () followedBy :: Parser a -> Parser ()
@ -252,12 +260,44 @@ separator = void newline <|> void eof <?> "separator"
infostring :: UTCTime -> Parser Card infostring :: UTCTime -> Parser Card
infostring time = do infostring time = do
_ <- string ":: " _ <- string ":: "
card <- between (string "{") (string "}") (innerinfo time) cardModifiers <- between (string "{") (string "}") (innerinfo `sepBy` symbol ",")
return card let card = createCard time []
return $ foldr (.) id cardModifiers card
-- TODO: implement -- TODO: implement
innerinfo :: UTCTime -> Parser Card -- Possible implementation: Compose (Card -> Card)s and apply to base Card
innerinfo = undefined innerinfo :: Parser (Card -> Card)
innerinfo = try tierInfo
<|> try lastCheckedInfo
<|> offsetInfo
<?> "tier info or last checked info or offset info"
integer :: Parser Integer
integer = do
sign <- (-1) <$ char '-' <|> 1 <$ char '+' <|> return 1
digits <- many digitChar
return $ sign * read digits
field :: String -> Parser Integer
field name = between (char '"') (char '"') (string name) >> symbol ":" >> integer
tierInfo :: Parser (Card -> Card)
tierInfo = do
number <- field "level"
let t = toEnum $ fromInteger number
return (\card -> card {tier=t})
lastCheckedInfo :: Parser (Card -> Card)
lastCheckedInfo = do
number <- field "last_checked"
let lc = posixSecondsToUTCTime $ fromInteger number
return (\card -> card {lastChecked=lc})
offsetInfo :: Parser (Card -> Card)
offsetInfo = do
number <- field "delay"
let o = fromInteger number
return (\card -> card {offset=o})
-- sides of a card -- sides of a card