Abhiroop Sarkar
Abhiroop Sarkar

Reputation: 2311

Parse multiple instances of a string using ReadP

Problem Statement: Parse the string "AB" in "ABCDFGABIJABGHA"

Constraint: Using ReadP

Expected Solution : (["AB","AB","AB"],"whatever is left")

Attempt:

getAll :: ReadP a -> ReadP [a]
getAll p = many loop
  where
    loop = p <|> (get >> loop)

readP_to_S (getAll $ string "AB") "ABCDFGABIJABGHA"
[([],"ABCDFGABIJABGHA"),(["AB"],"CDFGABIJABGHA"),(["AB","AB"],"IJABGHA"),(["AB"],"IJABGHA"),(["AB","AB","AB"],"GHA"),(["AB","AB"],"GHA"),(["AB","AB"],"GHA"),(["AB"],"GHA")]

I wanted the last state to be (["AB","AB","AB"],"GHA"). Is it possible to do the same using ReadP?

Upvotes: 0

Views: 66

Answers (1)

basile-henry
basile-henry

Reputation: 1365

The problem is that you are doing a symmetric choice with <|>. If you want your parser to match all the ps without exception use the provided left-biased choice: <++.

getAll :: ReadP a -> ReadP [a]
getAll p = many loop
  where
    loop = p <++ (get >> loop)

Upvotes: 1

Related Questions