Skip to content

Yet another Parsers Combinator library on Scala 3. Functional, elegant, slow.

License

Notifications You must be signed in to change notification settings

wlad031/slowparse

Repository files navigation

slowparse

build

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.

Install (sbt)

  1. Install GitHub packages plugin.
  2. Add Resolver.githubPackages("wlad031") resolver.
  3. Include dependency:
libraryDependencies += "dev.vgerasimov" %% "slowparse" % "0.1.2",

Example

The following parser will be able to parse a valid JSON. Also it can be found in JsonParserTest.scala.

import dev.vgerasimov.slowparse.POut.*
import dev.vgerasimov.slowparse.*
import dev.vgerasimov.slowparse.Parsers.given
import dev.vgerasimov.slowparse.Parsers.*

sealed trait Json
case object JNull extends Json
case class JBoolean(v: Boolean) extends Json
case class JNumber(v: Double) extends Json
case class JString(v: String) extends Json
case class JArray(v: List[Json]) extends Json
case class JObject(v: Map[String, Json]) extends Json

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] =
  (anyFrom("+-").? ~ d.+ ~ (P(".") ~ d.*).? ~ (anyFrom("Ee") ~ anyFrom("+-").? ~ d.*).?).!.map(_.toDouble)
    .map(JNumber(_))
val pStr: P[JString] =
  (P("\"") ~ until(!P("\\") ~ P("\""), (P("\\\"") | anyChar)).! ~ (!P("\\") ~ P("\"")))
    .map(JString(_))
val pChoice: P[Json] = P(choice(pNull, pBool, pNum, pStr, pArr, pObj))
val pArr: P[JArray] = P("[") ~~ pChoice
  .rep(sep = Some(ws0 ~ P(",") ~ ws0))
  .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 = Some(ws0 ~ P(",") ~ ws0))
  P("{") ~~ pairs.map(_.toMap).map(JObject(_)) ~~ P("}")

// final parser
val json: P[Json] = P(pObj | pArr)

About

Yet another Parsers Combinator library on Scala 3. Functional, elegant, slow.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Languages