13
13
package scala
14
14
package util .parsing .combinator
15
15
16
+ import scala .util .DynamicVariable
16
17
import scala .util .parsing .input ._
17
18
import scala .collection .mutable .ListBuffer
18
19
import scala .annotation .tailrec
@@ -221,7 +222,7 @@ trait Parsers {
221
222
}
222
223
223
224
def Parser [T ](f : Input => ParseResult [T ]): Parser [T ]
224
- = new Parser [T ]{ def apply (in : Input ) = f(in) }
225
+ = new Parser [T ]{ def parse (in : Input ) = f(in) }
225
226
226
227
private [combinator] def Success [U ](res : U , next : Input , failure : Option [Failure ]): ParseResult [U ] =
227
228
new Success (res, next) { override val lastFailure : Option [Failure ] = failure }
@@ -236,8 +237,27 @@ trait Parsers {
236
237
case _ => None
237
238
}
238
239
240
+ val skipParser : DynamicVariable [Option [Parser [Any ]]] = new DynamicVariable (None );
241
+
242
+ final def skip (in : Input ): Input = {
243
+ skipParser.value match {
244
+ case None => in
245
+ case Some (parser) => {
246
+ skipParser.withValue(None ) {
247
+ parser(in) match {
248
+ case Success (_,next) => {
249
+ next
250
+ }
251
+ // A parser whose purpose is to skip shouldn't fail; it should just not skip stuff
252
+ case _ => in
253
+ }
254
+ }
255
+ }
256
+ }
257
+ }
258
+
239
259
def OnceParser [T ](f : Input => ParseResult [T ]): Parser [T ] with OnceParser [T ]
240
- = new Parser [T ] with OnceParser [T ] { def apply (in : Input ) = f(in) }
260
+ = new Parser [T ] with OnceParser [T ] { def parse (in : Input ) = f(in) }
241
261
242
262
/** The root class of parsers.
243
263
* Parsers are functions from the Input type to ParseResult.
@@ -248,7 +268,10 @@ trait Parsers {
248
268
override def toString = s " Parser ( $name) "
249
269
250
270
/** An unspecified method that defines the behaviour of this parser. */
251
- def apply (in : Input ): ParseResult [T ]
271
+ def parse (in : Input ): ParseResult [T ]
272
+ def apply (in : Input ): ParseResult [T ] = {
273
+ parse(skip(in))
274
+ }
252
275
253
276
def flatMap [U ](f : T => Parser [U ]): Parser [U ]
254
277
= Parser { in => this (in) flatMapWithNext(f)}
@@ -268,6 +291,20 @@ trait Parsers {
268
291
Parser { in => this (in) append p(in)}
269
292
}
270
293
294
+ /** A parser combinator that changes skipping behavior
295
+ */
296
+ def << (toSkip : => Option [Parser [Any ]]): Parser [T ] = {
297
+ val originalParse : Input => ParseResult [T ] = parse
298
+ new Parser [T ] {
299
+ override def apply (in : Input ): ParseResult [T ] = {
300
+ skipParser.withValue(toSkip) {
301
+ parse(skip(in))
302
+ }
303
+ }
304
+ def parse (in : Input ): ParseResult [T ] = originalParse(in)
305
+ }.named(name)
306
+ }
307
+
271
308
// the operator formerly known as +++, ++, &, but now, behold the venerable ~
272
309
// it's short, light (looks like whitespace), has few overloaded meaning (thanks to the recent change from ~ to unary_~)
273
310
// and we love it! (or do we like `,` better?)
@@ -324,7 +361,7 @@ trait Parsers {
324
361
325
362
/* not really useful: V cannot be inferred because Parser is covariant in first type parameter (V is always trivially Nothing)
326
363
def ~~ [U, V](q: => Parser[U])(implicit combine: (T, U) => V): Parser[V] = new Parser[V] {
327
- def apply (in: Input) = seq(Parser.this, q)((x, y) => combine(x,y))(in)
364
+ def parse (in: Input) = seq(Parser.this, q)((x, y) => combine(x,y))(in)
328
365
} */
329
366
330
367
/** A parser combinator for non-back-tracking sequential composition.
@@ -391,7 +428,7 @@ trait Parsers {
391
428
*/
392
429
def ||| [U >: T ](q0 : => Parser [U ]): Parser [U ] = new Parser [U ] {
393
430
lazy val q = q0 // lazy argument
394
- def apply (in : Input ) = {
431
+ def parse (in : Input ) = {
395
432
val res1 = Parser .this (in)
396
433
val res2 = q(in)
397
434
@@ -427,7 +464,7 @@ trait Parsers {
427
464
*/
428
465
def ^^^ [U ](v : => U ): Parser [U ] = new Parser [U ] {
429
466
lazy val v0 = v // lazy argument
430
- def apply (in : Input ) = Parser .this (in) map (x => v0)
467
+ def parse (in : Input ) = Parser .this (in) map (x => v0)
431
468
}.named(toString+ " ^^^" )
432
469
433
470
/** A parser combinator for partial function application.
@@ -769,18 +806,18 @@ trait Parsers {
769
806
770
807
def continue (in : Input , failure : Option [Failure ]): ParseResult [List [T ]] = {
771
808
val p0 = p // avoid repeatedly re-evaluating by-name parser
772
- @ tailrec def applyp (in0 : Input , failure : Option [Failure ]): ParseResult [List [T ]] = p0(in0) match {
809
+ @ tailrec def parsep (in0 : Input , failure : Option [Failure ]): ParseResult [List [T ]] = p0(in0) match {
773
810
case s @ Success (x, rest) =>
774
811
val selectedFailure = selectLastFailure(s.lastFailure, failure)
775
812
elems += x
776
- applyp (rest, selectedFailure)
813
+ parsep (rest, selectedFailure)
777
814
case e @ Error (_, _) => e // still have to propagate error
778
815
case f : Failure =>
779
816
val selectedFailure = selectLastFailure(failure, Some (f))
780
817
Success (elems.toList, in0, selectedFailure)
781
818
}
782
819
783
- applyp (in, failure)
820
+ parsep (in, failure)
784
821
}
785
822
786
823
first(in) match {
@@ -804,14 +841,14 @@ trait Parsers {
804
841
val elems = new ListBuffer [T ]
805
842
val p0 = p // avoid repeatedly re-evaluating by-name parser
806
843
807
- @ tailrec def applyp (in0 : Input , failure : Option [Failure ]): ParseResult [List [T ]] =
844
+ @ tailrec def parsep (in0 : Input , failure : Option [Failure ]): ParseResult [List [T ]] =
808
845
if (elems.length == num) Success (elems.toList, in0, failure)
809
846
else p0(in0) match {
810
- case s @ Success (x, rest) => elems += x ; applyp (rest, s.lastFailure)
847
+ case s @ Success (x, rest) => elems += x ; parsep (rest, s.lastFailure)
811
848
case ns : NoSuccess => ns
812
849
}
813
850
814
- applyp (in, None )
851
+ parsep (in, None )
815
852
}
816
853
817
854
/** A parser generator for a specified range of repetitions interleaved by a
@@ -835,13 +872,13 @@ trait Parsers {
835
872
836
873
def continue (in : Input ): ParseResult [List [T ]] = {
837
874
val p0 = sep ~> p // avoid repeatedly re-evaluating by-name parser
838
- @ tailrec def applyp (in0 : Input ): ParseResult [List [T ]] = p0(in0) match {
839
- case Success (x, rest) => elems += x; if (elems.length == m) Success (elems.toList, rest, None ) else applyp (rest)
875
+ @ tailrec def parsep (in0 : Input ): ParseResult [List [T ]] = p0(in0) match {
876
+ case Success (x, rest) => elems += x; if (elems.length == m) Success (elems.toList, rest, None ) else parsep (rest)
840
877
case e @ Error (_, _) => e // still have to propagate error
841
878
case _ => Success (elems.toList, in0, None )
842
879
}
843
880
844
- applyp (in)
881
+ parsep (in)
845
882
}
846
883
847
884
mandatory(in) match {
@@ -973,7 +1010,7 @@ trait Parsers {
973
1010
* if `p` consumed all the input.
974
1011
*/
975
1012
def phrase [T ](p : Parser [T ]) = new Parser [T ] {
976
- def apply (in : Input ) = p(in) match {
1013
+ def parse (in : Input ) = p(in) match {
977
1014
case s @ Success (out, in1) =>
978
1015
if (in1.atEnd) s
979
1016
else s.lastFailure match {
0 commit comments