0

My Java Program is below. It's my training exercise. The one implements stack stucture for special type of string parsing(string with delimiter).

This delimiter-matching program works by reading characters from the string one at a time and placing opening delimiters when it finds them, on a stack. When it reads a closing delimiter from the input, it pops the opening delimiter from the top of the stack and attempts to match it with the closing delimiter. If they’re not the same type (there’s an opening brace but a closing parenthesis, for example), an error occurs. Also, if there is no opening delimiter on the stack to match a closing one, or if a delimiter has not been matched, an error occurs. A delimiter that hasn’t been matched is discovered because it remains on the stack after all the characters in the string have been read.

I use Eclipse. My output is here:

Please enter String:
{}
ch0 = {
ch1 = }
chLabel1 = **UNDEFINED CHAR(SQUARE WITH QUESTION MARK INSIDE IT)**
Error at }**

Could you explain value of chLabel?

As I understand operator "|" (here, cause two operands have boolean type) - is "lazy", shortcut version of "||" operator. I've tested the program after substitution "|" for "||"-result is the same.

public class MyStack {
    private int top=0;
    private int maxSize=0;
    private char[] charArray=null;

    public MyStack(int size){
        maxSize=size;
        top=0;
        charArray=new char[maxSize];
    }

    public void push(char ch){
        charArray[top++]=ch;
    }

    public char pop(){
        return charArray[top--];
    }

    public boolean isEmpty(){
        if(top==0)          
        return true;
        else return false;
    }

    public boolean isFull(){
        if(top==(maxSize-1))            
        return true;
        else return false;
    }
}


class StringParse {
    private String stringForParsing = null;

    public StringParse(String string) {
        this.stringForParsing = string;
    }

    public void parser() {
        char[] chArr = stringForParsing.toCharArray();
        MyStack mySt = new MyStack(chArr.length);

        for (int i = 0; i < chArr.length; i++) {
            char ch = chArr[i];

            switch (ch) {
                case '{':
                case '(':
                case '[':
                    mySt.push(ch);
                    System.out.println("ch" + i + " = " + ch);
                    break;

                case '}':
                case ')':
                case ']':
                    if (mySt.isEmpty())
                        System.out.println("Error at" + ch);
                    else {
                        char chLabel = mySt.pop();
                        System.out.println("ch" + i + " = " + ch);
                        System.out.println("chLabel" + i + " = " + chLabel);

                        if ((chLabel == '{') && (ch == '}') | (chLabel == '(') && (ch == ')') | (chLabel == '[') && (ch == ']'))
                            break;

                        else {
                            System.out.println("Error at " + ch);
                            break;
                        } // end of second else
                    } //end of first else

                default:
                    break;
            } //end of switch
        } //end of parser method
    }
} //end of class


class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System. in ));
        System.out.println("Please enter String:");
        String s = br.readLine();

        StringParse strP = new StringParse(s);
        strP.parser();
    }
}
Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
VitalyVV
  • 1
  • 3
  • 2
    I think you should use double || in your condition when pop happens. Otherwise it performs binary OR instead of OR. this is probably the source of your problems – Jan Hruby Aug 22 '13 at 14:13
  • Can you provide the code for MyStack? – Andrew_CS Aug 22 '13 at 14:14
  • When I replaced `MyStack` with `java.util.Stack` (since you didn't give the code for `MyStack`), I don't see any such weird character, just a `{`. Thus there's presumably a bug in `MyStack`. – Bernhard Barker Aug 22 '13 at 14:14
  • `|` has higher precedence than `&&` (as opposed to `||` which has lower precedence) (see [this](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html)), thus `a && b | c && d` is the same as `a && (b | c) && d`, as opposed to `a && b || c && d` which would be `(a && b) || (c && d)`. This is the only difference `|` over `||` will make, along with [short-circuiting](http://stackoverflow.com/a/1724295/1711796), which doesn't make a big difference here. – Bernhard Barker Aug 22 '13 at 14:29
  • | is bitwise inclusive OR while || is logical OR. – Andrew_CS Aug 22 '13 at 14:33
  • @Andrew_CS Yes, but `|` can also be used for boolean values (otherwise the code won't compile). – Bernhard Barker Aug 22 '13 at 14:36
  • OK, I thought you were trying to say there was no difference over the two except for precedence. – Andrew_CS Aug 22 '13 at 14:37

2 Answers2

0

There may be a problem with your MyStack class

Using java.util.Stack gives me no error, just a "chLabel1 = {"

Error at } can be resolved by following Dukeling's advice and using || instead of |:

(chLabel == '{') && (ch == '}') || (chLabel == '(') && (ch == ')') || (chLabel == '[') && (ch == ']')

So, it looks like your code in MyStack.pop() doesn't return a valid char. I'll need to see your MyStack code to help further.

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
0

There are two problems:

  • There's an error with the pop function.

    Consider doing one push and then one pop:

    top = 0
    push
      insert at position 0
      set top to 1
    pop
      get position 1 (not set yet!)
      set top to 0
    

    You need to use pre-decrement instead of post-decrement, so charArray[top--] should be charArray[--top].

    With this change I get chLabel1 = {.

  • Reiterating what I said in the comments...

    | has higher precendence than &&(as opposed to || which has lower precedence) (see this)‌​,
    thus a && b | c && d is the same as a && (b | c) && d,
    as opposed to a && b || c && d which would be (a && b) || (c && d).

    When changing the |'s to ||'s, I no longer get Error at }.

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138