Parsing A Boolean Expression

hard stack parsing recursion

Problem

A boolean expression is built from 't' (true), 'f' (false), '!(expr)' (logical NOT), '&(expr1,expr2,...)' (logical AND of one or more sub-expressions) and '|(expr1,expr2,...)' (logical OR of one or more sub-expressions). Evaluate the expression and return its boolean value.

Inputexpression = "|(f,&(t,f))"
Outputfalse
The inner &(t,f) is false, so the outer becomes |(f,false) = false.

def parseBoolExpr(expression):
    stack = []
    for ch in expression:
        if ch == ',':
            continue
        if ch != ')':
            stack.append(ch)          # 't','f','!','&','|','('
            continue
        vals = []                     # collect operands until '('
        while stack[-1] != '(':
            vals.append(stack.pop())
        stack.pop()                   # remove '('
        op = stack.pop()              # the operator
        if op == '!':
            res = 'f' if vals[0] == 't' else 't'
        elif op == '&':
            res = 't' if all(v == 't' for v in vals) else 'f'
        else:                         # op == '|'
            res = 't' if any(v == 't' for v in vals) else 'f'
        stack.append(res)
    return stack[-1] == 't'
function parseBoolExpr(expression) {
  const stack = [];
  for (const ch of expression) {
    if (ch === ',') continue;
    if (ch !== ')') { stack.push(ch); continue; }
    const vals = [];
    while (stack[stack.length - 1] !== '(') vals.push(stack.pop());
    stack.pop();                 // remove '('
    const op = stack.pop();      // the operator
    let res;
    if (op === '!') res = vals[0] === 't' ? 'f' : 't';
    else if (op === '&') res = vals.every(v => v === 't') ? 't' : 'f';
    else res = vals.some(v => v === 't') ? 't' : 'f';
    stack.push(res);
  }
  return stack[stack.length - 1] === 't';
}
class Solution {
    public boolean parseBoolExpr(String expression) {
        Deque<Character> stack = new ArrayDeque<>();
        for (char ch : expression.toCharArray()) {
            if (ch == ',') continue;
            if (ch != ')') { stack.push(ch); continue; }
            List<Character> vals = new ArrayList<>();
            while (stack.peek() != '(') vals.add(stack.pop());
            stack.pop();                 // remove '('
            char op = stack.pop();       // the operator
            char res;
            if (op == '!') res = vals.get(0) == 't' ? 'f' : 't';
            else if (op == '&') {
                res = 't';
                for (char v : vals) if (v == 'f') res = 'f';
            } else {
                res = 'f';
                for (char v : vals) if (v == 't') res = 't';
            }
            stack.push(res);
        }
        return stack.peek() == 't';
    }
}
bool parseBoolExpr(string expression) {
    vector<char> stack;
    for (char ch : expression) {
        if (ch == ',') continue;
        if (ch != ')') { stack.push_back(ch); continue; }
        vector<char> vals;
        while (stack.back() != '(') { vals.push_back(stack.back()); stack.pop_back(); }
        stack.pop_back();                // remove '('
        char op = stack.back(); stack.pop_back();
        char res;
        if (op == '!') res = vals[0] == 't' ? 'f' : 't';
        else if (op == '&') {
            res = 't';
            for (char v : vals) if (v == 'f') res = 'f';
        } else {
            res = 'f';
            for (char v : vals) if (v == 't') res = 't';
        }
        stack.push_back(res);
    }
    return stack.back() == 't';
}
Time: O(n) Space: O(n)