Skip to content

Commit 6ee1688

Browse files
committed
Favour p to q in ||| parser if consuming same #chars, fixes scala#72
1 parent 4bcdc4d commit 6ee1688

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

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

+2-3
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,6 @@ trait Parsers {
365365
*/
366366
def | [U >: T](q: => Parser[U]): Parser[U] = append(q).named("|")
367367

368-
// TODO
369368
/** A parser combinator for alternative with longest match composition.
370369
*
371370
* `p ||| q` succeeds if `p` succeeds or `q` succeeds.
@@ -382,11 +381,11 @@ trait Parsers {
382381
val res2 = q(in)
383382

384383
(res1, res2) match {
385-
case (s1 @ Success(_, next1), s2 @ Success(_, next2)) => if (next2.pos < next1.pos) s1 else s2
384+
case (s1 @ Success(_, next1), s2 @ Success(_, next2)) => if (next2.pos < next1.pos || next2.pos == next1.pos) s1 else s2
386385
case (s1 @ Success(_, _), _) => s1
387386
case (_, s2 @ Success(_, _)) => s2
388387
case (e1 @ Error(_, _), _) => e1
389-
case (f1 @ Failure(_, next1), ns2 @ NoSuccess(_, next2)) => if (next2.pos < next1.pos) f1 else ns2
388+
case (f1 @ Failure(_, next1), ns2 @ NoSuccess(_, next2)) => if (next2.pos < next1.pos || next2.pos == next1.pos) f1 else ns2
390389
}
391390
}
392391
override def toString = "|||"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import scala.util.parsing.combinator.Parsers
2+
import scala.util.parsing.input.CharSequenceReader
3+
4+
import org.junit.Test
5+
import org.junit.Assert.assertEquals
6+
7+
class gh72 {
8+
class TestParsers extends Parsers {
9+
type Elem = Char
10+
val left: Parser[String] = 'a' ~ 'b' ~ 'c' ^^^ "left" withFailureMessage "failure on left"
11+
val right: Parser[String] = 'a' ~ 'b' ~ 'c' ^^^ "right" withFailureMessage "failure on right"
12+
def p: Parser[String] = left ||| right
13+
}
14+
15+
@Test
16+
def test(): Unit = {
17+
val tstParsers = new TestParsers
18+
val s = new CharSequenceReader("abc")
19+
assertEquals("[1.4] parsed: left", tstParsers.p(s).toString)
20+
21+
val t = new CharSequenceReader("def")
22+
val expectedFailure = """[1.1] failure: failure on left
23+
24+
def
25+
^"""
26+
assertEquals(expectedFailure, tstParsers.p(t).toString)
27+
}
28+
}

0 commit comments

Comments
 (0)