ChiPlusPlus
ChiPlusPlus

Reputation: 209

How to remove' identifier expected but integer literal found error' in Scala?

I am trying to build a function to identify if a an expresson has balanced parenthesis or not.

My problem is that I am getting this error on my functions for the variables opening_index and closing_index :

   Error:(3, 30) identifier expected but integer literal found.
  var  opening_index: Int =-1     
   Error:(6, 30) identifier expected but integer literal found.
  var  closing_index: Int =-1    
   Error:(34, 30) identifier expected but integer literal found.
  var  opening_index: Int =-1  
  Error:(37, 30) identifier expected but integer literal found.
  var  closing_index: Int =-1

I have been googling my error for the last hour without finding any valuable cluses.

Here is my code:

object Test
 {

  def balance(chars: List[Char]): Boolean=
   {     
    var  opening_index: Int =-1

    var  closing_index: Int =-1

  opening_index=chars.indexOf('(')
  closing_index=chars.indexOf(')')
  if (opening_index ==-1 && closing_index==-1)
    {

      true
    }
  if (closing_index>-1 && opening_index>-1)
    {
      if (closing_index<=opening_index) return(false)
      else
      {
        balance(chars.drop(closing_index).drop(opening_index))
      }
    }
  else
    return (false)
}
}

Upvotes: 0

Views: 2928

Answers (3)

James Whiteley
James Whiteley

Reputation: 3474

This can be simplified by just counting how many of each there are and seeing if the numbers match up:

def balance (chars: List[Char]): Boolean = {
  val opening = chars.count(_ == '(')
  val closing = chars.count(_ == ')')
  opening == closing
}

balance(List('(', ')', '(', ')', '(')) //false
balance(List('(', ')', '(', ')')) //true

If you want the balanced parentheses to be in order, you can do it recursively:

def balance(chars: List[Char], open: Int = 0): Boolean = {
  if (chars.isEmpty)
    open == 0
  else if (chars.head == '(')
    balance(chars.tail, open + 1)
  else if (chars.head == ')' && open > 0)
    balance(chars.tail, open - 1)
  else
    balance(chars.tail, open)
}

val x = "(apple + pear + (banana)))".toList
balance(x) //true

val y = "(()(".toList
balance(y) //false

This goes through every element of the list and adds/subtracts to/from a variable called open until the list is empty, at which point if open is 0 it returns true otherwise it returns false.

Upvotes: 1

Alexey Romanov
Alexey Romanov

Reputation: 170733

When Scala sees =-1, it gets tokenized (split) not as = -1 (as in other languages you may be familiar with), but as =- 1, since =- is a perfectly fine identifier in Scala.

Since = hasn't been seen, the entire Int =- 1 must be a type. By infix notation for types, it's equivalent to =-[Int, 1]. Except 1 here must be a type. To be a type it should start with an identifier, and that's what the error message is saying. If you fixed that, it would complain about unknown =- type next.

Upvotes: 1

user unknown
user unknown

Reputation: 36229

The tokenizer doesn't know, where a token ends or starts. Use some delimiters, which makes the code more readable for humans too:

object Test {

  def balance(chars: List[Char]): Boolean =
  {     
    var  opening_index: Int = -1
    var  closing_index: Int = -1
    opening_index=chars.indexOf ('(')
    closing_index=chars.indexOf (')')

    if (opening_index == -1 && closing_index == -1)
    {
      true
    }
    if (closing_index > -1 && opening_index > -1)
    {
      if (closing_index <= opening_index)
        return false
      else
        balance (chars.drop (closing_index).drop (opening_index))
    }
    else
      return false
  }
}

Since you only initialize your vars to reinitialize them directly again, you can easily earn some functional points by declaring them as vals:

  def balance (chars: List[Char]): Boolean =
  {     
    val opening_index: Int = chars.indexOf ('(')
    val closing_index: Int = chars.indexOf (')')

For recursive calls, you don't have to bother - those generate a new pair of values which don't interfere with those of the calling context.

You might also note, that return statements dont need a function-call-look with parens return (false) but can be written as return false, and even the return keyword is most of the time superflous.

object Test {

  def balance (chars: List[Char]): Boolean =
  {     
    val opening_index: Int = chars.indexOf ('(')
    val closing_index: Int = chars.indexOf (')')

    if (opening_index == -1 && closing_index == -1)
    {
      true // but note the else in the 2nd next line
    }
    else if (closing_index > -1 && opening_index > -1)
    {
      if (closing_index <= opening_index)
        false
      else
        balance (chars.drop (closing_index).drop (opening_index))
    }
    else 
      false
  }
}

Upvotes: 4

Related Questions