I am implementing the shunting yard algorithm and I am having trouble handling parenthesis. It works fine with non grouped expressions though. Here's what I have without Parenthesis detection:
public void makePost(String e)
{
String[] arr = e.split("");
for(int i = 0; i < arr.length; i++)
{
if(arr[i].equals(" "))
{
continue;
}
Operator o = OperatorList.getOpMap().get(arr[i]);
if(o == null){
postfix += " " + arr[i];
continue;
}
if(ops.isEmpty()){
ops.push(o);
continue;
}
else
{
while((!ops.isEmpty() && (ops.peek().getPresedence() <= o.getPresedence()))){
postfix += " " + ops.pop();
}
ops.push(o);
continue;
}
}
while(!ops.isEmpty())
{
postfix += " " + ops.pop();
}
postfix = postfix.trim();
}
ops is the stack that holds Operator objects. There are two types of operators, functions(+,-,* etc) and Parans ("(","["). How would you add parenthesis handling to this? Each time I try, I can't seem to get it to work properly
Here is what I tried:
public void makePost(String e)
{
String[] arr = e.split("");
for(int i = 0; i < arr.length; i++){
if(arr[i].equals(" ")){
continue;
}
Operator o = OperatorList.getOpMap().get(arr[i]);
if(o == null){
postfix += " " + arr[i];
continue;
}
if(ops.isEmpty()){
ops.push(o);
continue;
}
else
{
if(o.isParan())
{
Paran p = new Paran(o.toString());
if(p.isOpen())
{
ops.push(o);
System.out.println(ops);
continue;
}else{
while(!ops.isEmpty()){
if(ops.peek().isParan()){
Paran n = new Paran(o.toString());
if(n.isOpen()){
ops.pop();
break;
}
}
postfix += " " + ops.pop();
}
continue;
}
}
while((!ops.isEmpty() && (ops.peek().getPresedence() <= o.getPresedence()))){
postfix += " " + ops.pop();
}
ops.push(o);
continue;
}
}
while(!ops.isEmpty())
{
postfix += " " + ops.pop();
}
postfix = postfix.trim();
}
I suspect the while loop condition is bad, but I don't know of any proper replacement. It goes on to infinity. This was the cleanest implementation I had. Basically what it is supposed to do is when it encounters an open parenthesis, push it onto the stack. When it hits a closed one, pop everything off the stack onto the output until it hits the open parenthesis. Then it should break, and continue to the next token.
if(o.isParan())
{
Paran p = new Paran(o.toString());
if(p.isOpen())
{
ops.push(o);
System.out.println(ops);
continue;
}else{
while(!ops.isEmpty()){
if(ops.peek().isParan()){
Paran n = new Paran(o.toString());
if(n.isOpen()){
ops.pop();
break;
}
}
postfix += " " + ops.pop();
}
continue;
}
EDIT: added my attempt
Got it to work! I added a few checks for parenthesis in logical areas, Here is the final:
I have the replaceall() call because the output kept return closing parenthesis along with the corrent postfix, ex:
I have no idea why it does that, but I am glad it works