h0tk3y/better-parse

Building parsers for fixed-width fields

KushalP opened this issue · 1 comments

Let's say I have a String containing numbers that I want to convert into a data class. The fields are of fixed width. How should I go about building a grammar that can achieve this without having the different tokens cause issues with each other?

At the moment I'm seeing a MismatchedToken exception.

Reproducible sample case

data class Line(
    val fieldA: Int,
    val fieldB: Int,
    val fieldC: Int
)

object LineGrammar : Grammar<Line>() {
    private val fieldA by token("[0-9]{2}")
    private val fieldB by token("[0-9]{5}")
    private val fieldC by token("[0-9]{3}")

    private val line =
        fieldA and fieldB and fieldC

    override val rootParser: Parser<Line> =
        line.map { (a, b, c) ->
            Line(
                fieldA = a.text.toInt(),
                fieldB = b.text.toInt(),
                fieldC = c.text.toInt()
            )
        }
}

val line = "1234567891"
val result = LineGrammar.parseToEnd(line)
// result should be Line(fieldA = 12, fieldB = 34567, fieldC = 891)
//
// Instead seeing the following exception
// Could not parse input: MismatchedToken(expected=fieldB ([0-9]{5}), found=fieldA for "34" at 2 (1:3))
// com.github.h0tk3y.betterParse.parser.ParseException: Could not parse input: MismatchedToken(expected=fieldB ([0-9]{5}), found=fieldA for "34" at 2 (1:3))
// 	at com.github.h0tk3y.betterParse.parser.ParserKt.toParsedOrThrow(Parser.kt:70)
// 	at com.github.h0tk3y.betterParse.parser.ParserKt.parseToEnd(Parser.kt:30)
// 	at com.github.h0tk3y.betterParse.grammar.GrammarKt.parseToEnd(Grammar.kt:69)

Ran into the same issue. Did you ever find a solution for this?