2015-03-07 1 views
0

Javadoc для RegexParsers признака содержит следующий пример:калькулятор Скала RegexParser Пример правой ассоциативности

object Calculator extends RegexParsers { 
    def number: Parser[Double] = """\d+(\.\d*)?""".r ^^ { _.toDouble } 
    def factor: Parser[Double] = number | "(" ~> expr <~ ")" 
    def term : Parser[Double] = factor ~ rep("*" ~ factor | "/" ~ factor) ^^ { 
     case number ~ list => (number /: list) { 
     case (x, "*" ~ y) => x * y 
     case (x, "/" ~ y) => x/y 
     } 
    } 
    def expr : Parser[Double] = term ~ rep("+" ~ log(term)("Plus term") | "-" ~ log(term)("Minus term")) ^^ { 
     case number ~ list => list.foldLeft(number) { // same as before, using alternate name for /: 
     case (x, "+" ~ y) => x + y 
     case (x, "-" ~ y) => x - y 
     } 
    } 

    def apply(input: String): Double = parseAll(expr, input) match { 
     case Success(result, _) => result 
     case failure : NoSuccess => scala.sys.error(failure.msg) 
    } 
    } 

При анализе экспрессии 5 - 4 - 2 он рассматривает это как (5 - 4) - 2 и возвращает -1. Как я могу изменить этот анализатор на право-ассоциативный, чтобы он действительно оценил 5 - (4 - 2) и вернул 3?

ответ

0

мне удалось сделать грамматику быть правым ассоциативным:

trait Tree 
case class Node(op: String, left: Tree, right: Tree) extends Tree 
case class Leaf(value: BigInt) extends Tree 

class ExpressionParser extends RegexParsers { 
    var result : BigInt = 0 

    def number: Parser[Tree] = """-?\d+""".r ^^ { s => Leaf(BigInt(s))} 

    def expr : Parser[Tree] = (term ~ ("+" | "-") ~ expr ^^ { 
    case ((x ~ op) ~ y) => Node(op, x, y) 
    }) | term 

    def term : Parser[Tree] = (factor ~ ("*" | "/") ~ term ^^ { 
    case ((x ~ op) ~ y) => Node(op, x, y) 
    }) | factor 

    def factor : Parser[Tree] = number | "(" ~> expr <~ ")" 

}