fastparse
fastparse copied to clipboard
Add `zipWith` and `traverse` support
Motivation:
Input: Seq[FunctionType]
output: P[Seq[Expr]]
When parsing the JSONPath Function, where the function is predefined, and after the function name is parsed, query the FunctionRegistry, which returns a function definition. A function definition has a Seq[FunctionType]
So when parsing the parameters, we must choose the correct parser.
Currently:
private def `function-params`[_: P](parameterTypes: java.util.List[FunctionType]): P[java.util.List[_ <: Expression]] = {
import scala.jdk.CollectionConverters._
traverse(parameterTypes.asScala) {
case FunctionType.VALUE => ??? //...
case FunctionType.LOGICAL => ??? //...
case FunctionType.NodeList => ???
}.map(_.asJava)
}
private implicit class ParserOps[A](val self: P[A]) extends AnyVal {
def zipWith[U, R, _: P](that: P[U])(f: (A, U) => R): P[R] = P(
for {
r1 <- self
r2 <- that
} yield f(r1, r2)
)
}
private def traverse[A, B, M[X] <: IterableOnce[X], _: P](in: M[A])(fn: A => P[B])(implicit bf: BuildFrom[M[A], B, M[B]]): P[M[B]] =
in.iterator.foldLeft(Pass(bf.newBuilder(in))) {
(fr, a) => fr.zipWith(fn(a))(addToBuilderFun)
}.map(_.result())
When debugging, seems it not working as expected.
name: $[?search(@ ,'[a-z]+')]
selector: space between arg and comma
isInValid: false
java.lang.ClassCastException: class com.alibaba.ultramax.mtop.jsonpath.ast.Expression$ValueExpression$PathValueExpression cannot be cast to class scala.collection.mutable.Builder (com.alibaba.ultramax.mtop.jsonpath.ast.Expression$ValueExpression$PathValueExpression and scala.collection.mutable.Builder are in unnamed module of loader 'app')
switch to something:
private def functionParametersParser[_: P](parameterTypeItr: util.Iterator[FunctionType],
resultList: util.ArrayList[Expression]): P[java.util.List[Expression]] =
P {
if (parameterTypeItr.hasNext) {
val parameterType = parameterTypeItr.next()
getArgumentParser(parameterType).flatMap { arg =>
resultList.add(arg)
functionParametersParser(parameterTypeItr, resultList)
}
} else {
Pass(resultList)
}
}