With Parsec, how do I parse zero or more foo1, terminated by foo2 and all separated by a dot?

What I'm trying to do seems pretty simple, but since I am a Haskell newb parsec, the solution eludes me.

I have two parsers, say foo1and foo2, where foo1can analyze the intermediate term and foo2analyze the final term. Terms are separated by a symbol ".".

The sentences I need to analyze

  • foo2
  • foo1.foo2
  • foo1.foo1.foo2

etc.

My initial thought was to make

do k <- sepBy foo1 (char'.')
   j <- foo2

but it will not catch the case foo2-only.

+3
source share
4 answers

You want endBy, not sepBy.

foo = do k <- foo1 `endBy` char '.'
         j <- foo2
         ... 

foo1.

, endBy many, .

foo = do k <- many $ foo1 <* char '.' 
         j <- foo2
         ...

, Control.Applicative:

foo = do k <- many $ do x <- foo1; char '.'; return x
         j <- foo2
         ...
+3

endBy sepBy:

do k <- endBy foo1 (char'.')
   j <- foo2

-,

foo2

:

endBy p sep p, sep. , p.

+2

-

many (foo1 >>= (\v -> char '.' >> return v)) >>= \v1 ->
  foo2 >>= \v2 ->
  -- ...
  -- combine v1 & v2 somehow

( , .)

, many Parsec Kleene star; - , , >>/>>= , do.

0

, foo2. foo1, Leiden word:

let a = sepBy word (char '.')
parseTest a "foo.bar.baz"
parseTest a "foo"
parseTest a ".baz"
0

Source: https://habr.com/ru/post/1735296/


All Articles