function getNextSyntacticCharOffset(char, state) {
  var pendingSource = state.g.source.substring(state.g.position);
  var pendingSourceLines = pendingSource.split('\n');

  var charOffset = 0;
  var line;
  var withinBlockComment = false;
  var withinString = false;
  lineLoop: while ((line = pendingSourceLines.shift()) !== undefined) {
    var lineEndPos = charOffset + line.length;
    charLoop: for (; charOffset < lineEndPos; charOffset++) {
      var currChar = pendingSource[charOffset];
      if (currChar === '"' || currChar === '\'') {
        withinString = !withinString;
        continue charLoop;
      } else if (withinString) {
        continue charLoop;
      } else if (charOffset + 1 < lineEndPos) {
        var nextTwoChars = currChar + line[charOffset + 1];
        if (nextTwoChars === '//') {
          charOffset = lineEndPos + 1;
          continue lineLoop;
        } else if (nextTwoChars === '/*') {
          withinBlockComment = true;
          charOffset += 1;
          continue charLoop;
        } else if (nextTwoChars === '*/') {
          withinBlockComment = false;
          charOffset += 1;
          continue charLoop;
        }
      }

      if (!withinBlockComment && currChar === char) {
        return charOffset + state.g.position;
      }
    }

    // Account for '\n'
    charOffset++;
    withinString = false;
  }

  throw new Error('`' + char + '` not found!');
}
Finds the position of the next instance of the specified syntactic char in
the pending source.

NOTE: This will skip instances of the specified char if they sit inside a
      comment body.

NOTE: This function also assumes that the buffer's current position is not
      already within a comment or a string. This is rarely the case since all
      of the buffer-advancement utility methods tend to be used on syntactic
      nodes' range values -- but it's a small gotcha that's worth mentioning.