public Object getNext() {
    // getNext() gets the next item on stack, pointed to by the stackPointer:
    // - if stack is empty, it gets a token from Lexer and returns it, setting SP = 1
    // **(in this case, the newly returned element is put on stack)
    // - if SP is pointing to an existing element of stack, that element is returned, setting
    // SP=SP+1
    //
    // - if SP is pointing right above stack, a new token from Lexer is returned, setting SP=SP+1
    // **(in this case, the newly returned element is put on stack)
    //
    // if SP points to something that is way above stack, it returns an EOFToken().

    if (stack.size() == 0) {
      // System.out.println("I read " + lexer.peekNextToken());
      if (lexer.hasMoreTokens()) {
        stack.add(lexer.getNextToken());
        stackPointer++;
        return stack.get(stackPointer - 1);
      } else return new EOFToken();
    } else if (stackPointer < stack.size()) {
      return stack.get(stackPointer++);
    } else if (stackPointer == stack.size()) // execute this case only if
    // stackpointer points to element right on top of stack, i.e. asks for a new element
    {
      if (lexer.hasMoreTokens()) {
        stack.add(lexer.getNextToken());
        return stack.get(stackPointer++);
      } else return new EOFToken();
    } else { // execute this case if stackpointer is point somewhere absurdly above the top of stack
      if (diag2)
        System.out.println(
            "**Diag warning: invalid stack ref: getNext(), SP="
                + stackPointer
                + " for a stack of size "
                + stack.size());
      return new EOFToken();
    }
  }