Parsing: how to correctly advance on fail?

Related to “how to get all available matches”. I want the usual behavior you’d expect from regexp engines: for every character, try to match, on fail advance by one. E.g. if you do echo foo ffoo foo | grep foo you’ll get all 3 matches, because when grep reaches ffoo and fails to match ff with fo, it simply advances by a single character and tries again.

Now, I know I could do something like myParser <|> anyChar and I was doing that. However, for a 7kb file with just 2 matches this was returning a List with thousands of Nils, which is both slow and then have to be filtered out.

So my question is: how can I achieve the behavior of simply advancing the parser internal index by one on fail without returning anything related to the failure?

Code for the grep example:

module Main where

import Prelude

import Effect (Effect)
import Effect.Console (logShow)
import Parsing (runParser, Parser)
import Parsing.Combinators (many, try)
import Parsing.String (string)

myParser :: Parser String String
myParser = string "foo"

main :: Effect Unit
main = do
  logShow $ runParser "foo ffoo foo" (many $ try $ myParser)

I want this to return 3 matches and perhaps a single Nil for the end, but definitely not a dozen.

1 Like

I think that’s provided in the Parser.String.Replace module:
https://pursuit.purescript.org/packages/purescript-parsing/10.2.0/docs/Parsing.String.Replace#v:splitCap