Skip to content

Instantly share code, notes, and snippets.

@mizunashi-mana
Last active June 4, 2017 13:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mizunashi-mana/762eb20a0b56c49e386ff13195901612 to your computer and use it in GitHub Desktop.
Save mizunashi-mana/762eb20a0b56c49e386ff13195901612 to your computer and use it in GitHub Desktop.
module Works.TestParsec where
import Text.Parsec hiding (optional)
import Text.Parsec.String
import Control.Applicative (optional)
data Command = Command
{ address :: Maybe Address
, cmdName :: Char
, param :: Maybe String
} deriving (Show, Eq)
data Address
= AddressSingl AddressPointing
| AddressPair AddressPointing AddressPointing
deriving (Show, Eq)
data AddressPointing
= AddressLine Int -- absolute line number
| AddressCurrent Int -- relative line number
| AddressEOF -- end line of file
deriving (Show, Eq)
addressCurrentLine :: AddressPointing
addressCurrentLine = AddressCurrent 0
-- | A Parser for Command
--
-- >>> parse cmdParser "" "w test.txt"
-- Right (Command {addr1 = Nothing, addr2 = Nothing, cmdName = 'w', param = Just "test.txt"})
-- >>> parse cmdParser "" "1,2d"
-- Right (Command {addr1 = Just 1, addr2 = Just 2, cmdName = 'd', param = Nothing})
-- >>> parse cmdParser "" ""
-- Left (line 1, column 1):
-- unexpected end of input
-- expecting digit, "," or letter
--
cmdParser :: Parser Command
cmdParser = Command
<$> addressParser
<*> cmdNameParser
<*> paramParser
addressParser :: Parser (Maybe Address)
addressParser = optional addressParser' where
addressParser'
= currentToEOFParser
<|> prevToCurrentParser
currentToEOFParser = char ';'
*> pure (AddressPair addressCurrentLine AddressEOF)
prevToCurrentParser = char '-'
*> (AddressPair <$> (AddressCurrent . negate <$> parseInt) <*> pure addressCurrentLine)
cmdNameParser :: Parser Char
cmdNameParser = letter
paramParser :: Parser (Maybe String)
paramParser = spaces *> (listToMaybeList <$> many anyChar) where
listToMaybeList [] = Nothing
listToMaybeList xs = Just xs
parseInt :: Parser Int
parseInt = do
value <- many1 digit
return (read value)
{-
parseText :: Parser [Int]
parseText = parseInt `sepBy1` (char ',')
parseString :: Parser String
parseString = do
value <- string
return value
parseByCmd :: Parser [String]
parseByCmd = parseString `sepBy1` (letter)
parseStrList :: String -> [String]
parseStrList input
= case (parse parseByCmd "" input) of
Left err -> []
Right x -> x
parseIntList :: String -> [Int]
parseIntList input
= case (parse parseText "" input) of
Left err -> []
Right x -> x
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment