Skip to content

Commit

Permalink
Add naive JSON grammar test
Browse files Browse the repository at this point in the history
  • Loading branch information
alllex committed Oct 5, 2023
1 parent 3368259 commit 915edc8
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions src/commonTest/kotlin/me/alllex/parsus/GrammarTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import assertk.assertThat
import assertk.assertions.isEqualTo
import me.alllex.parsus.parser.*
import me.alllex.parsus.token.literalToken
import me.alllex.parsus.token.regexToken
import me.alllex.parsus.tree.SyntaxTree
import me.alllex.parsus.tree.lexeme
import kotlin.test.Test
Expand Down Expand Up @@ -80,4 +81,56 @@ class GrammarTests {
}
}

@Test
fun naiveJsonGrammarTest() {
NaiveJsonGrammar.run {
assertParsed("""{${'\n'}"a": 1,${'\n'}"b": {"c":false}${'\n'}}""").isEqualTo(
Json.Obj(
mapOf(
"a" to Json.Num(1.0),
"b" to Json.Obj(mapOf("c" to Json.Bool(false)))
)
)
)
}
}

sealed class Json {
object Null : Json() {
override fun toString(): String = "Null"
}

data class Bool(val value: Boolean) : Json()
data class Num(val value: Double) : Json()
data class Str(val value: String) : Json()
data class Arr(val values: List<Json>) : Json()
data class Obj(val values: Map<String, Json>) : Json()
}

object NaiveJsonGrammar : Grammar<Json>() {
init {
regexToken("\\s+", ignored = true)
}

private val comma by literalToken(",")
private val colon by literalToken(":")
private val lbrace by literalToken("{")
private val rbrace by literalToken("}")
private val lbracket by literalToken("[")
private val rbracket by literalToken("]")
private val str by regexToken("\"[^\\\\\"]*(\\\\[\"nrtbf\\\\][^\\\\\"]*)*\"") map { it.text.run { substring(1, lastIndex) } }
private val jsonTrue by literalToken("true") map { Json.Bool(true) }
private val jsonFalse by literalToken("false") map { Json.Bool(false) }
private val jsonNull by literalToken("null") map Json.Null
private val jsonNum by regexToken("-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?") map { Json.Num(it.text.toDouble()) }
private val jsonStr by str map { Json.Str(it) }

private val keyValue by str * -colon and ref(::jsonValue) map { it.toPair() }
private val jsonObj by -lbrace * separated(keyValue, comma) * -rbrace map { Json.Obj(it.toMap()) }

private val jsonArr by -lbracket * separated(ref(::jsonValue), comma) * -rbracket map { Json.Arr(it) }
private val jsonValue: Parser<Json> by jsonNull or jsonTrue or jsonFalse or jsonNum or jsonStr or jsonArr or jsonObj
override val root by jsonValue
}

}

0 comments on commit 915edc8

Please sign in to comment.