Git Product home page Git Product logo

Comments (5)

johnynek avatar johnynek commented on June 3, 2024

If I were parsing this, I would do something like:

// parse expressions like names, `{1 + 1}` etc...
val pexpr: Parser[Expr] = ...

sealed trait Element
case class ExprEl(toExpr: Expr) extends Element
case class StringEl(toStr: String) extends Element

val pstr: Parser[List[Element]] = {
  import cats.parse.{Parser => P}
  val notDollar = P.not(P.charIn('\\' :: '"' :: Nil)).with1 *> ((P.char('\\') *> P.anyChar) | P.anyChar)
  
  val strEl: P[StringEl] = notDollar.repAs[String].map(StringEl(_))  

  val expr: P[ExprEl] = P.char('$') *> pexpr.map(ExprEl(_)) 
  
  P.string("json") *> (strEl | expr).rep <* P.char('"')
}

Something like that...

Does that make sense (warning, I didn't compile this, I just wrote it in the comment).

from cats-parse.

michel-steuwer avatar michel-steuwer commented on June 3, 2024

Sorry, I think I didn't make my question clear enough.
I don't want to parse json"{ name: $name, id: $id }" directly.
I want to use cats-parse to implement a parser to be used for an implementation of the Scala string interpolation feature.

At https://docs.scala-lang.org/overviews/core/string-interpolation.html#advanced-usage
they give a simple example implementation for a string interpolation json parser:

implicit class JsonHelper(val sc: StringContext) extends AnyVal {
  def json(args: Any*): JSONObject = {
    val strings = sc.parts.iterator
    val expressions = args.iterator
    var buf = new StringBuilder(strings.next())
    while(strings.hasNext) {
      buf.append(expressions.next())
      buf.append(strings.next())
    }
    parseJson(buf)
  }
}

The challenge here is that we don't have a single input string to parse, but two iterators: one for the string snippets, and one for the elements that separate these snippets.
So for

json"{ name: $name, id: $id }"

The sc.parts.iterator from above will return: "{ name: " and then ", id: " and finally " }" and the args.iterator will return the values of a variable name and id that are in the scala scope (as values of type Any).

How do I use cats-parse (or any other Scala combinator library) with this string / Any value iterator interfact?

from cats-parse.

johnynek avatar johnynek commented on June 3, 2024

I really don't know how this library might relate to what you are proposing.

I mean, you might want to parse the result of that string? so, are you talking about how to implement parseJson? I'd probably say it is better to use a library like circe or jawn for that.

from cats-parse.

ritschwumm avatar ritschwumm commented on June 3, 2024

@johnynek well, all this is about parsing a (slightly fancy) json string into a data structure, isn't it?

@michel-steuwer i think the "slightly fancy" will be a problem here:

what you get from StringContext is more structured than a plain string, and you'd want to make use of this additional structure.
you could for example convert the template into a Seq[Either[Char,Parameter]] and run a parser on this - but i don't think cat-parse supports parsing any other sequence of tokens than a String.

one way to attack that problem is concatenating the template literal strings, interspersed with some private unicode markers.
then you can have an almost normal json parser that just additionally expects these markers in certain places and returns the value associated to them in the template parameters when they occur.

from cats-parse.

johnynek avatar johnynek commented on June 3, 2024

Yeah. We only support String as an input (since it is by far the most common case and it we can optimize it considerably).

If you want to see an example parser for a structured type, see the JSON parser here:

https://github.com/typelevel/cats-parse/blob/main/bench/src/main/scala/cats/parse/bench/self.scala

Lastly, what I would do here is to just convert the whole interpolated argument to a string and then run the parser on that string.

from cats-parse.

Related Issues (20)

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.