1
// -----------------------------------------------------------------------------
3
// Scalax - The Scala Community Library
4
// Copyright (c) 2005-8 The Scalax Project. All rights reserved.
6
// The primary distribution site is http://scalax.scalaforge.org/
8
// This software is released under the terms of the Revised BSD License.
9
// There is NO WARRANTY. See the file LICENSE for the full text.
11
// -----------------------------------------------------------------------------
13
package org.json4s.scalap
15
import language.postfixOps
18
* A workaround for the difficulties of dealing with
19
* a contravariant 'In' parameter type...
21
class InRule[In, +Out, +A, +X](rule: Rule[In, Out, A, X]) {
23
def mapRule[Out2, B, Y](f: Result[Out, A, X] => In => Result[Out2, B, Y]): Rule[In, Out2, B, Y] = rule.factory.rule {
24
in: In => f(rule(in))(in)
27
/** Creates a rule that succeeds only if the original rule would fail on the given context. */
28
def unary_! : Rule[In, In, Unit, Nothing] = mapRule {
29
case Success(_, _) => in: In => Failure
30
case _ => in: In => Success(in, ())
33
/** Creates a rule that succeeds if the original rule succeeds, but returns the original input. */
34
def & : Rule[In, In, A, X] = mapRule {
35
case Success(_, a) => in: In => Success(in, a)
36
case Failure => in: In => Failure
37
case Error(x) => in: In => Error(x)
41
class SeqRule[S, +A, +X](rule: Rule[S, S, A, X]) {
44
def ? = rule mapRule {
45
case Success(out, a) => in: S => Success(out, Some(a))
46
case Failure => in: S => Success(in, None)
47
case Error(x) => in: S => Error(x)
50
/** Creates a rule that always succeeds with a Boolean value.
51
* Value is 'true' if this rule succeeds, 'false' otherwise */
52
def -? = ? map { _ isDefined }
55
// tail-recursive function with reverse list accumulator
56
def rep(in: S, acc: List[A]): Result[S, List[A], X] = rule(in) match {
57
case Success(out, a) => rep(out, a :: acc)
58
case Failure => Success(in, acc.reverse)
59
case err: Error[_] => err
66
def ~>?[B >: A, X2 >: X](f: => Rule[S, S, B => B, X2]) = for (a <- rule; fs <- f?) yield fs.foldLeft[B](a) { (b, f) => f(b) }
68
def ~>*[B >: A, X2 >: X](f: => Rule[S, S, B => B, X2]) = for (a <- rule; fs <- f*) yield fs.foldLeft[B](a) { (b, f) => f(b) }
70
def ~*~[B >: A, X2 >: X](join: => Rule[S, S, (B, B) => B, X2]) = {
71
this ~>* (for (f <- join; a <- rule) yield f(_: B, a))
74
/** Repeats this rule one or more times with a separator (which is discarded) */
75
def +/[X2 >: X](sep: => Rule[S, S, Any, X2]) = rule ~++ (sep -~ rule *)
77
/** Repeats this rule zero or more times with a separator (which is discarded) */
78
def */[X2 >: X](sep: => Rule[S, S, Any, X2]) = +/(sep) | state[S].nil
80
def *~-[Out, X2 >: X](end: => Rule[S, Out, Any, X2]) = (rule - end *) ~- end
81
def +~-[Out, X2 >: X](end: => Rule[S, Out, Any, X2]) = (rule - end +) ~- end
83
/** Repeats this rule num times */
84
def times(num: Int): Rule[S, S, Seq[A], X] = from[S] {
85
val result = new scala.collection.mutable.ArraySeq[A](num)
86
// more compact using HoF but written this way so it's tail-recursive
87
def rep(i: Int, in: S): Result[S, Seq[A], X] = {
88
if (i == num) Success(in, result)
90
case Success(out, a) => {
94
case Failure => Failure
95
case err: Error[_] => err