code: def _get_next_token(self, string):
          
          STOP_CHARS = "_ {}^ \n ,()="
          UNARY_CHARS = "^_"
          # ^ and _ are valid leaf expressions--just ones that should be handled on their own
          if string[0] in STOP_CHARS:
              return string[0], string[1:]
          
          expression = []
          for i, c in enumerate(string):
              if c in STOP_CHARS:
                  break
              else:
                  expression.append(c)
          
          return "".join(expression), string[i:]
docs: "eats" up the string until it hits an ending character to get valid leaf expressions.
          For example, given \\Phi_{z}(L) = \\sum_{i=1}^{N} \\frac{1}{C_{i} \\times V_{\\rm max, i}},
          this function would pull out \\Phi, stopping at _
          @ string: str
          returns a tuple of (expression [ex: \\Phi], remaining_chars [ex: _{z}(L) = \\sum_{i=1}^{N}...])