Skip to content

Incorrect mismatch location reported by RegexParsers #573

Open
@asarkar

Description

@asarkar
implicit def literal(s: String): Parser[String] = new Parser[String] {
  def apply(in: Input) = {
    val source = in.source
    val offset = in.offset
    val start = handleWhiteSpace(source, offset)
    var i = 0
    var j = start
    while (i < s.length && j < source.length && s.charAt(i) == source.charAt(j)) {
      i += 1
      j += 1
    }
    if (i == s.length)
      Success(source.subSequence(start, j).toString, in.drop(j - offset), None)
    else  {
      val found = if (start == source.length()) "end of source" else "'"+source.charAt(start)+"'"
      Failure("'"+s+"' expected but "+found+" found", in.drop(start - offset))
    }
  }
}

Note the error reporting at the end where the index of the mismatch is reported as start. If the string is "apple", and the input "...apply...", the mismatch is at the character 'y', which is pointed to by the variable j, not at the character 'a', which is pointed to by start.

println(parse("apple", "apply"))

Failure('apple' expected but 'a' found,CharSequenceReader('a', ...))

A potential fix may be as follows:

val rest = in.drop(start - offset)
if (start == source.length()) Failure(s"'$s' expected but end of source found", rest)
else Failure(s"'$s' expected but '${source.charAt(j)}' found at index $j", rest)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions