Skip to content

No parse when using filter for associativity disambiguation + explicit parenthesis #34

Description

@danleh

Given the following test case

import cats.Eval
import parseback._
import parseback.ast._
import parseback.compat.cats._

object Testcase extends App {

  sealed trait Expr extends Node
  case class Identifier(name: String) extends Expr with LeafNode
  case class Application(left: Expr, right: Expr) extends Expr with BinaryNode {
    override def assocLeft: Boolean = true
    override def sym: Symbol = 'app
  }

  lazy val expr: Parser[Expr] = (
    """[a-zA-Z0-9]+""".r ^^ { (_, name) => Identifier(name) }
      | expr ~ " " ~ expr ^^ { (_, fun, _, arg) => Application(fun, arg) }
      | "(" ~> expr <~ ")"
    ) filter prec(Application)

  // Test 1, correct: gives the left assoc. AST
  println(expr(LineStream[Eval]("function1 function2 argument")).value.map(_.toList))

  // Test 2, bug? gives no error but an empty list of ASTs
  println(expr(LineStream[Eval]("function1 (function2 argument)")).value.map(_.toList))
}

where we define a simple grammar with just Identifiers and function Application. I intend application to be left-associative and thus write filter prec(Application) with BinaryNode and def assocLeft: Boolean = true.

The first example works fine, only the left-associative AST is returned. However, in the second example where we use parentheses, an empty list is returned (where we would expect the right-associative AST).

Am I using filter and/or BinaryNode wrong? Or is this a bug?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions