Comments (5)
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.
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.
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.
@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.
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)
- docs can give warnings, which causes publish to fail
- orElse not working as expected HOT 3
- Either x or not y HOT 6
- Recursive parser creates infinite loop. HOT 1
- A parser string interpolator
- Backtracking with context HOT 1
- Rep same char as surrounded by HOT 5
- idea for safe repetition on Parser0
- RadixNode and stringIn are a bit slow
- Is it possible to support Scala Native? HOT 6
- alternate design for voiding
- use java.util.BitSet on scalajs
- `p1.? ~ p2` != `(p1 ~ p2) | p2` for error reporting purposes HOT 9
- Remove isScalaJs/isScalaJvm on minor version update
- identifier parser HOT 2
- flakey test: X cats.parse.ParserTest.a.flatMap(b) composes as expected parser00
- add json string parsing
- add a withString combinator
- Should `Parser` have a typeclass? HOT 2
- set up github CI to run benchmarks on release
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cats-parse.