function getToken() {
  tokenType = TOKENTYPE.NULL;
  token = "";

  // skip over whitespaces
  while (c === " " || c === "\t" || c === "\n" || c === "\r") {
    // space, tab, enter
    next();
  }

  do {
    var isComment = false;

    // skip comment
    if (c === "#") {
      // find the previous non-space character
      var i = index - 1;
      while (dot.charAt(i) === " " || dot.charAt(i) === "\t") {
        i--;
      }
      if (dot.charAt(i) === "\n" || dot.charAt(i) === "") {
        // the # is at the start of a line, this is indeed a line comment
        while (c != "" && c != "\n") {
          next();
        }
        isComment = true;
      }
    }
    if (c === "/" && nextPreview() === "/") {
      // skip line comment
      while (c != "" && c != "\n") {
        next();
      }
      isComment = true;
    }
    if (c === "/" && nextPreview() === "*") {
      // skip block comment
      while (c != "") {
        if (c === "*" && nextPreview() === "/") {
          // end of block comment found. skip these last two characters
          next();
          next();
          break;
        } else {
          next();
        }
      }
      isComment = true;
    }

    // skip over whitespaces
    while (c === " " || c === "\t" || c === "\n" || c === "\r") {
      // space, tab, enter
      next();
    }
  } while (isComment);

  // check for end of dot file
  if (c === "") {
    // token is still empty
    tokenType = TOKENTYPE.DELIMITER;
    return;
  }

  // check for delimiters consisting of 2 characters
  var c2 = c + nextPreview();
  if (DELIMITERS[c2]) {
    tokenType = TOKENTYPE.DELIMITER;
    token = c2;
    next();
    next();
    return;
  }

  // check for delimiters consisting of 1 character
  if (DELIMITERS[c]) {
    tokenType = TOKENTYPE.DELIMITER;
    token = c;
    next();
    return;
  }

  // check for an identifier (number or string)
  // TODO: more precise parsing of numbers/strings (and the port separator ':')
  if (isAlphaNumeric(c) || c === "-") {
    token += c;
    next();

    while (isAlphaNumeric(c)) {
      token += c;
      next();
    }
    if (token === "false") {
      token = false; // convert to boolean
    } else if (token === "true") {
      token = true; // convert to boolean
    } else if (!isNaN(Number(token))) {
      token = Number(token); // convert to number
    }
    tokenType = TOKENTYPE.IDENTIFIER;
    return;
  }

  // check for a string enclosed by double quotes
  if (c === '"') {
    next();
    while (c != "" && (c != '"' || (c === '"' && nextPreview() === '"'))) {
      if (c === '"') {
        // skip the escape character
        token += c;
        next();
      } else if (c === "\\" && nextPreview() === "n") {
        // Honor a newline escape sequence
        token += "\n";
        next();
      } else {
        token += c;
      }
      next();
    }
    if (c != '"') {
      throw newSyntaxError('End of string " expected');
    }
    next();
    tokenType = TOKENTYPE.IDENTIFIER;
    return;
  }

  // something unknown is found, wrong characters, a syntax error
  tokenType = TOKENTYPE.UNKNOWN;
  while (c != "") {
    token += c;
    next();
  }
  throw new SyntaxError('Syntax error in part "' + chop(token, 30) + '"');
}
Get next token in the current dot file.
The token and token type are available as token and tokenType