Skip to content

Commit

Permalink
Favour p to q in ||| parser if consuming same #chars, fixes #72
Browse files Browse the repository at this point in the history
  • Loading branch information
Philippus committed Apr 10, 2019
1 parent 4bcdc4d commit 6ee1688
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,6 @@ trait Parsers {
*/
def | [U >: T](q: => Parser[U]): Parser[U] = append(q).named("|")

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

(res1, res2) match {
case (s1 @ Success(_, next1), s2 @ Success(_, next2)) => if (next2.pos < next1.pos) s1 else s2
case (s1 @ Success(_, next1), s2 @ Success(_, next2)) => if (next2.pos < next1.pos || next2.pos == next1.pos) s1 else s2
case (s1 @ Success(_, _), _) => s1
case (_, s2 @ Success(_, _)) => s2
case (e1 @ Error(_, _), _) => e1
case (f1 @ Failure(_, next1), ns2 @ NoSuccess(_, next2)) => if (next2.pos < next1.pos) f1 else ns2
case (f1 @ Failure(_, next1), ns2 @ NoSuccess(_, next2)) => if (next2.pos < next1.pos || next2.pos == next1.pos) f1 else ns2
}
}
override def toString = "|||"
Expand Down
28 changes: 28 additions & 0 deletions shared/src/test/scala/scala/util/parsing/combinator/gh72.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import scala.util.parsing.combinator.Parsers
import scala.util.parsing.input.CharSequenceReader

import org.junit.Test
import org.junit.Assert.assertEquals

class gh72 {
class TestParsers extends Parsers {
type Elem = Char
val left: Parser[String] = 'a' ~ 'b' ~ 'c' ^^^ "left" withFailureMessage "failure on left"
val right: Parser[String] = 'a' ~ 'b' ~ 'c' ^^^ "right" withFailureMessage "failure on right"
def p: Parser[String] = left ||| right
}

@Test
def test(): Unit = {
val tstParsers = new TestParsers
val s = new CharSequenceReader("abc")
assertEquals("[1.4] parsed: left", tstParsers.p(s).toString)

val t = new CharSequenceReader("def")
val expectedFailure = """[1.1] failure: failure on left
def
^"""
assertEquals(expectedFailure, tstParsers.p(t).toString)
}
}

0 comments on commit 6ee1688

Please sign in to comment.