Skip to content

Can we have more typesafety w.r.t. many-like combinators and infinite loops? #75

Closed
@chtenb

Description

@chtenb

The issue discussed in purescript-contrib/purescript-parsing#120 also applies to this project.

Paraphrasing the conclusion from the other issue:

  1. many p will get stuck in a loop if p possibly doesn't consume any input but still succeeds.
  2. We could change the semantics of many-like combinators (or add a safe variant) that doesn't hang in the situation where no input was consumed.

@jamesdbrock pointed out that

Because ParserT is a monad transformer, it's possible to imagine a ParserT s State a which consumes no input of the first parse but does consume input on the second parse, due to some mechanics of the internal state.

However, I don't think that problem applies in this project, since Parser is not a monad transformer here.

I would propose something like the following. But perhaps these safe variants could even replace the original functions.

-- Fails with parse error if parser did not consume any input
assertConsume :: forall a. Parser a -> Parser a
assertConsume p = Parser $ \posStrBefore ->
  case unParser p posStrBefore of
    Right result ->
      if posStrBefore.pos < result.suffix.pos
      then Right result
      else Left { pos: result.suffix.pos, error: "Consumed no input." }
    x -> x

safeMany :: forall a. Parser a -> Parser (List a)
safeMany = many <<< assertConsume

safeMany1 :: forall a. Parser a -> Parser (NonEmptyList a)
safeMany1 = many1 <<< assertConsume

safeManyTill :: forall a end. Parser a -> Parser end -> Parser (List a)
safeManyTill p = manyTill (assertConsume p)

safeMany1Till :: forall a end. Parser a -> Parser end -> Parser (NonEmptyList a)
safeMany1Till p = many1Till (assertConsume p)

Any thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions