簡單版計算器

weixin_33866037發表於2017-04-19
object NumOperator {
  def main(args: Array[String]) {
    val input = Input("5+6*(2+1)")

    println(expr(input.str.toCharArray))
  }

  /**
    *
    * @param chars
    * @return
    */
  def expr(chars: Array[Char]): Float = {
    var tmp = term(chars)
    if (tokenIndex < chars.size) {
      val char = chars(tokenIndex)
      char match {
        case '+' => {
          tokenIndex = tokenIndex + 1
          tmp = tmp + term(chars)
        }
        case '-' => {
          tokenIndex = tokenIndex + 1
          tmp = tmp - term(chars)
        }
        case _ => {}
      }
    }
    tmp
  }

  def term(chars: Array[Char]): Float = {
    var tmp = factor(chars)
    if (tokenIndex < chars.size) {
      var char = chars(tokenIndex)
      char match {
        case '*' => {
          tokenIndex = tokenIndex + 1
          tmp = tmp * factor(chars)
        }
        case '/' => {
          tokenIndex = tokenIndex + 1
          tmp = tmp / factor(chars)
        }
        case _ => {

        }
      }

    }

    tmp
  }

  def factor(chars: Array[Char]): Float = {
    var tmp = 0F
    if (tokenIndex < chars.size) {
      var char = chars(tokenIndex)
      char match {
        case '(' => {
          tokenIndex = tokenIndex + 1
          tmp = expr(chars)
          tokenIndex = tokenIndex + 1
        }
        case isnum if isNum(char) => {

          tmp = num(chars)

        }
      }

    }
    tmp
  }

  var tokenIndex = 0

  def isNum(char: Char): Boolean = char match {
    case number if char >= '0' && char <= '9' => true
    case _ => false
  }

  def num(chars: Array[Char]): Float = {

    var result = 0
    for (index <- tokenIndex until chars.size) {
      var char = chars(index)
      char match {
        case isFloat if char == '.' && index < chars.size && isNum(chars(index + 1)) && index != 0 => result
        case isNum if char >= '0' && char <= '9' => result = result * 10 + (char.toInt - '0'.toInt)
        case isOperator if char == '*' || char == '+' || char == '-' || char == '/' || char == '(' || char == ')' => {
          tokenIndex = tokenIndex + 1
          return result
        }
        case _ => throw new RuntimeException("expecting num but not found")
      }
    }
    result
  }
}

case class Input(str: String)

相關文章