From f2de186ea62b22c16d38424db89c0e90d3fe75f5 Mon Sep 17 00:00:00 2001 From: Alex Semin Date: Tue, 19 Dec 2023 11:32:34 +0100 Subject: [PATCH] Fix `separated` and `split` combinator implementations --- .../kotlin/me/alllex/parsus/parser/parsers.kt | 6 ++--- .../kotlin/me/alllex/parsus/Tests.kt | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) 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))) + } } }