在Scala Parser中为变量赋值

时间:2017-06-06 09:47:25

标签: scala parsing

我对Scala中的Parser有疑问。我只是在这里发布重要的部分,以便不会有太多的代码。对于eval函数:

def eval(t: Term): Double = t match {
    case Addition(l, r) => eval(l) + eval(r)
    case Multiplication(l, r) => eval(l) * eval(r)
    case Numeric(i) => i
    case Variable("X") => 3
    }

计算功能:

def calculate(arg: String): Double = {
    return eval(parseAll(term, arg).get)
  }

现在我应该重载函数"计算"这样它需要额外的参数tup:(String,Double)并为此String赋值。例如(" Y",2)然后在解析器中Y = 2。然后计算解析器。但我不知道如何为此String分配值。我有一个愚蠢的想法并试过这个但它没有用。

def calculate(arg: String, tup : (String, Double)) : Double = {
    tup match {
      case (a,b) => {
        def eval(t : Term): Double = t match {
          case Variable(a) => b
        }
        return eval(parseAll(term, arg).get)
      }
    }
你能帮我解决一下吗?谢谢!!

1 个答案:

答案 0 :(得分:3)

你几乎就在那里,你只需要告诉编译器a模式中的Variable实际上是a模式中的(a, b)。默认情况下,您所做的操作称为变量名称a的阴影(在此模式匹配的范围内,aVariable中提取的值,另一个a被遗忘了。)

你想要的是

...
  case Variable(`a`) => b
...

或者,如果你的表达变得有点复杂,你应该使用一个警卫:

...
  case Variable(v) if v == a => b
...

编辑但是,现在您的eval功能定义不明确。你需要把它全部放在一起:

def eval(t: Term, varAssignement: (String, Double)): Double = t match {
  case Addition(l, r) => eval(l) + eval(r)
  case Multiplication(l, r) => eval(l) * eval(r)
  case Numeric(i) => i
  case Variable(a) if a == varAssignment._1 => varAssignment._2
}

或者,如果您想要多个变量:

def eval(t: Term, assignments: Map[String, Double]): Double = t match {
  case Addition(l, r) => eval(l) + eval(r)
  case Multiplication(l, r) => eval(l) * eval(r)
  case Numeric(i) => i
  case Variable(a) if assignments.exists(a) => assignments(a)
}

请注意,每当使用未分配的变量时,您仍会获得MatchError