module Data.SMILES.Parser where import Text.Megaparsec import Text.Megaparsec.Text import Text.Megaparsec.Lexer import Data.SMILES import Data.SMILES.Atom import Data.SMILES.Bond import Data.SMILES.Atom.Parser import Data.SMILES.Bond.Parser smilesP :: Parser SMILES smilesP = do atom <- Atom <$> atomP rest <- many chainTokenP pure $ SMILES (atom:rest) chainTokenP :: Parser ChainToken chainTokenP = (Atom <$> atomP) <|> (Bond <$> bondP) <|> ringP <|> branchP branchP :: Parser ChainToken branchP = Branch <$> between (char '(') (char ')') branchHelperP where branchHelperP = do bondMb <- optional (Bond <$> bondP) SMILES rest <- smilesP case bondMb of Just bond -> pure $ SMILES (bond:rest) Nothing -> pure $ SMILES rest ringP :: Parser ChainToken ringP = RingClosure <$> ringHelperP where ringHelperP :: Parser Int ringHelperP = do pcMb <- optional $ char '%' case pcMb of Just _ -> fromIntegral <$> integer Nothing -> read . pure <$> digitChar