sirthias / parboiled2

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

By-name higher-order parsers don't work #116

Open lihaoyi opened 9 years ago

lihaoyi commented 9 years ago
scala> class C(val input: ParserInput) extends Parser{
     | def id(rule: => Rule0) = rule
     | def MyRule = rule( "omg" ~ id("wtf" ~ "bbq") )
     | }
<console>:12: error: Calls to `~` must be inside `rule` macro
       def MyRule = rule( "omg" ~ id("wtf" ~ "bbq") )
                                           ^
<console>:12: error: Calls to `str` must be inside `rule` macro
       def MyRule = rule( "omg" ~ id("wtf" ~ "bbq") )
                                     ^
<console>:12: error: Calls to `str` must be inside `rule` macro
       def MyRule = rule( "omg" ~ id("wtf" ~ "bbq") )
                                             ^

scala>
sirthias commented 9 years ago

The work-around of wrapping the argument with another application of the rule macro should work:

rule( "omg" ~ id(rule("wtf" ~ "bbq")))
lihaoyi commented 9 years ago

@sirthias maybe it should, but it doesn't

Welcome to Scala version 2.11.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import org.parboiled2._
import org.parboiled2._

scala> class C(val input: ParserInput) extends Parser{
     |  def id(rule: => Rule0) = rule
     |  def myRule = rule( "omg" ~ id(rule("wtf" ~ "bbq")))
     | }
ReplGlobal.abort: symbol value matched does not exist in $line4.$read$$iw$$iw$$iw$$iw$C.myRule
error:
  symbol value matched does not exist in C.myRule
     while compiling: <console>
        during phase: icode
     library version: version 2.11.4
    compiler version: version 2.11.4
  reconstructed args: -Xplugin:/Users/haoyi/.ivy2/cache/com.lihaoyi/acyclic_2.11/jars/acyclic_2.11-0.1.2.jar -bootclasspath /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/classes:/Users/haoyi/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.11.4.jar -classpath /Users/haoyi/Dropbox (Personal)/Workspace/scalatex/scalaParser/target/scala-2.11/classes:/Users/haoyi/.ivy2/cache/org.parboiled/parboiled_2.11/jars/parboiled_2.11-2.0.1.jar:/Users/haoyi/.ivy2/cache/com.chuusai/shapeless_2.11/bundles/shapeless_2.11-2.0.0.jar:/Users/haoyi/.ivy2/cache/com.lihaoyi/acyclic_2.11/jars/acyclic_2.11-0.1.2.jar:/Users/haoyi/.ivy2/cache/org.scala-lang/scala-compiler/jars/scala-compiler-2.11.4.jar:/Users/haoyi/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.11.4.jar:/Users/haoyi/.ivy2/cache/org.scala-lang.modules/scala-xml_2.11/bundles/scala-xml_2.11-1.0.2.jar:/Users/haoyi/.ivy2/cache/org.scala-lang.modules/scala-parser-combinators_2.11/bundles/scala-parser-combinators_2.11-1.0.2.jar:/Users/haoyi/.ivy2/cache/jline/jline/jars/jline-2.12.jar -Yrepl-sync

  last tree to typer: Ident(input)
       tree position: line 10 of <console>
            tree tpe: org.parboiled2.ParserInput
              symbol: value input
   symbol definition: input: org.parboiled2.ParserInput (a TermSymbol)
      symbol package: $line4
       symbol owners: value input -> constructor $read$C -> class iw$C
           call site: <$anon: Function0> in package $line4 in package $line4

<Cannot read source file>
scala.reflect.internal.FatalError:
  symbol value matched does not exist in $line4.$read$$iw$$iw$$iw$$iw$C.myRule
     while compiling: <console>
        during phase: icode
     library version: version 2.11.4
    compiler version: version 2.11.4
  reconstructed args: -Xplugin:/Users/haoyi/.ivy2/cache/com.lihaoyi/acyclic_2.11/jars/acyclic_2.11-0.1.2.jar -bootclasspath /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/classes:/Users/haoyi/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.11.4.jar -classpath /Users/haoyi/Dropbox (Personal)/Workspace/scalatex/scalaParser/target/scala-2.11/classes:/Users/haoyi/.ivy2/cache/org.parboiled/parboiled_2.11/jars/parboiled_2.11-2.0.1.jar:/Users/haoyi/.ivy2/cache/com.chuusai/shapeless_2.11/bundles/shapeless_2.11-2.0.0.jar:/Users/haoyi/.ivy2/cache/com.lihaoyi/acyclic_2.11/jars/acyclic_2.11-0.1.2.jar:/Users/haoyi/.ivy2/cache/org.scala-lang/scala-compiler/jars/scala-compiler-2.11.4.jar:/Users/haoyi/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.11.4.jar:/Users/haoyi/.ivy2/cache/org.scala-lang.modules/scala-xml_2.11/bundles/scala-xml_2.11-1.0.2.jar:/Users/haoyi/.ivy2/cache/org.scala-lang.modules/scala-parser-combinators_2.11/bundles/scala-parser-combinators_2.11-1.0.2.jar:/Users/haoyi/.ivy2/cache/jline/jline/jars/jline-2.12.jar -Yrepl-sync

  last tree to typer: Ident(input)
       tree position: line 10 of <console>
            tree tpe: org.parboiled2.ParserInput
              symbol: value input
   symbol definition: input: org.parboiled2.ParserInput (a TermSymbol)
      symbol package: $line4
       symbol owners: value input -> constructor $read$$iw$$iw$$iw$$iw$C -> class iw$C
           call site: <$anon: Function0> in package $line4 in package $line4

<Cannot read source file>
    at scala.reflect.internal.Reporting$class.abort(Reporting.scala:59)
    at scala.tools.nsc.interpreter.IMain$$anon$1.scala$tools$nsc$interpreter$ReplGlobal$$super$abort(IMain.scala:237)
    at scala.tools.nsc.interpreter.ReplGlobal$class.abort(ReplGlobal.scala:20)
    at scala.tools.nsc.interpreter.IMain$$anon$1.abort(IMain.scala:237)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genLoadIdent$1(GenICode.scala:885)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:891)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$genLoadArguments$1.apply(GenICode.scala:1133)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$genLoadArguments$1.apply(GenICode.scala:1131)
    at scala.collection.LinearSeqOptimized$class.foldLeft(LinearSeqOptimized.scala:110)
    at scala.collection.immutable.List.foldLeft(List.scala:83)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genLoadArguments(GenICode.scala:1131)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genLoadApply6$1(GenICode.scala:778)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:809)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genLoadIf(GenICode.scala:373)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:536)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genLoadValDef$1(GenICode.scala:525)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:533)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genStat(GenICode.scala:181)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$genStat$1.apply(GenICode.scala:155)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$genStat$1.apply(GenICode.scala:155)
    at scala.collection.LinearSeqOptimized$class.foldLeft(LinearSeqOptimized.scala:110)
    at scala.collection.immutable.List.foldLeft(List.scala:83)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:915)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:924)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:123)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:71)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:148)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:98)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:71)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:89)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:67)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.apply(GenICode.scala:63)
    at scala.tools.nsc.Global$GlobalPhase$$anonfun$applyPhase$1.apply$mcV$sp(Global.scala:428)
    at scala.tools.nsc.Global$GlobalPhase.withCurrentUnit(Global.scala:419)
    at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:428)
    at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:386)
    at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:386)
    at scala.collection.Iterator$class.foreach(Iterator.scala:743)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1195)
    at scala.tools.nsc.Global$GlobalPhase.run(Global.scala:386)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.run(GenICode.scala:55)
    at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1338)
    at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1325)
    at scala.tools.nsc.Global$Run.compileSources(Global.scala:1320)
    at scala.tools.nsc.interpreter.IMain.compileSourcesKeepingRun(IMain.scala:407)
    at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.compileAndSaveRun(IMain.scala:823)
    at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.compile(IMain.scala:782)
    at scala.tools.nsc.interpreter.IMain$Request.compile$lzycompute(IMain.scala:958)
    at scala.tools.nsc.interpreter.IMain$Request.compile(IMain.scala:953)
    at scala.tools.nsc.interpreter.IMain.compile(IMain.scala:550)
    at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:538)
    at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:536)
    at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:750)
    at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:795)
    at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:768)
    at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:795)
    at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:768)
    at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:795)
    at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:768)
    at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:795)
    at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:662)
    at scala.tools.nsc.interpreter.ILoop.processLine(ILoop.scala:407)
    at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:430)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:864)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:850)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:850)
    at scala.reflect.internal.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:97)
    at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:850)
    at scala.tools.nsc.interpreter.ILoop.main(ILoop.scala:872)
    at xsbt.ConsoleInterface.run(ConsoleInterface.scala:62)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:101)
    at sbt.compiler.AnalyzingCompiler.console(AnalyzingCompiler.scala:76)
    at sbt.Console.sbt$Console$$console0$1(Console.scala:22)
    at sbt.Console$$anonfun$apply$2$$anonfun$apply$1.apply$mcV$sp(Console.scala:23)
    at sbt.Console$$anonfun$apply$2$$anonfun$apply$1.apply(Console.scala:23)
    at sbt.Console$$anonfun$apply$2$$anonfun$apply$1.apply(Console.scala:23)
    at sbt.Logger$$anon$4.apply(Logger.scala:85)
    at sbt.TrapExit$App.run(TrapExit.scala:248)
    at java.lang.Thread.run(Thread.java:745)

That entry seems to have slain the compiler.  Shall I replay
your session? I can re-run each line except the last one.
sirthias commented 9 years ago

Ah, a hygiene issue. I see. I guess we'll have to wait for the "new design" with parser singletons and static rules to emerge before being able to solve higher-order rules properly.