module Main where import System.Environment (getArgs) import Debug.Trace(trace) import qualified Text.Parsec as Parsec import qualified Text.Parsec.Char as Parsec import Control.Applicative ((<|>)) import Data.Char import Data.List parse rule text = Parsec.parse rule "(source)" text data Simple = Electron | Atom Atom deriving (Eq, Ord, Show) data Token a = Simple Simple | Complex [a] deriving (Eq, Ord, Show) newtype Molecule = Molecule [Token Molecule] deriving (Eq, Ord, Show) type Atom = String type Replacement = (Simple, [Token Atom]) parseElectron :: Parsec.Parsec String () Simple parseElectron = do Parsec.string "e" return Electron parseAtom :: Parsec.Parsec String () Atom parseAtom = do first <- Parsec.upper remainder <- Parsec.many Parsec.lower return (first:remainder) onlySimple :: Token a -> Bool onlySimple (Simple _) = True onlySimple _ = False parseToken :: Parsec.Parsec String () a -> Parsec.Parsec String () (Token a) parseToken p = do Parsec.try (Complex <$> (Parsec.between (Parsec.string "Rn") (Parsec.string "Ar") $ p `Parsec.sepBy` (Parsec.string "Y"))) <|> (Simple <$> Atom <$> parseAtom) parseMolecule :: Parsec.Parsec String () Molecule parseMolecule = Molecule <$> Parsec.many1 (parseToken parseMolecule)