Low-level Custom Rule

44 views
Skip to first unread message

Alexander Myltsev

unread,
Jul 28, 2015, 9:27:44 AM7/28/15
to parboiled2.org User List
Hi Mathias, 

What do you think on exposing custom rule creation to public API?

I drafted some code at https://github.com/GlobalNamesArchitecture/gnparser/commit/3db444c3aec0e30de25a980941446d204c13f1c8. I overrid opTreePF. To get it I needed to entirely copy-paste Parser and Macros as they are tightly coupled with OpTreeContext. 

Error handling is stubbed.

Changes to pb2 master to get this working:

diff --git a/parboiled-core/src/main/scala/org/parboiled2/support/OpTreeContext.scala b/parboiled-core/src/main/scala/org/parboiled2/support/OpTreeContext.scala
index 1aae731..d73374f 100644
--- a/parboiled-core/src/main/scala/org/parboiled2/support/OpTreeContext.scala
+++ b/parboiled-core/src/main/scala/org/parboiled2/support/OpTreeContext.scala
@@ -44,7 +44,7 @@ class OpTreeContext[OpTreeCtx <: reflect.macros.blackbox.Context](val c: OpTreeC
     protected def renderInner(wrapped: Boolean): Tree
   }

-  sealed abstract class DefaultNonTerminalOpTree extends NonTerminalOpTree {
+  abstract class DefaultNonTerminalOpTree extends NonTerminalOpTree {
     def bubbleUp: Tree = q"e.bubbleUp($ruleTraceNonTerminalKey, start)"
     def ruleTraceNonTerminalKey: Tree
   }
@@ -80,7 +80,7 @@ class OpTreeContext[OpTreeCtx <: reflect.macros.blackbox.Context](val c: OpTreeC
       case x ⇒ c.abort(x.pos, "Unexpected Lifter: " + lifterTree)
     }

-  val opTreePF: PartialFunction[Tree, OpTree] = {
+  def opTreePF: PartialFunction[Tree, OpTree] = {
     case q"$lhs.~[..$a]($rhs)($c, $d)"                   ⇒ Sequence(OpTree(lhs), OpTree(rhs))
     case q"$lhs.~!~[..$a]($rhs)($c, $d)"                 ⇒ Cut(OpTree(lhs), OpTree(rhs))
     case q"$lhs.|[..$a]($rhs)($b)"                       ⇒ FirstOf(OpTree(lhs), OpTree(rhs))
diff --git a/parboiled-core/src/main/scala/org/parboiled2/support/package.scala b/parboiled-core/src/main/scala/org/parboiled2/support/package.scala
index aec5137..c9e6e28 100644
--- a/parboiled-core/src/main/scala/org/parboiled2/support/package.scala
+++ b/parboiled-core/src/main/scala/org/parboiled2/support/package.scala
@@ -17,5 +17,5 @@
 package org.parboiled2

 package object support {
-  private[parboiled2] def `n/a` = throw new IllegalStateException("Untranslated compile-time only call")
+  def `n/a` = throw new IllegalStateException("Untranslated compile-time only call")
 }


If it sounds good then I complete the PR. After that I publish detailed instruction on custom rule creation at http://myltsev.name.

A.

Mathias Doenitz

unread,
Aug 6, 2015, 3:03:54 PM8/6/15
to parboil...@googlegroups.com
Hey Alex,

sorry for not replying earlier! (I am incredibly busy currently with getting a new company bootstrapped.)

I don’t think we should expose any of our internals as public API, at least not at this point.
Doing so would make it much harder to evolve parboiled's internal structure, which is in fact something that I’m planning to do quite heavily in the near future.
There is quite a bit that can be (and needs to be) improved in order to take pb2 to the next level, mainly with regard to macro robustness. Currently we are still way to brittle, users see to many compiler errors that are due to inadequacy of our current macro implementation. AFAICS there are ways to make things better here.

Cheers,
Mathias

---
mat...@parboiled.org
http://www.parboiled.org
> --
> You received this message because you are subscribed to the Google Groups "parboiled2.org User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to parboiled-use...@googlegroups.com.
> Visit this group at http://groups.google.com/group/parboiled-user.
> To view this discussion on the web visit https://groups.google.com/d/msgid/parboiled-user/2ded59d7-c208-42df-834f-cf18c54c422f%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages