diff --git a/src/commonMain/kotlin/me/alllex/parsus/parser/parsers.kt b/src/commonMain/kotlin/me/alllex/parsus/parser/parsers.kt index 1df053c..fe39c64 100644 --- a/src/commonMain/kotlin/me/alllex/parsus/parser/parsers.kt +++ b/src/commonMain/kotlin/me/alllex/parsus/parser/parsers.kt @@ -68,9 +68,9 @@ suspend fun ParsingScope.split( val values = mutableListOf() values += if (!allowEmpty) term() else poll(term) ?: return emptyList() - while (true) { - poll(separator) ?: break - values += if (!trailingSeparator) term() else (poll(term) ?: break) + values += repeat(ignored(separator) * term, atLeast = 0) + if (trailingSeparator) { + poll(separator) } return values } diff --git a/src/commonTest/kotlin/me/alllex/parsus/Tests.kt b/src/commonTest/kotlin/me/alllex/parsus/Tests.kt index fdfd52e..8738125 100644 --- a/src/commonTest/kotlin/me/alllex/parsus/Tests.kt +++ b/src/commonTest/kotlin/me/alllex/parsus/Tests.kt @@ -435,6 +435,29 @@ class Tests { assertParsed("a,a").isEqualTo(node(a.lex(0), a.lex(2))) assertParsed("a,a,").isEqualTo(node(a.lex(0), a.lex(2))) } + + object : Grammar() { + val com by literalToken(",") + val a by literalToken("a") + val b by literalToken("b") + val ap by parser { lexeme(a) } + val bp by parser { lexeme(b) } + override val root by separated(ap, com) * -com * bp map { (a, b) -> node(a + b) } + }.run { + assertParsed("a,b").isEqualTo(node(a.lex(0), b.lex(2))) + assertParsed("a,a,b").isEqualTo(node(a.lex(0), a.lex(2), b.lex(4))) + } + + object : Grammar() { + val com by literalToken(",") + val a by literalToken("a") + val b by literalToken("b") + val ap by parser { lexeme(a) } + val bp by parser { lexeme(b) } + override val root by separated(ap, com, trailingSeparator = true) * -com * bp map { (a, b) -> node(a + b) } + }.run { + assertParsed("a,,b").isEqualTo(node(a.lex(0), b.lex(3))) + } } }