function advance(expected, relatedToken) {
    var nextToken = state.tokens.next;

    if (expected && nextToken.id !== expected) {
      if (relatedToken) {
        if (nextToken.id === "(end)") {
          error("E019", relatedToken, relatedToken.id);
        } else {
          error("E020", nextToken, expected, relatedToken.id,
            relatedToken.line, nextToken.value);
        }
      } else if (nextToken.type !== "(identifier)" || nextToken.value !== expected) {
        error("E021", nextToken, expected, nextToken.value);
      }
    }

    state.tokens.prev = state.tokens.curr;
    state.tokens.curr = state.tokens.next;
    for (;;) {
      state.tokens.next = lookahead.shift() || lex.token();

      if (!state.tokens.next) { // No more tokens left, give up
        quit("E041", state.tokens.curr);
      }

      if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") {
        return;
      }

      if (state.tokens.next.check) {
        state.tokens.next.check();
      }

      if (state.tokens.next.isSpecial) {
        lintingDirective(state.tokens.next, state.tokens.curr);
      } else {
        if (state.tokens.next.id !== "(endline)") {
          break;
        }
      }
    }
  }
Consume the next token.

@param {string} [expected] - the expected value of the next token's `id`
                             property (in the case of punctuators) or
                             `value` property (in the case of identifiers
                             and literals); if unspecified, any token will
                             be accepted
@param {object} [relatedToken] - the token that informed the expected
                                 value, if any (for example: the opening
                                 brace when a closing brace is expected);
                                 used to produce more meaningful errors