sirthias / parboiled2

A macro-based PEG parser generator for Scala 2.10+
Other
717 stars 86 forks source link

zeroOrMore and optional don't seem to work as documented. #204

Closed fr-rustyphillips closed 5 years ago

fr-rustyphillips commented 5 years ago

Using parboiled_2.12 v2.16

This:

 def TestZero: Rule1[Seq[String]] = rule (
    zeroOrMore(capture("aa"))
  )

and this:

 def TestZero: Rule1[Seq[String]] = rule (
    optional(oneOrMore(capture("aa")))
  )

Both produce this error: Expression of type Rule[HNil, StrictOut] doesn't conform to expected type Parboiled2.Rule1[Seq[String]]

In contrast, this does work:

 def TestZero: Rule1[Seq[String]] = rule (
    oneOrMore(capture("aa"))
  )

According to the docs, this type should work. Is there something different I should be doing for this to work?

ljleb commented 5 years ago

I am using the following class as a workaround for this issue:

implicit final class ArityRule[L](that: () => Rule1[L]) {
    def * : () => Rule1[Seq[L]] = () => rule {
        oneOrMore(that()) | push(Seq.empty[L])
    }

    def ? : () => Rule1[Option[L]] = () => rule {
        that() ~> Some.apply[L] _ | push(None)
    }
}

Please note this declaration uses meta rules: it requires that to be of type () => Rule[_, _] rather than Rule[_, _]. This requirement is stated in the README of parboiled2.

sirthias commented 5 years ago

Your first snippet:

def TestZero: Rule1[Seq[String]] = rule (
    zeroOrMore(capture("aa"))
  )

should compile fine. (It does for me, using Scala 2.12.8)

Your second snippet produces this compile error:

[error] ...: type mismatch;
[error]  found   : org.parboiled2.Rule[shapeless.HNil,Option[scala.collection.immutable.Seq[String]] :: shapeless.HNil]
[error]  required: org.parboiled2.Rule[shapeless.HNil,Seq[String] :: shapeless.HNil]
[error]       optional(oneOrMore(capture("aa")))

which explains the problem quite well, because the optional produces an Option, which your method result type doesn't contain.

How do you manage to have the compiler produce the error you've quoted?

fr-rustyphillips commented 5 years ago

Upon looking deeper, it looks like this problem is actually only one with the Scala plugins for Idea and Eclipse. It seems to actually compile fine.

Considering that basically everything else has worked flawlessly for me, I was under the impression that the tooling and the compiler were actually in sync. The workaround seems to work even when used with an IDE, so I'm probably going to go with that just so that I can continue to use the IDE for debugging purposes.

On Mon, Jun 24, 2019 at 8:38 AM Mathias notifications@github.com wrote:

Your first snippet:

def TestZero: Rule1[Seq[String]] = rule ( zeroOrMore(capture("aa")) )

should compile fine. (It does for me, using Scala 2.12.8)

Your second snippet produces this compile error:

[error] ...: type mismatch; [error] found : org.parboiled2.Rule[shapeless.HNil,Option[scala.collection.immutable.Seq[String]] :: shapeless.HNil] [error] required: org.parboiled2.Rule[shapeless.HNil,Seq[String] :: shapeless.HNil] [error] optional(oneOrMore(capture("aa")))

which explains the problem quite well, because the optional produces an Option, which your method result type doesn't contain.

How do you manage to have the compiler produce the error you've quoted?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/sirthias/parboiled2/issues/204?email_source=notifications&email_token=AKRCEI7HXESNQK7H73GHZLDP4C54LA5CNFSM4HWWGEDKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYMY7RY#issuecomment-504991687, or mute the thread https://github.com/notifications/unsubscribe-auth/AKRCEI3G3NSFUUXEACGEVFTP4C54LANCNFSM4HWWGEDA .

sirthias commented 5 years ago

Ok, thanks for digging up the source of the problem!