code: function _parseFormula(self, currentString, currentPrecedence, currentJSON) {
    if (!currentString.length && !currentJSON) {
      throw new SyntaxError('Invalid formula! Unexpected end of input.');
    }
  
    // First, we need an initial subformula.
    // A valid formula can't start with a binary operator, but anything else is possible.
    const parsedHead =
      currentJSON ? { json: currentJSON, remainder: currentString } :
        _parseUnarySubformula(self, currentString) ||
        _parseParenthesizedSubformula(self, currentString) ||
        _parseVariable(self, currentString);
  
    if (!parsedHead) {
      throw new SyntaxError('Invalid formula! Could not find an initial subformula.');
    }
  
    // Having found an initial subformula, let's see if it's the left operand to a binary operator...
    const parsedBinary = _parseBinarySubformula(self, parsedHead.remainder, currentPrecedence, parsedHead.json);
    if (!parsedBinary) {
      // ...if it isn't, we're done!
      return parsedHead;
    }
  
    // ...if it is, we parse onward, with our new binary subformula as the next initial subformula.
    return _parseFormula(self, parsedBinary.remainder, currentPrecedence, parsedBinary.json);
  }
docs: Recursively parses a formula according to this parser's parameters.
  Returns an complete AST and a (hopefully empty) string remainder.
  
  @private
  @param {FormulaParser} self
  @param {string}        currentString     - remainder of input string left to parse
  @param {number}        currentPrecedence - lowest binary precedence allowable at current parse stage
  @param {Object}        [currentJSON]     - AST node retained from previous parse stage
  @returns {Object}