[Haskell-beginners] Parsing a file
David McBride
toad3k at gmail.com
Wed Jan 26 17:29:40 UTC 2022
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 <rmason at mun.ca> wrote:
> 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 at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20220126/88629188/attachment-0001.html>
More information about the Beginners
mailing list