Skip to content

Commit 8709067

Browse files
authored
Merge pull request #162 from Philippus/issue-1229
Add 'exception' operator, closes scala/bug#1229
2 parents 86f570d + 23b4dd7 commit 8709067

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

shared/src/main/scala/scala/util/parsing/combinator/Parsers.scala

+10
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,16 @@ trait Parsers {
290290
(for(a <- this; b <- p) yield a).named("<~")
291291
}
292292

293+
/**
294+
* A parser combinator for exceptions.
295+
*
296+
* `p - q` succeeds if `p` succeeds, and `q` fails on the same input given `p`.
297+
*
298+
* @param q a parser that will be executed before `p` (this parser). q will not consume the input.
299+
* @return a `Parser` that returns the result of `p` (this parser) if it succeeds and q fails. If q succeeds, the parser will fail.
300+
*/
301+
def - [U](q: Parser[U]): Parser[T] = (not(q) ~> this).named("-")
302+
293303
/* not really useful: V cannot be inferred because Parser is covariant in first type parameter (V is always trivially Nothing)
294304
def ~~ [U, V](q: => Parser[U])(implicit combine: (T, U) => V): Parser[V] = new Parser[V] {
295305
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)