sirthias / parboiled2

A macro-based PEG parser generator for Scala 2.10+

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

On 'times' combinator rule

lordgordon opened this issue · comments

Hi there,

thanks for this very useful and powerful library. I'm pretty new to this library and to Scala world in general. I'm using parboiled2 for a personal project and I'm wondering why this is not working:

class Demo(val input: ParserInput) extends Parser {
  val max = 10 // can be in another package, it's here now for clarity
  def aRule = rule { (1, max).times(CharPredicate.Digit) }
}

(I just cut to the essence of the issue)

I got errors at compile time. Apparently is not possible to use values, even if they are constant, in such construct. Is this a bug, or is a missing feature? Can I assume is due to the current macro implementation?

In case this is not a bug and is the current behavior, I suggest it as a new feature for parboiled as it could be really useful for a better grammar management. As a common scenario, if my requirements changes and I need to capture a longer element (or shorter), I'd like to have a single, well defined, value to change rather than search and fix all the rules. This can be tedious and prone to errors in case of big grammars.

Thanks for your time.

Regards,

Nicholas

Edit:
I'm using parboiled2 2.1.0 with Scala 2.11.6

Please use the following syntax for ranges - replace (1, max) with (1 to max):
def aRule = rule { (1 to max).times(CharPredicate.Digit) }

Sorry, my fault in copy-and-paste. My actual code is already with to. The issue stands.

(1 to max).times(...) should work in the use case that you show.
If it doesn't it's a bug.
Thanks for reporting!

I see!
Let me try again to double check it's really a bug or just a mistake somewhere on my side.
I'll provide a reproducible code snippet with the compiler output.

Hi there,

I confirm the issue. Here all the details to reproduce, as promised.

Environment:

  • Scala 2.11.6
  • sbt 0.13.8
  • parboiled2 2.1.0
  • JDK 1.8.0_45
  • OS X 10.9.5

Tested also on:

  • OpenJDK 1.8 (I don't have the minor right now)
  • FreeBSD 10.1

build.sbt

// MAIN CONFIGURATION
lazy val root = (project in file(".")).
  settings(
    // versioning
    name := "demo",
    version := "0",
    scalaVersion := "2.11.6",

    // dependencies
    libraryDependencies += "org.parboiled" %% "parboiled" % "2.1.0"
  )

Here the minimal code to reproduce.

demo.scala

import org.parboiled2._

class Demo(val input: ParserInput) extends Parser {
  val max = 10
  def InputLine = rule { (1 to max).times(CharPredicate.Digit) ~ EOI }
}

object HelloWorld {
  def main(args: Array[String]) {
     println(new Demo("123").InputLine.run())
  }
}

Then, sbt run fails with this output:

[info] Loading project definition from /tmp/demo/project
[info] Set current project to demo (in build file:/tmp/demo/)
[info] Compiling 1 Scala source to /tmp/demo/target/scala-2.11/classes...
[error] /tmp/demo/src/main/scala/demo.scala:5: Invalid int range expression for `.times(...)`: scala.this.Predef.intWrapper(1).to(Demo.this.max)
[error]   def InputLine = rule { (1 to max).times(CharPredicate.Digit) ~ EOI }
[error]                             ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 7 s, completed 22-giu-2015 17.13.02

Of course, putting (1 to 10) works fine.

Regards,

Nicholas

Edit: minor typo

Ok, thank you!
I'll get this fixed.

Status on this? Looks like it was fixed in #153, but that's been left to collect dust.

Sorry Chip, #153 was indeed unjustifiably neglected over way too long a time.
I'll try to get it a new released published in the short-term.

@sirthias thanks! I was waiting for this 👍

Awesome, glad to hear it, @sirthias. Building a debugger REPL using parboiled2 and had to use an ugly workaround for some of the parsing logic due to this issue.

Closed by d61aa1d.