
Hello, Warning: long post. I've worked my way through various parsing tutorials using either Parsec or ReadP. I reached a point where I need to try parsing one of the types of file for which I'm writing the parser. I have written parsers for various parts of this file: eqatoms.out: ====================================================== Species : 1 (Si) atom 1 is equivalent to atom(s) 1 2 3 atom 2 is equivalent to atom(s) 1 2 3 atom 3 is equivalent to atom(s) 1 2 3 Species : 2 (O) atom 1 is equivalent to atom(s) 1 2 3 4 5 6 atom 2 is equivalent to atom(s) 1 2 3 4 5 6 atom 3 is equivalent to atom(s) 1 2 3 4 5 6 atom 4 is equivalent to atom(s) 1 2 3 4 5 6 atom 5 is equivalent to atom(s) 1 2 3 4 5 6 atom 6 is equivalent to atom(s) 1 2 3 4 5 6 ====================================================== These are my imports: ====================================================== import qualified Text.Parsec as Parsec import Text.Parsec ((>)) import Control.Applicative import Control.Monad.Identity (Identity) ====================================================== These are my parsers: ====================================================== :{ species :: Parsec.Parsec String () (String,String) species = do --Parsec.char 'S' Parsec.string "Species" Parsec.spaces Parsec.char ':' Parsec.spaces digits <- Parsec.many1 Parsec.digit Parsec.spaces Parsec.char '(' id <- Parsec.many1 Parsec.letter return (id,digits) :} :{ atom = do Parsec.spaces Parsec.string "atom" Parsec.spaces digits <- Parsec.digit return digits :} :{ equivalents = do Parsec.spaces digits <- Parsec.digit return digits :} ====================================================== Some simple tests: ====================================================== src = "oops" Parsec.parse species src "Species : 1 (Si)" Right ("Si","1") src = "Parsing_File/eqatoms.out" Parsec.parse atom src "atom 5 is equivalent to atom(s)" Right '5' src = "Parsing_File/eqatoms.out" Parsec.parse (Parsec.many1 equivalents) src " 1 2 3 4 5 6" : Right "123456" ====================================================== So, the individual parsers work as intended. However, parsing an actual file does not work. I define a function to return the file contents: ====================================================== :{ input = do eqatoms <- readFile "Parsing_File/eqatoms.out" return eqatoms :} ====================================================== A test shows that my reader works: ====================================================== input : Species : 1 (Si)\n atom 1 is equivalent to atom(s)\n 1 2 3\n atom 2 is equivalent to atom(s)\n 1 2 3\n atom 3 is equivalent to atom(s)\n 1 2 3\n\nSpecies : 2 (O)\n atom 1 is equivalent to atom(s)\n 1 2 3 4 5 6\n atom 2 is equivalent to atom(s)\n 1 2 3 4 5 6\n atom 3 is equivalent to atom(s)\n 1 2 3 4 5 6\n atom 4 is equivalent to atom(s)\n 1 2 3 4 5 6\n atom 5 is equivalent to atom(s)\n 1 2 3 4 5 6\n atom 6 is equivalent to atom(s)\n 1 2 3 4 5 6\n ====================================================== I attempt to parse the input: ====================================================== :{ main = do eqatoms <- readFile "Parsing_File/eqatoms.out" Parsec.parse species "test species" eqatoms return :} Prelude Parsec Text.Parsec Control.Applicative Control.Monad.Identity| Prelude Parsec Text.Parsec Control.Applicative Control.Monad.Identity| Prelude Parsec Text.Parsec Control.Applicative Control.Monad.Identity| Prelude Parsec Text.Parsec Control.Applicative Control.Monad.Identity| Prelude Parsec Text.Parsec Control.Applicative Control.Monad.Identity| <interactive>:250:3: error: ,* Couldn't match type `Either Parsec.ParseError' with `IO' Expected type: IO (String, String) Actual type: Either Parsec.ParseError (String, String) ,* In a stmt of a 'do' block: Parsec.parse species "test species" eqatoms In the expression: do eqatoms <- readFile "Parsing_File/eqatoms.out" Parsec.parse species "test species" eqatoms return In an equation for `main': main = do eqatoms <- readFile "Parsing_File/eqatoms.out" Parsec.parse species "test species" eqatoms return <interactive>:251:3: error: ,* Couldn't match expected type `IO b' with actual type `a0 -> m0 a0' ,* Probable cause: `return' is applied to too few arguments In a stmt of a 'do' block: return In the expression: do eqatoms <- readFile "Parsing_File/eqatoms.out" Parsec.parse species "test species" eqatoms return In an equation for `main': main = do eqatoms <- readFile "Parsing_File/eqatoms.out" Parsec.parse species "test species" eqatoms return ,* Relevant bindings include main :: IO b (bound at <interactive>:248:3) ====================================================== Can someone please help me to get this to work? Thanks for reading to the end of this very long post. Roger