Skip to content

Commit 23b4dd7

Browse files
committed
Add 'exception' operator, closes scala/bug#1229
1 parent 4719736 commit 23b4dd7

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

Diff for: shared/src/main/scala/scala/util/parsing/combinator/Parsers.scala

+10
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,16 @@ trait Parsers {
301301
(for(a <- this; b <- p) yield a).named("<~")
302302
}
303303

304+
/**
305+
* A parser combinator for exceptions.
306+
*
307+
* `p - q` succeeds if `p` succeeds, and `q` fails on the same input given `p`.
308+
*
309+
* @param q a parser that will be executed before `p` (this parser). q will not consume the input.
310+
* @return a `Parser` that returns the result of `p` (this parser) if it succeeds and q fails. If q succeeds, the parser will fail.
311+
*/
312+
def - [U](q: Parser[U]): Parser[T] = (not(q) ~> this).named("-")
313+
304314
/* not really useful: V cannot be inferred because Parser is covariant in first type parameter (V is always trivially Nothing)
305315
def ~~ [U, V](q: => Parser[U])(implicit combine: (T, U) => V): Parser[V] = new Parser[V] {
306316
def apply(in: Input) = seq(Parser.this, q)((x, y) => combine(x,y))(in)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import scala.util.parsing.combinator.RegexParsers
2+
3+
import org.junit.Test
4+
import org.junit.Assert.assertEquals
5+
6+
class t1229 extends RegexParsers {
7+
val number = """0|[1-9]\d*""".r ^^ { _.toInt }
8+
9+
val parser: Parser[Int] = number - "42"
10+
11+
@Test
12+
def test: Unit = {
13+
assertEquals("[1.3] parsed: 21", parse(phrase(parser), "21").toString)
14+
15+
val expected = """[1.1] failure: Expected failure
16+
17+
42
18+
^"""
19+
assertEquals(expected, parse(phrase(parser), "42").toString )
20+
}
21+
}

0 commit comments

Comments
 (0)