
These two pieces of code are not equivalent.
:{
input = do
eqatoms <- readFile "Parsing_File/eqatoms.out"
return eqatoms
:}
:{
main = do
eqatoms <- readFile "Parsing_File/eqatoms.out"
Parsec.parse species "test species" eqatoms
return
:}
You will have to do something like
:{
main = do
eqatoms <- readFile "Parsing_File/eqatoms.out"
let res = Parsec.parse species "test species" eqatoms
putStrLn (show res)
return
:}
And you will eventually clean it up by using a case statement to
distinguish between success and error.
On Wed, Jan 26, 2022 at 7:41 AM Roger Mason
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 _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners