fastparse icon indicating copy to clipboard operation
fastparse copied to clipboard

Add `zipWith` and `traverse` support

Open He-Pin opened this issue 1 year ago • 2 comments

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())

He-Pin avatar Dec 07 '24 19:12 He-Pin

When debugging, seems it not working as expected. image

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')

He-Pin avatar Dec 14 '24 22:12 He-Pin

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)
      }
    }

He-Pin avatar Dec 14 '24 23:12 He-Pin