Code Monkey home page Code Monkey logo

parsequery's Introduction

parsequery

Build Status

What is Parsequery?

Parsequery is a parser combinator library. It uses staging to remove composition overhead at compile time to produce efficient, fast parsers. Its interface is almost similar to Scala's parser combinators.

Example

To benefit from staging, you wrap your parser declarations in the optimise scope. Here is an example JSON parser:

  sealed abstract class JSValue
  case class JSObject(dict: List[(String, JSValue)]) extends JSValue
  case class JSArray(arr: List[JSValue]) extends JSValue
  case class JSDouble(d: Double) extends JSValue
  case class JSString(s: String) extends JSValue
  case class JSBool(b: Boolean) extends JSValue
  case object JSNull extends JSValue

  val jsonParser = optimise {

    def value: Parser[JSValue] = (
      obj |
      arr |
      stringLiteral.map(x => JSString(x)) |
      double.map(x => JSDouble(x)) |
      accept("null").map(_ => JSNull) |
      accept("true").map(_ => JSBool(true)) |
      accept("false").map(_ => JSBool(false))
    )

    def obj: Parser[JSValue] = (skipWs(accept('{')) ~>
      repsep(member, skipWs(accept(',')))
    <~ skipWs(accept('}'))) map { x => JSObject(x) }

    def arr: Parser[JSValue] = (skipWs(accept('[')) ~>
      repsep(value, skipWs(accept(',')))
    <~ skipWs(accept(']'))) map { x => JSArray(x) }

    def member: Parser[(String, JSValue)] =
      stringLiteral ~ (skipWs(accept(':')) ~> value)

    value
  }

You run the parser as follows:

val myReader = CharReader("""{"libname": "parsequery"}""".toArray)

jsonParser(myReader) match {
  case Success(res, rest) => println(res)
  case Failure(err, _)    => println(err)
}

You can find more examples in the test files here

How do I use it?

A snapshot is available on Sonatype. To use it with SBT, add the following lines to your build:

libraryDependencies += "com.github.manojo" %% "parsequery" % "0.1-SNAPSHOT"
resolvers += Resolver.sonatypeRepo("snapshots")

How fast is it?

Check for yourself, by running the following two benchmarks, sources here and here:

> bench:testOnly parsequery.BooleansBenchmark
> bench:testOnly parsequery.JSONBenchmark

On these benchmarks we are currently about 2-3x faster than FastParse.

More Information

The main goal of parsequery is to systematically eliminate all intermediate data structures that are creating when running a traditional parser combinator program. Typically, parser combinators interleave static composition of parsers with the dynamic act of parsing itself, at runtime. The key insight is that we can fully decouple the static parts from the dynamic ones. This is done by leveraging a technique known as partial evaluation. To know more about the ideas check out the these blog posts on optimising list pipelines and parser combinators. A more detailed blog post catered to the current implementation is to appear soon.

You can find a talk about this here and the accompanying slides here.

This implementation draws inspiration from previous implementations in the LMS framework, found [here](https://github.com/ma nojo/functadelic/tree/master/src/main/scala/stagedparsec) and a macro implementation by the man called Eric Béguet, found here.

parsequery's People

Contributors

manojo avatar jvican avatar heathermiller avatar

Stargazers

Andrejs Agejevs avatar Masanori Ogino avatar  avatar Borislav Iordanov avatar  avatar Tienson Qin avatar Bastian Müller avatar Charles Vinodh avatar  avatar Zin avatar Jan avatar  avatar Adam Wyłuda avatar Chris Birchall avatar Ben Sowell avatar Masashi Fujita avatar  avatar YUSUKE IZAWA avatar Kota Mizushima avatar Tongfei Chen avatar hrj avatar  avatar narayanareddy avatar wp.yi' avatar Jarno Keskikangas avatar  avatar Jarek Przygódzki avatar Nikolay Donets avatar Takeru Sato avatar Martin Mauch avatar He-Pin(kerr) avatar  avatar Suminda Sirinath Salpitikorala Dharmasena avatar Samuel Gruetter avatar

Watchers

Franklin Chen avatar  avatar He-Pin(kerr) avatar  avatar James Cloos avatar Andreas Gebhardt avatar  avatar Béguet Eric avatar

Forkers

adilakhter

parsequery's Issues

Build for Scala 2.12

I use scala.util.parsing.combinators currently. I'd like to use parsequery to optmize my parser, which is built on Scala 2.12. Is it planned to publish parsequery for Scala 2.12 ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.