0

I have a program that reads in a specific grammar for a CFL and outputs the separate productions for the start symbol, but for some reason passing in command line arguments doesn't work.

I've tried using a String[] in the program, named input and using that seems to provide output, but when I try and run the program with specific commands from the command line, I get errors.

Here's the code:

    char[][] prod; int prodCount = 0, numProds = 0;
    String[] input = new String[] {"a","a","S","b","X",
                                   "a","a","S","a","X",
                                   "a","S","a","X"};

    for(int i = 0; i < input.length; i++) {
        if(input[i] == "X") 
            prodCount++;
    }

    if(input[input.length - 1] == "X") {
        prod = new char[prodCount + 1][1];
        prod[prod.length - 1][0] = '\0';
    } else
        prod = new char[prodCount][];

    int current = 0;
    for(int i = 0; i < input.length; i++) {
        if(input[i] == "X") {
            prod[current] = new char[numProds];
            current++; numProds = 0;
        } else
            numProds++;
    }

    int currentTerminal = 0; current = 0;
    for(int i = 0; i < input.length; i++) {
        if(input[i] == "X") {
            currentTerminal = 0;
            current++;
        }
        else {
            prod[current][currentTerminal] = input[i].charAt(0);
            currentTerminal++;
        }
    }

    for(int i = 0; i < prod.length; i++) {
        for(int j = 0; j < prod[i].length; j++) {
            if(prod[i][j] == '\0')
                System.out.print("E");
            else
                System.out.print(prod[i][j]);
        }
        System.out.println();
    }

Using this code with the String[] input gives me

aaSb
aaSa
aSa
E

However, when I try using input from the command line I get...

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
             Line 36

Here's the line that the above error points to

prod[current][currentTerminal] = args[i].charAt(0);

I'm not sure what's different between String[] input and String[] args. Can someone let me know where I'm making a mistake?

Delfino
  • 967
  • 4
  • 21
  • 46
  • try to check in debug mode. put breackpoint in line no 36. – NFE Nov 24 '14 at 03:36
  • Show the code where you are parsing command line arguments and how you are running the program from the command line. – takendarkk Nov 24 '14 at 03:39
  • `args` is populated with information from the command line. So, if you're just running your program with `java MyClass` instead of `java MyClass arg1 arg2 arg3 arg4`, then `args` will never have any elements in it. – Makoto Nov 24 '14 at 03:47

1 Answers1

1

Your index is out of bounds here: for(int j = 0; j < prod[i].length; j++) {

Because prod is a new, NULL, array, as defined here:

  if(input[input.length - 1] == "X") { //This is the problem line
    prod = new char[prodCount + 1][1];
    prod[prod.length - 1][0] = '\0';
} else
    prod = new char[prodCount][];

You can't compare a String using ==. Since this comparison will always evaluate to FALSE (in this particular snippet), you're declaring prod with this line: prod = new char[prodCount][]; every time. Notice, that nowhere else in your code do you alter this array or assign anything to it. Thus, the out of bounds you receive later when you attempt to access indexes that don't exist.

Change your code to to use String::equals() like this:

  if(input[input.length - 1].equals("X") { //Here's the fix
    prod = new char[prodCount + 1][1];
    prod[prod.length - 1][0] = '\0';
} else
    prod = new char[prodCount][];

Edit:

I should clarify that you need to make this change throughout your code, because you use the == operator several times, not just in the snippet above.

  • 1
    [Well, it doesn't *always* evaluate to `false`...](http://stackoverflow.com/q/19418427/1079354) – Makoto Nov 24 '14 at 03:52
  • @Makoto That's a little beyond my education yet, but thanks for the link. I did mean it as it will always evaluate to false in his case, though. I even thought about it as I wrote it that there are probably cases where you can use `==` with String to get a true. –  Nov 24 '14 at 03:55
  • 2
    Well, in general, you [do want to use `.equals` instead.](http://stackoverflow.com/q/513832/1079354) – Makoto Nov 24 '14 at 03:56
  • That second link described interning so much better, that now I'm confident that I understand it. Thanks again. I'd give you +1 if I could. –  Nov 24 '14 at 03:58
  • I've made the corrections, and my code seems to work with `input`, but not with command line arguments :/ I've tried using the string `aaSbXaaSaXaSaX` when calling `java LoadGrammar` but I keep getting an `ArrayIndexOutOfBounds` error in the last `for` loop block, around the `else` statement – Delfino Nov 25 '14 at 00:56
  • You're running into the same issue of creating an empty array. Your arg is a String, not a String[], so `"aaSbXaaSaXaSaX".equals("X")` is false, and so this code is executed: `prod = new char[prodCount][];` This means that for `prod[i][j]` there exists no index for an `j`, and you'll be out of bounds. You need to create the empty array with a default size in the 2nd dimension **or** you need to check `prod[i].length != 0 ` before accessing `prod[i][j]`. –  Nov 25 '14 at 01:09