Alok
Alok

Reputation: 1506

Scala Parser Combinators :Extract List of a type

I am writing parser and grammer using scala.util.parsing.combinator . My input is ":za >= 1 alok && :ft == 9"

case class Expression(op1:Operand,operator:Operator,op2:Operand)

def word: Parser[String] = """[a-z\\\s]+""".r ^^ { _.toString }

def colonWord:Parser[Operand]=":"~> word ^^{case variable => Operand(variable)}

def constant:Parser[Operand]="""^[a-zA-Z0-9\\\s-]*""".r ^^ {case constant => Operand(constant)}

def expression:Parser[Expression] = colonWord ~ operator ~ constant  ^^{ case op1~operator~op2 => Expression(op1, operator, op2)}

def expressions = expression ~ opt(" && " ~> expression)* 

but when I parse sample String , the result is not expected. The second expression after && is not parsed. Please note there can be multiple expression joined using &&.

When i execute:

val expr= ":za >= 1 alok && :ft == 9"
    parse(expressions, expr) match {
      case Success(matched, _) => println(matched)
      case ..}

Output is :

List((Expression(za ,>= ,1 alok )~None))

I dont see the second expression being parsed. Can anyone help what have i missed here?

EDIT -----------------------------------

The requirement is to get List[Expression]. when I say, incorporting the changes mentioned in Ans :

def expressions = expression ~ ("&&" ~> expression)* 

The return type of expressions is not List[Expression]. For eg: If I write another def :

case class Condition(exprs: List[Expression], st:Statement)
def condition = expressions ~","~statement ^^{
    case exprs~commaa~statement => Condition(exprs,statement) //This is giving error.

the error is: type mismatch; found : ~[Expression,Expression]] required: Expressions.

So how do i convert [Expression, Expression] to List[Expressions]?

Thanks

Upvotes: 1

Views: 795

Answers (1)

Jatin
Jatin

Reputation: 31724

The correction needed was:

expression ~ opt("&&" ~> expression)*

Remove space across && and it should work. This is because you are already covering space in your constant parser.

Edit: Based on edited question, is this what you want:

 def expressions = expression ~ (("&&" ~> expression)*) ^^{
    case x ~ y => x :: y
  }

Now the return type of expressions is List[Expression]. Your condition will now compile

Upvotes: 2

Related Questions