generated from wlad031/template-scala-sbt
-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Vladislav Gerasimov edited this page Nov 18, 2021
·
2 revisions
This is just my experiment with parser combinators and Scala 3. Highly inspired by fastparse from Li Haoyi and talk from Scott Wlaschin. If you want to use parser combinators in your project, probably better use fastparse.
The following parser will be able to parse a valid JSON. Also it can be found in JsonParserTest.scala.
import dev.vgerasimov.slowparse.Parsers.given
import dev.vgerasimov.slowparse.Parsers.*
// ... definitions of JSON classes are pretty straighforward, thus, omitted ...
val pNull: P[JNull.type] = P("null").map(_ => JNull)
val pBool: P[JBoolean] = (P("true").! | P("false").!).map(_.toBoolean).map(JBoolean(_))
val pNum: P[JNumber] =
(anyCharIn("+-").? ~ d.+ ~ (P(".") ~ d.*).? ~ (anyCharIn("Ee") ~ anyCharIn("+-").? ~ d.*).?).!.map(_.toDouble)
.map(JNumber(_))
val pStr: P[JString] = (P("\"") ~ until(P("\"")).! ~ P("\"")).map(JString(_))
val pChoice: P[Json] = P(choice(pNull, pBool, pNum, pStr, pArr, pObj))
val pArr: P[JArray] = P("[") ~~ pChoice.rep(sep = wss ~ P(",") ~ wss).map(JArray(_)) ~~ P("]")
val pObj: P[JObject] =
val pair: P[(String, Json)] = pStr.map(_.v) ~~ P(":") ~~ pChoice
val pairs: P[List[(String, Json)]] = pair.rep(sep = wss ~ P(",") ~ wss)
P("{") ~~ pairs.map(_.toMap).map(JObject(_)) ~~ P("}")
val json: P[Json] = P(pObj | pArr)