What does the number mean in "java.lang.ArrayIndexOutOfBoundsException: -1" in Scala?

Go To StackoverFlow.com

0

I am getting this error, but it isn't very helpful in that it doesn't point me near where the error is happening. What do the numbers after the error mean? I have been looking at the error for the last few hours, but I don't really get where the error is coming from. My code is:

val str = "(and x y)";

def stringParse ( exp: String, expreshHolder: ArrayBuffer[String] ): ArrayBuffer[String] = { //takes three arguments, string, int, arraybuffer

    var b = 0; //position of where in the expression String I am currently in
    var temp = expreshHolder; //holder of expressions without parens
    if(temp == 0) b = 0; else {b = temp(temp.length-1).toInt; temp.remove(temp.length-1)} //this sets the position of wherever the string was read last plus removes that check from the end of the ArrayBuffer
    var arrayCounter = temp.length; //just counts to make sure an empty spot in the array is there to put in the strings

    if(exp(b) == '(') {
        b = b + 1;

        while(exp(b) == ' '){b = b + 1;} //point of this is to just skip any spaces between paren and start of expression type
        if(exp(b) == 'a') {
            //first create the 'and', 'or', 'not' expression types to figure out 
            temp += exp(b).toString; 
            b = b+1; 
            temp(arrayCounter) = temp(arrayCounter) + exp(b).toString; //concatenates the second letter
            b = b+1; 
            temp(arrayCounter) = temp(arrayCounter) + exp(b).toString; //concatenates the last letter for the expression type
            arrayCounter+=1
            //this part now takes the symbols and puts them in an array
            b+=1;
            while(exp(b) == ' ') {b+=1;} //just skips any spaces until it reaches the first symbol
            if(exp(b) == '(') { temp += b.toString; temp = stringParse(exp, temp);
            b = temp(temp.length-1).toInt; 
            temp.remove(temp.length-1); 
            arrayCounter = temp.length 
            } else {
            temp += exp(b).toString; 
            arrayCounter+=1; b+=1; }
            while(exp(b) == ' ') {b+=1;} //just skips any spaces until it reaches the second symbol

            if(exp(b) == '(') { temp += b.toString; temp = stringParse(exp, temp); 
                            b = temp(temp.length-1).toInt; 
                            temp.remove(temp.length-1); 
                            arrayCounter = temp.length } else {temp += exp(b).toString; arrayCounter+=1; b+=1; }    
        }
    temp;
    } else { 
      temp(arrayCounter) +="failed"; temp;} //this is just incase it fails and I should probably check this incase it fails when it doesnt encounter an opening paren
}//end of while loop

hold = stringParse(str, ho );
for(test <- hold) println(test);

Sorry for the amount of code, but from what I can tell it is correct. The point of this code is to read this the first string at the top and just put "and", "x", "y" in an array. Its suppose to do it on more complicated ones, but I am trying it on a simple version first to test and make sure it works. The error I am getting is:

java.lang.ArrayIndexOutOfBoundsException: -1
at scala.collection.mutable.ResizableArray$class.apply(ResizableArray.scala:45)
at scala.collection.mutable.ArrayBuffer.apply(ArrayBuffer.scala:44)
at Driver$.stringParse$1(Driver.scala:19)
at Driver$.main(Driver.scala:60)
at Driver.main(Driver.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:56)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

any help on being able to read this error message and understand where it is happening? Thanks in advance.

2012-04-04 23:45
by Andy
The error means your program tried to go to the negative first index in an array, ie myArray[-1], which is not possible as 0 is the lowest index in an array - Matt Greer 2012-04-04 23:48


6

It means the variable you are decrementing has reached -1

Also note that all you need do is follow the line numbers. For example, the first place to look is line '45'

 scala.collection.mutable.ResizableArray$class.apply(ResizableArray.scala:45)

Tackle the methods you wrote first.

2012-04-04 23:53
by kasavbere
Hmm, I thought the numbers meant nothing because there are also lines that do not exist. But I looked, and it should never reach a negative. At least thats the whole point of the very first check inside the metho - Andy 2012-04-05 00:08
I appreciate the help - Andy 2012-04-05 00:54


6

The error is on the 19th line of Driver.scala:

at Driver$.stringParse$1(Driver.scala:19)

Take a gander:

if(temp == 0) b = 0; else {b = temp(temp.length-1).toInt; temp.remove(temp.length-1)} 

temp is a ArrayBuffer[String], not a number, so temp == 0 will always be false. That means the else clause will always execute, even when temp.length is 0.

2012-04-05 01:09
by rampion
Thanks! I noticed it too. But My code is full of bad code, for scala at least. Gotta fix the errors one by one - Andy 2012-04-05 01:11
Though going off on what you said, I am getting an error with the else part. My next example was going to be "(and x (and y z))". When it runs, it gets an issue with the z, so I assume the y passed. You think maybe you can look why its giving me that error - Andy 2012-04-05 01:27
@Andy: You get java.lang.NumberFormatException: For input string: "z" ... at Driver$.stringParse$1(Temp.scala:47) because on line 47 you try to convert the last thing on your ArrayBuffer[String] stack into an index, but the last thing you pushed onto the stack was "z" (on line 49 - temp += exp(b).toString) - rampion 2012-04-05 18:21
@Andy: You should check out using a debugger to step through your codes execution. That would let you see exactly where your code is going wrong and why. Also, consider using scala's combinator parsing library - check out Chapter 31 of "Programming in Scala" for details - rampion 2012-04-05 18:24
hmm, thanks a lot for the info. I will definitely check into that. And I haven't used debuggers much, but I guess I might as well switch to an IDE to use the debuggers. Any recommendation for which is the better IDE for scala - Andy 2012-04-05 23:05
I don't use an IDE, so I have no idea - rampion 2012-04-05 23:06
Ads