// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library engine.scanner;

import 'dart:collection';

import 'error.dart';
import 'java_engine.dart';
import 'source.dart';

/**
 * The opening half of a grouping pair of tokens. This is used for curly
 * brackets ('{'), parentheses ('('), and square brackets ('[').
 */
class BeginToken extends Token {
  /**
   * The token that corresponds to this token.
   */
  Token endToken;

  /**
   * Initialize a newly created token to have the given [type] at the given
   * [offset].
   */
  BeginToken(TokenType type, int offset) : super(type, offset) {
    assert(type == TokenType.OPEN_CURLY_BRACKET ||
        type == TokenType.OPEN_PAREN ||
        type == TokenType.OPEN_SQUARE_BRACKET ||
        type == TokenType.STRING_INTERPOLATION_EXPRESSION);
  }

  @override
  Token copy() => new BeginToken(type, offset);
}

/**
 * A begin token that is preceded by comments.
 */
class BeginTokenWithComment extends BeginToken {
  /**
   * The first comment in the list of comments that precede this token.
   */
  CommentToken _precedingComment;

  /**
   * Initialize a newly created token to have the given [type] at the given
   * [offset] and to be preceded by the comments reachable from the given
   * [comment].
   */
  BeginTokenWithComment(TokenType type, int offset, this._precedingComment)
      : super(type, offset) {
    _setCommentParent(_precedingComment);
  }

  CommentToken get precedingComments => _precedingComment;

  void set precedingComments(CommentToken comment) {
    _precedingComment = comment;
    _setCommentParent(_precedingComment);
  }

  @override
  void applyDelta(int delta) {
    super.applyDelta(delta);
    Token token = precedingComments;
    while (token != null) {
      token.applyDelta(delta);
      token = token.next;
    }
  }

  @override
  Token copy() =>
      new BeginTokenWithComment(type, offset, copyComments(precedingComments));
}

/**
 * A [CharacterReader] that reads a range of characters from another character
 * reader.
 */
class CharacterRangeReader extends CharacterReader {
  /**
   * The reader from which the characters are actually being read.
   */
  final CharacterReader baseReader;

  /**
   * The last character to be read.
   */
  final int endIndex;

  /**
   * Initialize a newly created reader to read the characters from the given
   * [baseReader] between the [startIndex] inclusive to [endIndex] exclusive.
   */
  CharacterRangeReader(this.baseReader, int startIndex, this.endIndex) {
    baseReader.offset = startIndex - 1;
  }

  @override
  int get offset => baseReader.offset;

  @override
  void set offset(int offset) {
    baseReader.offset = offset;
  }

  @override
  int advance() {
    if (baseReader.offset + 1 >= endIndex) {
      return -1;
    }
    return baseReader.advance();
  }

  @override
  String getString(int start, int endDelta) =>
      baseReader.getString(start, endDelta);

  @override
  int peek() {
    if (baseReader.offset + 1 >= endIndex) {
      return -1;
    }
    return baseReader.peek();
  }
}

/**
 * An object used by the scanner to read the characters to be scanned.
 */
abstract class CharacterReader {
  /**
   * The current offset relative to the beginning of the source. Return the
   * initial offset if the scanner has not yet scanned the source code, and one
   * (1) past the end of the source code if the entire source code has been
   * scanned.
   */
  int get offset;

  /**
   * Set the current offset relative to the beginning of the source to the given
   * [offset]. The new offset must be between the initial offset and one (1)
   * past the end of the source code.
   */
  void set offset(int offset);

  /**
   * Advance the current position and return the character at the new current
   * position.
   */
  int advance();

  /**
   * Return the substring of the source code between the [start] offset and the
   * modified current position. The current position is modified by adding the
   * [endDelta], which is the number of characters after the current location to
   * be included in the string, or the number of characters before the current
   * location to be excluded if the offset is negative.
   */
  String getString(int start, int endDelta);

  /**
   * Return the character at the current position without changing the current
   * position.
   */
  int peek();
}

/**
 * A [CharacterReader] that reads characters from a character sequence.
 */
class CharSequenceReader implements CharacterReader {
  /**
   * The sequence from which characters will be read.
   */
  final String _sequence;

  /**
   * The number of characters in the string.
   */
  int _stringLength = 0;

  /**
   * The index, relative to the string, of the last character that was read.
   */
  int _charOffset = 0;

  /**
   * Initialize a newly created reader to read the characters in the given
   * [_sequence].
   */
  CharSequenceReader(this._sequence) {
    this._stringLength = _sequence.length;
    this._charOffset = -1;
  }

  @override
  int get offset => _charOffset;

  @override
  void set offset(int offset) {
    _charOffset = offset;
  }

  @override
  int advance() {
    if (_charOffset + 1 >= _stringLength) {
      return -1;
    }
    return _sequence.codeUnitAt(++_charOffset);
  }

  @override
  String getString(int start, int endDelta) =>
      _sequence.substring(start, _charOffset + 1 + endDelta).toString();

  @override
  int peek() {
    if (_charOffset + 1 >= _stringLength) {
      return -1;
    }
    return _sequence.codeUnitAt(_charOffset + 1);
  }
}

/**
 * A token representing a comment.
 */
class CommentToken extends StringToken {
  /**
   * The [Token] that contains this comment.
   */
  Token parent;

  /**
   * Initialize a newly created token to represent a token of the given [type]
   * with the given [value] at the given [offset].
   */
  CommentToken(TokenType type, String value, int offset)
      : super(type, value, offset);

  @override
  CommentToken copy() => new CommentToken(type, _value, offset);
}

/**
 * A documentation comment token.
 */
class DocumentationCommentToken extends CommentToken {
  /**
   * The references embedded within the documentation comment.
   * This list will be empty unless this is a documentation comment that has
   * references embedded within it.
   */
  final List<Token> references = <Token>[];

  /**
   * Initialize a newly created token to represent a token of the given [type]
   * with the given [value] at the given [offset].
   */
  DocumentationCommentToken(TokenType type, String value, int offset)
      : super(type, value, offset);

  @override
  CommentToken copy() => new DocumentationCommentToken(type, _value, offset);
}

/**
 * The keywords in the Dart programming language.
 */
class Keyword {
  static const Keyword ASSERT = const Keyword('ASSERT', "assert");

  static const Keyword BREAK = const Keyword('BREAK', "break");

  static const Keyword CASE = const Keyword('CASE', "case");

  static const Keyword CATCH = const Keyword('CATCH', "catch");

  static const Keyword CLASS = const Keyword('CLASS', "class");

  static const Keyword CONST = const Keyword('CONST', "const");

  static const Keyword CONTINUE = const Keyword('CONTINUE', "continue");

  static const Keyword DEFAULT = const Keyword('DEFAULT', "default");

  static const Keyword DO = const Keyword('DO', "do");

  static const Keyword ELSE = const Keyword('ELSE', "else");

  static const Keyword ENUM = const Keyword('ENUM', "enum");

  static const Keyword EXTENDS = const Keyword('EXTENDS', "extends");

  static const Keyword FALSE = const Keyword('FALSE', "false");

  static const Keyword FINAL = const Keyword('FINAL', "final");

  static const Keyword FINALLY = const Keyword('FINALLY', "finally");

  static const Keyword FOR = const Keyword('FOR', "for");

  static const Keyword IF = const Keyword('IF', "if");

  static const Keyword IN = const Keyword('IN', "in");

  static const Keyword IS = const Keyword('IS', "is");

  static const Keyword NEW = const Keyword('NEW', "new");

  static const Keyword NULL = const Keyword('NULL', "null");

  static const Keyword RETHROW = const Keyword('RETHROW', "rethrow");

  static const Keyword RETURN = const Keyword('RETURN', "return");

  static const Keyword SUPER = const Keyword('SUPER', "super");

  static const Keyword SWITCH = const Keyword('SWITCH', "switch");

  static const Keyword THIS = const Keyword('THIS', "this");

  static const Keyword THROW = const Keyword('THROW', "throw");

  static const Keyword TRUE = const Keyword('TRUE', "true");

  static const Keyword TRY = const Keyword('TRY', "try");

  static const Keyword VAR = const Keyword('VAR', "var");

  static const Keyword VOID = const Keyword('VOID', "void");

  static const Keyword WHILE = const Keyword('WHILE', "while");

  static const Keyword WITH = const Keyword('WITH', "with");

  static const Keyword ABSTRACT = const Keyword('ABSTRACT', "abstract", true);

  static const Keyword AS = const Keyword('AS', "as", true);

  static const Keyword DEFERRED = const Keyword('DEFERRED', "deferred", true);

  static const Keyword DYNAMIC = const Keyword('DYNAMIC', "dynamic", true);

  static const Keyword EXPORT = const Keyword('EXPORT', "export", true);

  static const Keyword EXTERNAL = const Keyword('EXTERNAL', "external", true);

  static const Keyword FACTORY = const Keyword('FACTORY', "factory", true);

  static const Keyword GET = const Keyword('GET', "get", true);

  static const Keyword IMPLEMENTS =
      const Keyword('IMPLEMENTS', "implements", true);

  static const Keyword IMPORT = const Keyword('IMPORT', "import", true);

  static const Keyword LIBRARY = const Keyword('LIBRARY', "library", true);

  static const Keyword OPERATOR = const Keyword('OPERATOR', "operator", true);

  static const Keyword PART = const Keyword('PART', "part", true);

  static const Keyword SET = const Keyword('SET', "set", true);

  static const Keyword STATIC = const Keyword('STATIC', "static", true);

  static const Keyword TYPEDEF = const Keyword('TYPEDEF', "typedef", true);

  static const List<Keyword> values = const [
    ASSERT,
    BREAK,
    CASE,
    CATCH,
    CLASS,
    CONST,
    CONTINUE,
    DEFAULT,
    DO,
    ELSE,
    ENUM,
    EXTENDS,
    FALSE,
    FINAL,
    FINALLY,
    FOR,
    IF,
    IN,
    IS,
    NEW,
    NULL,
    RETHROW,
    RETURN,
    SUPER,
    SWITCH,
    THIS,
    THROW,
    TRUE,
    TRY,
    VAR,
    VOID,
    WHILE,
    WITH,
    ABSTRACT,
    AS,
    DEFERRED,
    DYNAMIC,
    EXPORT,
    EXTERNAL,
    FACTORY,
    GET,
    IMPLEMENTS,
    IMPORT,
    LIBRARY,
    OPERATOR,
    PART,
    SET,
    STATIC,
    TYPEDEF
  ];

  /**
   * A table mapping the lexemes of keywords to the corresponding keyword.
   */
  static final Map<String, Keyword> keywords = _createKeywordMap();

  /**
   * The name of the keyword type.
   */
  final String name;

  /**
   * The lexeme for the keyword.
   */
  final String syntax;

  /**
   * A flag indicating whether the keyword is a pseudo-keyword. Pseudo keywords
   * can be used as identifiers.
   */
  final bool isPseudoKeyword;

  /**
   * Initialize a newly created keyword to have the given [name] and [syntax].
   * The keyword is a pseudo-keyword if the [isPseudoKeyword] flag is `true`.
   */
  const Keyword(this.name, this.syntax, [this.isPseudoKeyword = false]);

  @override
  String toString() => name;

  /**
   * Create a table mapping the lexemes of keywords to the corresponding keyword
   * and return the table that was created.
   */
  static Map<String, Keyword> _createKeywordMap() {
    LinkedHashMap<String, Keyword> result =
        new LinkedHashMap<String, Keyword>();
    for (Keyword keyword in values) {
      result[keyword.syntax] = keyword;
    }
    return result;
  }
}

/**
 * A state in a state machine used to scan keywords.
 */
class KeywordState {
  /**
   * An empty transition table used by leaf states.
   */
  static List<KeywordState> _EMPTY_TABLE = new List<KeywordState>(26);

  /**
   * The initial state in the state machine.
   */
  static final KeywordState KEYWORD_STATE = _createKeywordStateTable();

  /**
   * A table mapping characters to the states to which those characters will
   * transition. (The index into the array is the offset from the character
   * `'a'` to the transitioning character.)
   */
  final List<KeywordState> _table;

  /**
   * The keyword that is recognized by this state, or `null` if this state is
   * not a terminal state.
   */
  Keyword _keyword;

  /**
   * Initialize a newly created state to have the given transitions and to
   * recognize the keyword with the given [syntax].
   */
  KeywordState(this._table, String syntax) {
    this._keyword = (syntax == null) ? null : Keyword.keywords[syntax];
  }

  /**
   * Return the keyword that was recognized by this state, or `null` if this
   * state does not recognized a keyword.
   */
  Keyword keyword() => _keyword;

  /**
   * Return the state that follows this state on a transition of the given
   * [character], or `null` if there is no valid state reachable from this state
   * with such a transition.
   */
  KeywordState next(int character) => _table[character - 0x61];

  /**
   * Create the next state in the state machine where we have already recognized
   * the subset of strings in the given array of [strings] starting at the given
   * [offset] and having the given [length]. All of these strings have a common
   * prefix and the next character is at the given [start] index.
   */
  static KeywordState _computeKeywordStateTable(
      int start, List<String> strings, int offset, int length) {
    List<KeywordState> result = new List<KeywordState>(26);
    assert(length != 0);
    int chunk = 0x0;
    int chunkStart = -1;
    bool isLeaf = false;
    for (int i = offset; i < offset + length; i++) {
      if (strings[i].length == start) {
        isLeaf = true;
      }
      if (strings[i].length > start) {
        int c = strings[i].codeUnitAt(start);
        if (chunk != c) {
          if (chunkStart != -1) {
            result[chunk - 0x61] = _computeKeywordStateTable(
                start + 1, strings, chunkStart, i - chunkStart);
          }
          chunkStart = i;
          chunk = c;
        }
      }
    }
    if (chunkStart != -1) {
      assert(result[chunk - 0x61] == null);
      result[chunk - 0x61] = _computeKeywordStateTable(
          start + 1, strings, chunkStart, offset + length - chunkStart);
    } else {
      assert(length == 1);
      return new KeywordState(_EMPTY_TABLE, strings[offset]);
    }
    if (isLeaf) {
      return new KeywordState(result, strings[offset]);
    } else {
      return new KeywordState(result, null);
    }
  }

  /**
   * Create and return the initial state in the state machine.
   */
  static KeywordState _createKeywordStateTable() {
    List<Keyword> values = Keyword.values;
    List<String> strings = new List<String>(values.length);
    for (int i = 0; i < values.length; i++) {
      strings[i] = values[i].syntax;
    }
    strings.sort();
    return _computeKeywordStateTable(0, strings, 0, strings.length);
  }
}

/**
 * A token representing a keyword in the language.
 */
class KeywordToken extends Token {
  /**
   * The keyword being represented by this token.
   */
  final Keyword keyword;

  /**
   * Initialize a newly created token to represent the given [keyword] at the
   * given [offset].
   */
  KeywordToken(this.keyword, int offset) : super(TokenType.KEYWORD, offset);

  @override
  String get lexeme => keyword.syntax;

  @override
  Token copy() => new KeywordToken(keyword, offset);

  @override
  Keyword value() => keyword;
}

/**
 * A keyword token that is preceded by comments.
 */
class KeywordTokenWithComment extends KeywordToken {
  /**
   * The first comment in the list of comments that precede this token.
   */
  CommentToken _precedingComment;

  /**
   * Initialize a newly created token to to represent the given [keyword] at the
   * given [offset] and to be preceded by the comments reachable from the given
   * [comment].
   */
  KeywordTokenWithComment(Keyword keyword, int offset, this._precedingComment)
      : super(keyword, offset) {
    _setCommentParent(_precedingComment);
  }

  CommentToken get precedingComments => _precedingComment;

  void set precedingComments(CommentToken comment) {
    _precedingComment = comment;
    _setCommentParent(_precedingComment);
  }

  @override
  void applyDelta(int delta) {
    super.applyDelta(delta);
    Token token = precedingComments;
    while (token != null) {
      token.applyDelta(delta);
      token = token.next;
    }
  }

  @override
  Token copy() => new KeywordTokenWithComment(
      keyword, offset, copyComments(precedingComments));
}

/**
 * The class `Scanner` implements a scanner for Dart code.
 *
 * The lexical structure of Dart is ambiguous without knowledge of the context
 * in which a token is being scanned. For example, without context we cannot
 * determine whether source of the form "<<" should be scanned as a single
 * left-shift operator or as two left angle brackets. This scanner does not have
 * any context, so it always resolves such conflicts by scanning the longest
 * possible token.
 */
class Scanner {
  /**
   * The source being scanned.
   */
  final Source source;

  /**
   * The reader used to access the characters in the source.
   */
  final CharacterReader _reader;

  /**
   * The error listener that will be informed of any errors that are found
   * during the scan.
   */
  final AnalysisErrorListener _errorListener;

  /**
   * The flag specifying whether documentation comments should be parsed.
   */
  bool _preserveComments = true;

  /**
   * The token pointing to the head of the linked list of tokens.
   */
  Token _tokens;

  /**
   * The last token that was scanned.
   */
  Token _tail;

  /**
   * The first token in the list of comment tokens found since the last
   * non-comment token.
   */
  Token _firstComment;

  /**
   * The last token in the list of comment tokens found since the last
   * non-comment token.
   */
  Token _lastComment;

  /**
   * The index of the first character of the current token.
   */
  int _tokenStart = 0;

  /**
   * A list containing the offsets of the first character of each line in the
   * source code.
   */
  List<int> _lineStarts = new List<int>();

  /**
   * A list, treated something like a stack, of tokens representing the
   * beginning of a matched pair. It is used to pair the end tokens with the
   * begin tokens.
   */
  List<BeginToken> _groupingStack = new List<BeginToken>();

  /**
   * The index of the last item in the [_groupingStack], or `-1` if the stack is
   * empty.
   */
  int _stackEnd = -1;

  /**
   * A flag indicating whether any unmatched groups were found during the parse.
   */
  bool _hasUnmatchedGroups = false;

  /**
   * A flag indicating whether null-aware operators ('?.', '??', and '??=')
   * should be tokenized.
   */
  bool enableNullAwareOperators = false;

  /**
   * Initialize a newly created scanner to scan characters from the given
   * [source]. The given character [_reader] will be used to read the characters
   * in the source. The given [_errorListener] will be informed of any errors
   * that are found.
   */
  Scanner(this.source, this._reader, this._errorListener) {
    _tokens = new Token(TokenType.EOF, -1);
    _tokens.setNext(_tokens);
    _tail = _tokens;
    _tokenStart = -1;
    _lineStarts.add(0);
  }

  /**
   * Return the first token in the token stream that was scanned.
   */
  Token get firstToken => _tokens.next;

  /**
   * Return `true` if any unmatched groups were found during the parse.
   */
  bool get hasUnmatchedGroups => _hasUnmatchedGroups;

  /**
   * Return an array containing the offsets of the first character of each line
   * in the source code.
   */
  List<int> get lineStarts => _lineStarts;

  /**
   * Set whether documentation tokens should be preserved.
   */
  void set preserveComments(bool preserveComments) {
    this._preserveComments = preserveComments;
  }

  /**
   * Return the last token that was scanned.
   */
  Token get tail => _tail;

  /**
   * Append the given [token] to the end of the token stream being scanned. This
   * method is intended to be used by subclasses that copy existing tokens and
   * should not normally be used because it will fail to correctly associate any
   * comments with the token being passed in.
   */
  void appendToken(Token token) {
    _tail = _tail.setNext(token);
  }

  int bigSwitch(int next) {
    _beginToken();
    if (next == 0xD) {
      // '\r'
      next = _reader.advance();
      if (next == 0xA) {
        // '\n'
        next = _reader.advance();
      }
      recordStartOfLine();
      return next;
    } else if (next == 0xA) {
      // '\n'
      next = _reader.advance();
      recordStartOfLine();
      return next;
    } else if (next == 0x9 || next == 0x20) {
      // '\t' || ' '
      return _reader.advance();
    }
    if (next == 0x72) {
      // 'r'
      int peek = _reader.peek();
      if (peek == 0x22 || peek == 0x27) {
        // '"' || "'"
        int start = _reader.offset;
        return _tokenizeString(_reader.advance(), start, true);
      }
    }
    if (0x61 <= next && next <= 0x7A) {
      // 'a'-'z'
      return _tokenizeKeywordOrIdentifier(next, true);
    }
    if ((0x41 <= next && next <= 0x5A) || next == 0x5F || next == 0x24) {
      // 'A'-'Z' || '_' || '$'
      return _tokenizeIdentifier(next, _reader.offset, true);
    }
    if (next == 0x3C) {
      // '<'
      return _tokenizeLessThan(next);
    }
    if (next == 0x3E) {
      // '>'
      return _tokenizeGreaterThan(next);
    }
    if (next == 0x3D) {
      // '='
      return _tokenizeEquals(next);
    }
    if (next == 0x21) {
      // '!'
      return _tokenizeExclamation(next);
    }
    if (next == 0x2B) {
      // '+'
      return _tokenizePlus(next);
    }
    if (next == 0x2D) {
      // '-'
      return _tokenizeMinus(next);
    }
    if (next == 0x2A) {
      // '*'
      return _tokenizeMultiply(next);
    }
    if (next == 0x25) {
      // '%'
      return _tokenizePercent(next);
    }
    if (next == 0x26) {
      // '&'
      return _tokenizeAmpersand(next);
    }
    if (next == 0x7C) {
      // '|'
      return _tokenizeBar(next);
    }
    if (next == 0x5E) {
      // '^'
      return _tokenizeCaret(next);
    }
    if (next == 0x5B) {
      // '['
      return _tokenizeOpenSquareBracket(next);
    }
    if (next == 0x7E) {
      // '~'
      return _tokenizeTilde(next);
    }
    if (next == 0x5C) {
      // '\\'
      _appendTokenOfType(TokenType.BACKSLASH);
      return _reader.advance();
    }
    if (next == 0x23) {
      // '#'
      return _tokenizeTag(next);
    }
    if (next == 0x28) {
      // '('
      _appendBeginToken(TokenType.OPEN_PAREN);
      return _reader.advance();
    }
    if (next == 0x29) {
      // ')'
      _appendEndToken(TokenType.CLOSE_PAREN, TokenType.OPEN_PAREN);
      return _reader.advance();
    }
    if (next == 0x2C) {
      // ','
      _appendTokenOfType(TokenType.COMMA);
      return _reader.advance();
    }
    if (next == 0x3A) {
      // ':'
      _appendTokenOfType(TokenType.COLON);
      return _reader.advance();
    }
    if (next == 0x3B) {
      // ';'
      _appendTokenOfType(TokenType.SEMICOLON);
      return _reader.advance();
    }
    if (next == 0x3F) {
      // '?'
      return _tokenizeQuestion();
    }
    if (next == 0x5D) {
      // ']'
      _appendEndToken(
          TokenType.CLOSE_SQUARE_BRACKET, TokenType.OPEN_SQUARE_BRACKET);
      return _reader.advance();
    }
    if (next == 0x60) {
      // '`'
      _appendTokenOfType(TokenType.BACKPING);
      return _reader.advance();
    }
    if (next == 0x7B) {
      // '{'
      _appendBeginToken(TokenType.OPEN_CURLY_BRACKET);
      return _reader.advance();
    }
    if (next == 0x7D) {
      // '}'
      _appendEndToken(
          TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
      return _reader.advance();
    }
    if (next == 0x2F) {
      // '/'
      return _tokenizeSlashOrComment(next);
    }
    if (next == 0x40) {
      // '@'
      _appendTokenOfType(TokenType.AT);
      return _reader.advance();
    }
    if (next == 0x22 || next == 0x27) {
      // '"' || "'"
      return _tokenizeString(next, _reader.offset, false);
    }
    if (next == 0x2E) {
      // '.'
      return _tokenizeDotOrNumber(next);
    }
    if (next == 0x30) {
      // '0'
      return _tokenizeHexOrNumber(next);
    }
    if (0x31 <= next && next <= 0x39) {
      // '1'-'9'
      return _tokenizeNumber(next);
    }
    if (next == -1) {
      // EOF
      return -1;
    }
    _reportError(ScannerErrorCode.ILLEGAL_CHARACTER, [next]);
    return _reader.advance();
  }

  /**
   * Record the fact that we are at the beginning of a new line in the source.
   */
  void recordStartOfLine() {
    _lineStarts.add(_reader.offset);
  }

  /**
   * Record that the source begins on the given [line] and [column] at the
   * current offset as given by the reader. Both the line and the column are
   * one-based indexes. The line starts for lines before the given line will not
   * be correct.
   *
   * This method must be invoked at most one time and must be invoked before
   * scanning begins. The values provided must be sensible. The results are
   * undefined if these conditions are violated.
   */
  void setSourceStart(int line, int column) {
    int offset = _reader.offset;
    if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) {
      return;
    }
    for (int i = 2; i < line; i++) {
      _lineStarts.add(1);
    }
    _lineStarts.add(offset - column + 1);
  }

  /**
   * Scan the source code to produce a list of tokens representing the source,
   * and return the first token in the list of tokens that were produced.
   */
  Token tokenize() {
    int next = _reader.advance();
    while (next != -1) {
      next = bigSwitch(next);
    }
    _appendEofToken();
    return firstToken;
  }

  void _appendBeginToken(TokenType type) {
    BeginToken token;
    if (_firstComment == null) {
      token = new BeginToken(type, _tokenStart);
    } else {
      token = new BeginTokenWithComment(type, _tokenStart, _firstComment);
      _firstComment = null;
      _lastComment = null;
    }
    _tail = _tail.setNext(token);
    _groupingStack.add(token);
    _stackEnd++;
  }

  void _appendCommentToken(TokenType type, String value) {
    // Ignore comment tokens if client specified that it doesn't need them.
    if (!_preserveComments) {
      return;
    }
    // OK, remember comment tokens.
    CommentToken token;
    if (_isDocumentationComment(value)) {
      token = new DocumentationCommentToken(type, value, _tokenStart);
    } else {
      token = new CommentToken(type, value, _tokenStart);
    }
    if (_firstComment == null) {
      _firstComment = token;
      _lastComment = _firstComment;
    } else {
      _lastComment = _lastComment.setNext(token);
    }
  }

  void _appendEndToken(TokenType type, TokenType beginType) {
    Token token;
    if (_firstComment == null) {
      token = new Token(type, _tokenStart);
    } else {
      token = new TokenWithComment(type, _tokenStart, _firstComment);
      _firstComment = null;
      _lastComment = null;
    }
    _tail = _tail.setNext(token);
    if (_stackEnd >= 0) {
      BeginToken begin = _groupingStack[_stackEnd];
      if (begin.type == beginType) {
        begin.endToken = token;
        _groupingStack.removeAt(_stackEnd--);
      }
    }
  }

  void _appendEofToken() {
    Token eofToken;
    if (_firstComment == null) {
      eofToken = new Token(TokenType.EOF, _reader.offset + 1);
    } else {
      eofToken = new TokenWithComment(
          TokenType.EOF, _reader.offset + 1, _firstComment);
      _firstComment = null;
      _lastComment = null;
    }
    // The EOF token points to itself so that there is always infinite
    // look-ahead.
    eofToken.setNext(eofToken);
    _tail = _tail.setNext(eofToken);
    if (_stackEnd >= 0) {
      _hasUnmatchedGroups = true;
      // TODO(brianwilkerson) Fix the ungrouped tokens?
    }
  }

  void _appendKeywordToken(Keyword keyword) {
    if (_firstComment == null) {
      _tail = _tail.setNext(new KeywordToken(keyword, _tokenStart));
    } else {
      _tail = _tail.setNext(
          new KeywordTokenWithComment(keyword, _tokenStart, _firstComment));
      _firstComment = null;
      _lastComment = null;
    }
  }

  void _appendStringToken(TokenType type, String value) {
    if (_firstComment == null) {
      _tail = _tail.setNext(new StringToken(type, value, _tokenStart));
    } else {
      _tail = _tail.setNext(
          new StringTokenWithComment(type, value, _tokenStart, _firstComment));
      _firstComment = null;
      _lastComment = null;
    }
  }

  void _appendStringTokenWithOffset(TokenType type, String value, int offset) {
    if (_firstComment == null) {
      _tail = _tail.setNext(new StringToken(type, value, _tokenStart + offset));
    } else {
      _tail = _tail.setNext(new StringTokenWithComment(
          type, value, _tokenStart + offset, _firstComment));
      _firstComment = null;
      _lastComment = null;
    }
  }

  void _appendTokenOfType(TokenType type) {
    if (_firstComment == null) {
      _tail = _tail.setNext(new Token(type, _tokenStart));
    } else {
      _tail =
          _tail.setNext(new TokenWithComment(type, _tokenStart, _firstComment));
      _firstComment = null;
      _lastComment = null;
    }
  }

  void _appendTokenOfTypeWithOffset(TokenType type, int offset) {
    if (_firstComment == null) {
      _tail = _tail.setNext(new Token(type, offset));
    } else {
      _tail = _tail.setNext(new TokenWithComment(type, offset, _firstComment));
      _firstComment = null;
      _lastComment = null;
    }
  }

  void _beginToken() {
    _tokenStart = _reader.offset;
  }

  /**
   * Return the beginning token corresponding to a closing brace that was found
   * while scanning inside a string interpolation expression. Tokens that cannot
   * be matched with the closing brace will be dropped from the stack.
   */
  BeginToken _findTokenMatchingClosingBraceInInterpolationExpression() {
    while (_stackEnd >= 0) {
      BeginToken begin = _groupingStack[_stackEnd];
      if (begin.type == TokenType.OPEN_CURLY_BRACKET ||
          begin.type == TokenType.STRING_INTERPOLATION_EXPRESSION) {
        return begin;
      }
      _hasUnmatchedGroups = true;
      _groupingStack.removeAt(_stackEnd--);
    }
    //
    // We should never get to this point because we wouldn't be inside a string
    // interpolation expression unless we had previously found the start of the
    // expression.
    //
    return null;
  }

  /**
   * Report an error at the current offset. The [errorCode] is the error code
   * indicating the nature of the error. The [arguments] are any arguments
   * needed to complete the error message
   */
  void _reportError(ScannerErrorCode errorCode, [List<Object> arguments]) {
    _errorListener.onError(
        new AnalysisError(source, _reader.offset, 1, errorCode, arguments));
  }

  int _select(int choice, TokenType yesType, TokenType noType) {
    int next = _reader.advance();
    if (next == choice) {
      _appendTokenOfType(yesType);
      return _reader.advance();
    } else {
      _appendTokenOfType(noType);
      return next;
    }
  }

  int _selectWithOffset(
      int choice, TokenType yesType, TokenType noType, int offset) {
    int next = _reader.advance();
    if (next == choice) {
      _appendTokenOfTypeWithOffset(yesType, offset);
      return _reader.advance();
    } else {
      _appendTokenOfTypeWithOffset(noType, offset);
      return next;
    }
  }

  int _tokenizeAmpersand(int next) {
    // && &= &
    next = _reader.advance();
    if (next == 0x26) {
      _appendTokenOfType(TokenType.AMPERSAND_AMPERSAND);
      return _reader.advance();
    } else if (next == 0x3D) {
      _appendTokenOfType(TokenType.AMPERSAND_EQ);
      return _reader.advance();
    } else {
      _appendTokenOfType(TokenType.AMPERSAND);
      return next;
    }
  }

  int _tokenizeBar(int next) {
    // | || |=
    next = _reader.advance();
    if (next == 0x7C) {
      _appendTokenOfType(TokenType.BAR_BAR);
      return _reader.advance();
    } else if (next == 0x3D) {
      _appendTokenOfType(TokenType.BAR_EQ);
      return _reader.advance();
    } else {
      _appendTokenOfType(TokenType.BAR);
      return next;
    }
  }

  int _tokenizeCaret(int next) =>
      _select(0x3D, TokenType.CARET_EQ, TokenType.CARET);

  int _tokenizeDotOrNumber(int next) {
    int start = _reader.offset;
    next = _reader.advance();
    if (0x30 <= next && next <= 0x39) {
      return _tokenizeFractionPart(next, start);
    } else if (0x2E == next) {
      return _select(
          0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD);
    } else {
      _appendTokenOfType(TokenType.PERIOD);
      return next;
    }
  }

  int _tokenizeEquals(int next) {
    // = == =>
    next = _reader.advance();
    if (next == 0x3D) {
      _appendTokenOfType(TokenType.EQ_EQ);
      return _reader.advance();
    } else if (next == 0x3E) {
      _appendTokenOfType(TokenType.FUNCTION);
      return _reader.advance();
    }
    _appendTokenOfType(TokenType.EQ);
    return next;
  }

  int _tokenizeExclamation(int next) {
    // ! !=
    next = _reader.advance();
    if (next == 0x3D) {
      _appendTokenOfType(TokenType.BANG_EQ);
      return _reader.advance();
    }
    _appendTokenOfType(TokenType.BANG);
    return next;
  }

  int _tokenizeExponent(int next) {
    if (next == 0x2B || next == 0x2D) {
      next = _reader.advance();
    }
    bool hasDigits = false;
    while (true) {
      if (0x30 <= next && next <= 0x39) {
        hasDigits = true;
      } else {
        if (!hasDigits) {
          _reportError(ScannerErrorCode.MISSING_DIGIT);
        }
        return next;
      }
      next = _reader.advance();
    }
  }

  int _tokenizeFractionPart(int next, int start) {
    bool done = false;
    bool hasDigit = false;
    LOOP: while (!done) {
      if (0x30 <= next && next <= 0x39) {
        hasDigit = true;
      } else if (0x65 == next || 0x45 == next) {
        hasDigit = true;
        next = _tokenizeExponent(_reader.advance());
        done = true;
        continue LOOP;
      } else {
        done = true;
        continue LOOP;
      }
      next = _reader.advance();
    }
    if (!hasDigit) {
      _appendStringToken(TokenType.INT, _reader.getString(start, -2));
      if (0x2E == next) {
        return _selectWithOffset(0x2E, TokenType.PERIOD_PERIOD_PERIOD,
            TokenType.PERIOD_PERIOD, _reader.offset - 1);
      }
      _appendTokenOfTypeWithOffset(TokenType.PERIOD, _reader.offset - 1);
      return bigSwitch(next);
    }
    _appendStringToken(
        TokenType.DOUBLE, _reader.getString(start, next < 0 ? 0 : -1));
    return next;
  }

  int _tokenizeGreaterThan(int next) {
    // > >= >> >>=
    next = _reader.advance();
    if (0x3D == next) {
      _appendTokenOfType(TokenType.GT_EQ);
      return _reader.advance();
    } else if (0x3E == next) {
      next = _reader.advance();
      if (0x3D == next) {
        _appendTokenOfType(TokenType.GT_GT_EQ);
        return _reader.advance();
      } else {
        _appendTokenOfType(TokenType.GT_GT);
        return next;
      }
    } else {
      _appendTokenOfType(TokenType.GT);
      return next;
    }
  }

  int _tokenizeHex(int next) {
    int start = _reader.offset - 1;
    bool hasDigits = false;
    while (true) {
      next = _reader.advance();
      if ((0x30 <= next && next <= 0x39) ||
          (0x41 <= next && next <= 0x46) ||
          (0x61 <= next && next <= 0x66)) {
        hasDigits = true;
      } else {
        if (!hasDigits) {
          _reportError(ScannerErrorCode.MISSING_HEX_DIGIT);
        }
        _appendStringToken(
            TokenType.HEXADECIMAL, _reader.getString(start, next < 0 ? 0 : -1));
        return next;
      }
    }
  }

  int _tokenizeHexOrNumber(int next) {
    int x = _reader.peek();
    if (x == 0x78 || x == 0x58) {
      _reader.advance();
      return _tokenizeHex(x);
    }
    return _tokenizeNumber(next);
  }

  int _tokenizeIdentifier(int next, int start, bool allowDollar) {
    while ((0x61 <= next && next <= 0x7A) ||
        (0x41 <= next && next <= 0x5A) ||
        (0x30 <= next && next <= 0x39) ||
        next == 0x5F ||
        (next == 0x24 && allowDollar)) {
      next = _reader.advance();
    }
    _appendStringToken(
        TokenType.IDENTIFIER, _reader.getString(start, next < 0 ? 0 : -1));
    return next;
  }

  int _tokenizeInterpolatedExpression(int next, int start) {
    _appendBeginToken(TokenType.STRING_INTERPOLATION_EXPRESSION);
    next = _reader.advance();
    while (next != -1) {
      if (next == 0x7D) {
        BeginToken begin =
            _findTokenMatchingClosingBraceInInterpolationExpression();
        if (begin == null) {
          _beginToken();
          _appendTokenOfType(TokenType.CLOSE_CURLY_BRACKET);
          next = _reader.advance();
          _beginToken();
          return next;
        } else if (begin.type == TokenType.OPEN_CURLY_BRACKET) {
          _beginToken();
          _appendEndToken(
              TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
          next = _reader.advance();
          _beginToken();
        } else if (begin.type == TokenType.STRING_INTERPOLATION_EXPRESSION) {
          _beginToken();
          _appendEndToken(TokenType.CLOSE_CURLY_BRACKET,
              TokenType.STRING_INTERPOLATION_EXPRESSION);
          next = _reader.advance();
          _beginToken();
          return next;
        }
      } else {
        next = bigSwitch(next);
      }
    }
    return next;
  }

  int _tokenizeInterpolatedIdentifier(int next, int start) {
    _appendStringTokenWithOffset(
        TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 0);
    if ((0x41 <= next && next <= 0x5A) ||
        (0x61 <= next && next <= 0x7A) ||
        next == 0x5F) {
      _beginToken();
      next = _tokenizeKeywordOrIdentifier(next, false);
    }
    _beginToken();
    return next;
  }

  int _tokenizeKeywordOrIdentifier(int next, bool allowDollar) {
    KeywordState state = KeywordState.KEYWORD_STATE;
    int start = _reader.offset;
    while (state != null && 0x61 <= next && next <= 0x7A) {
      state = state.next(next);
      next = _reader.advance();
    }
    if (state == null || state.keyword() == null) {
      return _tokenizeIdentifier(next, start, allowDollar);
    }
    if ((0x41 <= next && next <= 0x5A) ||
        (0x30 <= next && next <= 0x39) ||
        next == 0x5F ||
        next == 0x24) {
      return _tokenizeIdentifier(next, start, allowDollar);
    } else if (next < 128) {
      _appendKeywordToken(state.keyword());
      return next;
    } else {
      return _tokenizeIdentifier(next, start, allowDollar);
    }
  }

  int _tokenizeLessThan(int next) {
    // < <= << <<=
    next = _reader.advance();
    if (0x3D == next) {
      _appendTokenOfType(TokenType.LT_EQ);
      return _reader.advance();
    } else if (0x3C == next) {
      return _select(0x3D, TokenType.LT_LT_EQ, TokenType.LT_LT);
    } else {
      _appendTokenOfType(TokenType.LT);
      return next;
    }
  }

  int _tokenizeMinus(int next) {
    // - -- -=
    next = _reader.advance();
    if (next == 0x2D) {
      _appendTokenOfType(TokenType.MINUS_MINUS);
      return _reader.advance();
    } else if (next == 0x3D) {
      _appendTokenOfType(TokenType.MINUS_EQ);
      return _reader.advance();
    } else {
      _appendTokenOfType(TokenType.MINUS);
      return next;
    }
  }

  int _tokenizeMultiLineComment(int next) {
    int nesting = 1;
    next = _reader.advance();
    while (true) {
      if (-1 == next) {
        _reportError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT);
        _appendCommentToken(
            TokenType.MULTI_LINE_COMMENT, _reader.getString(_tokenStart, 0));
        return next;
      } else if (0x2A == next) {
        next = _reader.advance();
        if (0x2F == next) {
          --nesting;
          if (0 == nesting) {
            _appendCommentToken(TokenType.MULTI_LINE_COMMENT,
                _reader.getString(_tokenStart, 0));
            return _reader.advance();
          } else {
            next = _reader.advance();
          }
        }
      } else if (0x2F == next) {
        next = _reader.advance();
        if (0x2A == next) {
          next = _reader.advance();
          ++nesting;
        }
      } else if (next == 0xD) {
        next = _reader.advance();
        if (next == 0xA) {
          next = _reader.advance();
        }
        recordStartOfLine();
      } else if (next == 0xA) {
        recordStartOfLine();
        next = _reader.advance();
      } else {
        next = _reader.advance();
      }
    }
  }

  int _tokenizeMultiLineRawString(int quoteChar, int start) {
    int next = _reader.advance();
    outer: while (next != -1) {
      while (next != quoteChar) {
        if (next == -1) {
          break outer;
        } else if (next == 0xD) {
          next = _reader.advance();
          if (next == 0xA) {
            next = _reader.advance();
          }
          recordStartOfLine();
        } else if (next == 0xA) {
          next = _reader.advance();
          recordStartOfLine();
        } else {
          next = _reader.advance();
        }
      }
      next = _reader.advance();
      if (next == quoteChar) {
        next = _reader.advance();
        if (next == quoteChar) {
          _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
          return _reader.advance();
        }
      }
    }
    _reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
    _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
    return _reader.advance();
  }

  int _tokenizeMultiLineString(int quoteChar, int start, bool raw) {
    if (raw) {
      return _tokenizeMultiLineRawString(quoteChar, start);
    }
    int next = _reader.advance();
    while (next != -1) {
      if (next == 0x24) {
        _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
        next = _tokenizeStringInterpolation(start);
        _beginToken();
        start = _reader.offset;
        continue;
      }
      if (next == quoteChar) {
        next = _reader.advance();
        if (next == quoteChar) {
          next = _reader.advance();
          if (next == quoteChar) {
            _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
            return _reader.advance();
          }
        }
        continue;
      }
      if (next == 0x5C) {
        next = _reader.advance();
        if (next == -1) {
          break;
        }
        if (next == 0xD) {
          next = _reader.advance();
          if (next == 0xA) {
            next = _reader.advance();
          }
          recordStartOfLine();
        } else if (next == 0xA) {
          recordStartOfLine();
          next = _reader.advance();
        } else {
          next = _reader.advance();
        }
      } else if (next == 0xD) {
        next = _reader.advance();
        if (next == 0xA) {
          next = _reader.advance();
        }
        recordStartOfLine();
      } else if (next == 0xA) {
        recordStartOfLine();
        next = _reader.advance();
      } else {
        next = _reader.advance();
      }
    }
    _reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
    if (start == _reader.offset) {
      _appendStringTokenWithOffset(TokenType.STRING, "", 1);
    } else {
      _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
    }
    return _reader.advance();
  }

  int _tokenizeMultiply(int next) =>
      _select(0x3D, TokenType.STAR_EQ, TokenType.STAR);

  int _tokenizeNumber(int next) {
    int start = _reader.offset;
    while (true) {
      next = _reader.advance();
      if (0x30 <= next && next <= 0x39) {
        continue;
      } else if (next == 0x2E) {
        return _tokenizeFractionPart(_reader.advance(), start);
      } else if (next == 0x65 || next == 0x45) {
        return _tokenizeFractionPart(next, start);
      } else {
        _appendStringToken(
            TokenType.INT, _reader.getString(start, next < 0 ? 0 : -1));
        return next;
      }
    }
  }

  int _tokenizeOpenSquareBracket(int next) {
    // [ []  []=
    next = _reader.advance();
    if (next == 0x5D) {
      return _select(0x3D, TokenType.INDEX_EQ, TokenType.INDEX);
    } else {
      _appendBeginToken(TokenType.OPEN_SQUARE_BRACKET);
      return next;
    }
  }

  int _tokenizePercent(int next) =>
      _select(0x3D, TokenType.PERCENT_EQ, TokenType.PERCENT);

  int _tokenizePlus(int next) {
    // + ++ +=
    next = _reader.advance();
    if (0x2B == next) {
      _appendTokenOfType(TokenType.PLUS_PLUS);
      return _reader.advance();
    } else if (0x3D == next) {
      _appendTokenOfType(TokenType.PLUS_EQ);
      return _reader.advance();
    } else {
      _appendTokenOfType(TokenType.PLUS);
      return next;
    }
  }

  int _tokenizeQuestion() {
    // ? ?. ?? ??=
    int next = _reader.advance();
    if (enableNullAwareOperators && next == 0x2E) {
      // '.'
      _appendTokenOfType(TokenType.QUESTION_PERIOD);
      return _reader.advance();
    } else if (enableNullAwareOperators && next == 0x3F) {
      // '?'
      next = _reader.advance();
      if (next == 0x3D) {
        // '='
        _appendTokenOfType(TokenType.QUESTION_QUESTION_EQ);
        return _reader.advance();
      } else {
        _appendTokenOfType(TokenType.QUESTION_QUESTION);
        return next;
      }
    } else {
      _appendTokenOfType(TokenType.QUESTION);
      return next;
    }
  }

  int _tokenizeSingleLineComment(int next) {
    while (true) {
      next = _reader.advance();
      if (-1 == next) {
        _appendCommentToken(
            TokenType.SINGLE_LINE_COMMENT, _reader.getString(_tokenStart, 0));
        return next;
      } else if (0xA == next || 0xD == next) {
        _appendCommentToken(
            TokenType.SINGLE_LINE_COMMENT, _reader.getString(_tokenStart, -1));
        return next;
      }
    }
  }

  int _tokenizeSingleLineRawString(int next, int quoteChar, int start) {
    next = _reader.advance();
    while (next != -1) {
      if (next == quoteChar) {
        _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
        return _reader.advance();
      } else if (next == 0xD || next == 0xA) {
        _reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
        _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
        return _reader.advance();
      }
      next = _reader.advance();
    }
    _reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
    _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
    return _reader.advance();
  }

  int _tokenizeSingleLineString(int next, int quoteChar, int start) {
    while (next != quoteChar) {
      if (next == 0x5C) {
        next = _reader.advance();
      } else if (next == 0x24) {
        _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
        next = _tokenizeStringInterpolation(start);
        _beginToken();
        start = _reader.offset;
        continue;
      }
      if (next <= 0xD && (next == 0xA || next == 0xD || next == -1)) {
        _reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
        if (start == _reader.offset) {
          _appendStringTokenWithOffset(TokenType.STRING, "", 1);
        } else if (next == -1) {
          _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
        } else {
          _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
        }
        return _reader.advance();
      }
      next = _reader.advance();
    }
    _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
    return _reader.advance();
  }

  int _tokenizeSlashOrComment(int next) {
    next = _reader.advance();
    if (0x2A == next) {
      return _tokenizeMultiLineComment(next);
    } else if (0x2F == next) {
      return _tokenizeSingleLineComment(next);
    } else if (0x3D == next) {
      _appendTokenOfType(TokenType.SLASH_EQ);
      return _reader.advance();
    } else {
      _appendTokenOfType(TokenType.SLASH);
      return next;
    }
  }

  int _tokenizeString(int next, int start, bool raw) {
    int quoteChar = next;
    next = _reader.advance();
    if (quoteChar == next) {
      next = _reader.advance();
      if (quoteChar == next) {
        // Multiline string.
        return _tokenizeMultiLineString(quoteChar, start, raw);
      } else {
        // Empty string.
        _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
        return next;
      }
    }
    if (raw) {
      return _tokenizeSingleLineRawString(next, quoteChar, start);
    } else {
      return _tokenizeSingleLineString(next, quoteChar, start);
    }
  }

  int _tokenizeStringInterpolation(int start) {
    _beginToken();
    int next = _reader.advance();
    if (next == 0x7B) {
      return _tokenizeInterpolatedExpression(next, start);
    } else {
      return _tokenizeInterpolatedIdentifier(next, start);
    }
  }

  int _tokenizeTag(int next) {
    // # or #!.*[\n\r]
    if (_reader.offset == 0) {
      if (_reader.peek() == 0x21) {
        do {
          next = _reader.advance();
        } while (next != 0xA && next != 0xD && next > 0);
        _appendStringToken(
            TokenType.SCRIPT_TAG, _reader.getString(_tokenStart, 0));
        return next;
      }
    }
    _appendTokenOfType(TokenType.HASH);
    return _reader.advance();
  }

  int _tokenizeTilde(int next) {
    // ~ ~/ ~/=
    next = _reader.advance();
    if (next == 0x2F) {
      return _select(0x3D, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
    } else {
      _appendTokenOfType(TokenType.TILDE);
      return next;
    }
  }

  /**
   * Checks if [value] is a single-line or multi-line comment.
   */
  static bool _isDocumentationComment(String value) {
    return StringUtilities.startsWith3(value, 0, 0x2F, 0x2F, 0x2F) ||
        StringUtilities.startsWith3(value, 0, 0x2F, 0x2A, 0x2A);
  }
}

/**
 * The error codes used for errors detected by the scanner.
 */
class ScannerErrorCode extends ErrorCode {
  static const ScannerErrorCode ILLEGAL_CHARACTER =
      const ScannerErrorCode('ILLEGAL_CHARACTER', "Illegal character {0}");

  static const ScannerErrorCode MISSING_DIGIT =
      const ScannerErrorCode('MISSING_DIGIT', "Decimal digit expected");

  static const ScannerErrorCode MISSING_HEX_DIGIT =
      const ScannerErrorCode('MISSING_HEX_DIGIT', "Hexidecimal digit expected");

  static const ScannerErrorCode MISSING_QUOTE =
      const ScannerErrorCode('MISSING_QUOTE', "Expected quote (' or \")");

  static const ScannerErrorCode UNABLE_GET_CONTENT = const ScannerErrorCode(
      'UNABLE_GET_CONTENT', "Unable to get content: {0}");

  static const ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT =
      const ScannerErrorCode(
          'UNTERMINATED_MULTI_LINE_COMMENT', "Unterminated multi-line comment");

  static const ScannerErrorCode UNTERMINATED_STRING_LITERAL =
      const ScannerErrorCode(
          'UNTERMINATED_STRING_LITERAL', "Unterminated string literal");

  /**
   * Initialize a newly created error code to have the given [name]. The message
   * associated with the error will be created from the given [message]
   * template. The correction associated with the error will be created from the
   * given [correction] template.
   */
  const ScannerErrorCode(String name, String message, [String correction])
      : super(name, message, correction);

  @override
  ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;

  @override
  ErrorType get type => ErrorType.SYNTACTIC_ERROR;
}

/**
 * A token whose value is independent of it's type.
 */
class StringToken extends Token {
  /**
   * The lexeme represented by this token.
   */
  String _value;

  /**
   * Initialize a newly created token to represent a token of the given [type]
   * with the given [value] at the given [offset].
   */
  StringToken(TokenType type, String value, int offset) : super(type, offset) {
    this._value = StringUtilities.intern(value);
  }

  @override
  String get lexeme => _value;

  @override
  Token copy() => new StringToken(type, _value, offset);

  @override
  String value() => _value;
}

/**
 * A string token that is preceded by comments.
 */
class StringTokenWithComment extends StringToken {
  /**
   * The first comment in the list of comments that precede this token.
   */
  CommentToken _precedingComment;

  /**
   * Initialize a newly created token to have the given [type] at the given
   * [offset] and to be preceded by the comments reachable from the given
   * [comment].
   */
  StringTokenWithComment(
      TokenType type, String value, int offset, this._precedingComment)
      : super(type, value, offset) {
    _setCommentParent(_precedingComment);
  }

  CommentToken get precedingComments => _precedingComment;

  void set precedingComments(CommentToken comment) {
    _precedingComment = comment;
    _setCommentParent(_precedingComment);
  }

  @override
  void applyDelta(int delta) {
    super.applyDelta(delta);
    Token token = precedingComments;
    while (token != null) {
      token.applyDelta(delta);
      token = token.next;
    }
  }

  @override
  Token copy() => new StringTokenWithComment(
      type, lexeme, offset, copyComments(precedingComments));
}

/**
 * A [CharacterReader] that reads characters from a character sequence, but adds
 * a delta when reporting the current character offset so that the character
 * sequence can be a subsequence from a larger sequence.
 */
class SubSequenceReader extends CharSequenceReader {
  /**
   * The offset from the beginning of the file to the beginning of the source
   * being scanned.
   */
  final int _offsetDelta;

  /**
   * Initialize a newly created reader to read the characters in the given
   * [sequence]. The [_offsetDelta] is the offset from the beginning of the file
   * to the beginning of the source being scanned
   */
  SubSequenceReader(String sequence, this._offsetDelta) : super(sequence);

  @override
  int get offset => _offsetDelta + super.offset;

  @override
  void set offset(int offset) {
    super.offset = offset - _offsetDelta;
  }

  @override
  String getString(int start, int endDelta) =>
      super.getString(start - _offsetDelta, endDelta);
}

/**
 * A token whose value is independent of it's type.
 */
class SyntheticStringToken extends StringToken {
  /**
   * Initialize a newly created token to represent a token of the given [type]
   * with the given [value] at the given [offset].
   */
  SyntheticStringToken(TokenType type, String value, int offset)
      : super(type, value, offset);

  @override
  bool get isSynthetic => true;
}

/**
 * A token that was scanned from the input. Each token knows which tokens
 * precede and follow it, acting as a link in a doubly linked list of tokens.
 */
class Token {
  /**
   * The type of the token.
   */
  final TokenType type;

  /**
   * The offset from the beginning of the file to the first character in the
   * token.
   */
  int offset = 0;

  /**
   * The previous token in the token stream.
   */
  Token previous;

  /**
   * The next token in the token stream.
   */
  Token _next;

  /**
   * Initialize a newly created token to have the given [type] and [offset].
   */
  Token(this.type, int offset) {
    this.offset = offset;
  }

  /**
   * Return the offset from the beginning of the file to the character after the
   * last character of the token.
   */
  int get end => offset + length;

  /**
   * Return `true` if this token represents an operator.
   */
  bool get isOperator => type.isOperator;

  /**
   * Return `true` if this token is a synthetic token. A synthetic token is a
   * token that was introduced by the parser in order to recover from an error
   * in the code.
   */
  bool get isSynthetic => length == 0;

  /**
   * Return `true` if this token represents an operator that can be defined by
   * users.
   */
  bool get isUserDefinableOperator => type.isUserDefinableOperator;

  /**
   * Return the number of characters in the node's source range.
   */
  int get length => lexeme.length;

  /**
   * Return the lexeme that represents this token.
   */
  String get lexeme => type.lexeme;

  /**
   * Return the next token in the token stream.
   */
  Token get next => _next;

  /**
   * Return the first comment in the list of comments that precede this token,
   * or `null` if there are no comments preceding this token. Additional
   * comments can be reached by following the token stream using [next] until
   * `null` is returned.
   *
   * For example, if the original contents were "/* one */ /* two */ id", then
   * the first preceding comment token will have a lexeme of "/* one */" and
   * the next comment token will have a lexeme of "/* two */".
   */
  CommentToken get precedingComments => null;

  /**
   * Apply (add) the given [delta] to this token's offset.
   */
  void applyDelta(int delta) {
    offset += delta;
  }

  /**
   * Return a newly created token that is a copy of this token but that is not a
   * part of any token stream.
   */
  Token copy() => new Token(type, offset);

  /**
   * Copy a linked list of comment tokens identical to the given comment tokens.
   */
  Token copyComments(Token token) {
    if (token == null) {
      return null;
    }
    Token head = token.copy();
    Token tail = head;
    token = token.next;
    while (token != null) {
      tail = tail.setNext(token.copy());
      token = token.next;
    }
    return head;
  }

  /**
   * Return `true` if this token has any one of the given [types].
   */
  bool matchesAny(List<TokenType> types) {
    for (TokenType type in types) {
      if (this.type == type) {
        return true;
      }
    }
    return false;
  }

  /**
   * Set the next token in the token stream to the given [token]. This has the
   * side-effect of setting this token to be the previous token for the given
   * token. Return the token that was passed in.
   */
  Token setNext(Token token) {
    _next = token;
    token.previous = this;
    return token;
  }

  /**
   * Set the next token in the token stream to the given token without changing
   * which token is the previous token for the given token. Return the token
   * that was passed in.
   */
  Token setNextWithoutSettingPrevious(Token token) {
    _next = token;
    return token;
  }

  @override
  String toString() => lexeme;

  /**
   * Return the value of this token. For keyword tokens, this is the keyword
   * associated with the token, for other tokens it is the lexeme associated
   * with the token.
   */
  Object value() => type.lexeme;

  /**
   * Sets the `parent` property to `this` for the given [comment] and all the
   * next tokens.
   */
  void _setCommentParent(CommentToken comment) {
    while (comment != null) {
      comment.parent = this;
      comment = comment.next;
    }
  }

  /**
   * Compare the given [tokens] to find the token that appears first in the
   * source being parsed. That is, return the left-most of all of the tokens.
   * The list must be non-`null`, but the elements of the list are allowed to be
   * `null`. Return the token with the smallest offset, or `null` if the list is
   * empty or if all of the elements of the list are `null`.
   */
  static Token lexicallyFirst(List<Token> tokens) {
    Token first = null;
    int offset = -1;
    for (Token token in tokens) {
      if (token != null && (offset < 0 || token.offset < offset)) {
        first = token;
        offset = token.offset;
      }
    }
    return first;
  }
}

/**
 * The classes (or groups) of tokens with a similar use.
 */
class TokenClass {
  /**
   * A value used to indicate that the token type is not part of any specific
   * class of token.
   */
  static const TokenClass NO_CLASS = const TokenClass('NO_CLASS');

  /**
   * A value used to indicate that the token type is an additive operator.
   */
  static const TokenClass ADDITIVE_OPERATOR =
      const TokenClass('ADDITIVE_OPERATOR', 13);

  /**
   * A value used to indicate that the token type is an assignment operator.
   */
  static const TokenClass ASSIGNMENT_OPERATOR =
      const TokenClass('ASSIGNMENT_OPERATOR', 1);

  /**
   * A value used to indicate that the token type is a bitwise-and operator.
   */
  static const TokenClass BITWISE_AND_OPERATOR =
      const TokenClass('BITWISE_AND_OPERATOR', 11);

  /**
   * A value used to indicate that the token type is a bitwise-or operator.
   */
  static const TokenClass BITWISE_OR_OPERATOR =
      const TokenClass('BITWISE_OR_OPERATOR', 9);

  /**
   * A value used to indicate that the token type is a bitwise-xor operator.
   */
  static const TokenClass BITWISE_XOR_OPERATOR =
      const TokenClass('BITWISE_XOR_OPERATOR', 10);

  /**
   * A value used to indicate that the token type is a cascade operator.
   */
  static const TokenClass CASCADE_OPERATOR =
      const TokenClass('CASCADE_OPERATOR', 2);

  /**
   * A value used to indicate that the token type is a conditional operator.
   */
  static const TokenClass CONDITIONAL_OPERATOR =
      const TokenClass('CONDITIONAL_OPERATOR', 3);

  /**
   * A value used to indicate that the token type is an equality operator.
   */
  static const TokenClass EQUALITY_OPERATOR =
      const TokenClass('EQUALITY_OPERATOR', 7);

  /**
   * A value used to indicate that the token type is an if-null operator.
   */
  static const TokenClass IF_NULL_OPERATOR =
      const TokenClass('IF_NULL_OPERATOR', 4);

  /**
   * A value used to indicate that the token type is a logical-and operator.
   */
  static const TokenClass LOGICAL_AND_OPERATOR =
      const TokenClass('LOGICAL_AND_OPERATOR', 6);

  /**
   * A value used to indicate that the token type is a logical-or operator.
   */
  static const TokenClass LOGICAL_OR_OPERATOR =
      const TokenClass('LOGICAL_OR_OPERATOR', 5);

  /**
   * A value used to indicate that the token type is a multiplicative operator.
   */
  static const TokenClass MULTIPLICATIVE_OPERATOR =
      const TokenClass('MULTIPLICATIVE_OPERATOR', 14);

  /**
   * A value used to indicate that the token type is a relational operator.
   */
  static const TokenClass RELATIONAL_OPERATOR =
      const TokenClass('RELATIONAL_OPERATOR', 8);

  /**
   * A value used to indicate that the token type is a shift operator.
   */
  static const TokenClass SHIFT_OPERATOR =
      const TokenClass('SHIFT_OPERATOR', 12);

  /**
   * A value used to indicate that the token type is a unary operator.
   */
  static const TokenClass UNARY_POSTFIX_OPERATOR =
      const TokenClass('UNARY_POSTFIX_OPERATOR', 16);

  /**
   * A value used to indicate that the token type is a unary operator.
   */
  static const TokenClass UNARY_PREFIX_OPERATOR =
      const TokenClass('UNARY_PREFIX_OPERATOR', 15);

  /**
   * The name of the token class.
   */
  final String name;

  /**
   * The precedence of tokens of this class, or `0` if the such tokens do not
   * represent an operator.
   */
  final int precedence;

  const TokenClass(this.name, [this.precedence = 0]);

  @override
  String toString() => name;
}

/**
 * The types of tokens that can be returned by the scanner.
 */
class TokenType {
  /**
   * The type of the token that marks the end of the input.
   */
  static const TokenType EOF = const TokenType_EOF('EOF');

  static const TokenType DOUBLE = const TokenType('DOUBLE');

  static const TokenType HEXADECIMAL = const TokenType('HEXADECIMAL');

  static const TokenType IDENTIFIER = const TokenType('IDENTIFIER');

  static const TokenType INT = const TokenType('INT');

  static const TokenType KEYWORD = const TokenType('KEYWORD');

  static const TokenType MULTI_LINE_COMMENT =
      const TokenType('MULTI_LINE_COMMENT');

  static const TokenType SCRIPT_TAG = const TokenType('SCRIPT_TAG');

  static const TokenType SINGLE_LINE_COMMENT =
      const TokenType('SINGLE_LINE_COMMENT');

  static const TokenType STRING = const TokenType('STRING');

  static const TokenType AMPERSAND =
      const TokenType('AMPERSAND', TokenClass.BITWISE_AND_OPERATOR, "&");

  static const TokenType AMPERSAND_AMPERSAND = const TokenType(
      'AMPERSAND_AMPERSAND', TokenClass.LOGICAL_AND_OPERATOR, "&&");

  static const TokenType AMPERSAND_EQ =
      const TokenType('AMPERSAND_EQ', TokenClass.ASSIGNMENT_OPERATOR, "&=");

  static const TokenType AT = const TokenType('AT', TokenClass.NO_CLASS, "@");

  static const TokenType BANG =
      const TokenType('BANG', TokenClass.UNARY_PREFIX_OPERATOR, "!");

  static const TokenType BANG_EQ =
      const TokenType('BANG_EQ', TokenClass.EQUALITY_OPERATOR, "!=");

  static const TokenType BAR =
      const TokenType('BAR', TokenClass.BITWISE_OR_OPERATOR, "|");

  static const TokenType BAR_BAR =
      const TokenType('BAR_BAR', TokenClass.LOGICAL_OR_OPERATOR, "||");

  static const TokenType BAR_EQ =
      const TokenType('BAR_EQ', TokenClass.ASSIGNMENT_OPERATOR, "|=");

  static const TokenType COLON =
      const TokenType('COLON', TokenClass.NO_CLASS, ":");

  static const TokenType COMMA =
      const TokenType('COMMA', TokenClass.NO_CLASS, ",");

  static const TokenType CARET =
      const TokenType('CARET', TokenClass.BITWISE_XOR_OPERATOR, "^");

  static const TokenType CARET_EQ =
      const TokenType('CARET_EQ', TokenClass.ASSIGNMENT_OPERATOR, "^=");

  static const TokenType CLOSE_CURLY_BRACKET =
      const TokenType('CLOSE_CURLY_BRACKET', TokenClass.NO_CLASS, "}");

  static const TokenType CLOSE_PAREN =
      const TokenType('CLOSE_PAREN', TokenClass.NO_CLASS, ")");

  static const TokenType CLOSE_SQUARE_BRACKET =
      const TokenType('CLOSE_SQUARE_BRACKET', TokenClass.NO_CLASS, "]");

  static const TokenType EQ =
      const TokenType('EQ', TokenClass.ASSIGNMENT_OPERATOR, "=");

  static const TokenType EQ_EQ =
      const TokenType('EQ_EQ', TokenClass.EQUALITY_OPERATOR, "==");

  static const TokenType FUNCTION =
      const TokenType('FUNCTION', TokenClass.NO_CLASS, "=>");

  static const TokenType GT =
      const TokenType('GT', TokenClass.RELATIONAL_OPERATOR, ">");

  static const TokenType GT_EQ =
      const TokenType('GT_EQ', TokenClass.RELATIONAL_OPERATOR, ">=");

  static const TokenType GT_GT =
      const TokenType('GT_GT', TokenClass.SHIFT_OPERATOR, ">>");

  static const TokenType GT_GT_EQ =
      const TokenType('GT_GT_EQ', TokenClass.ASSIGNMENT_OPERATOR, ">>=");

  static const TokenType HASH =
      const TokenType('HASH', TokenClass.NO_CLASS, "#");

  static const TokenType INDEX =
      const TokenType('INDEX', TokenClass.UNARY_POSTFIX_OPERATOR, "[]");

  static const TokenType INDEX_EQ =
      const TokenType('INDEX_EQ', TokenClass.UNARY_POSTFIX_OPERATOR, "[]=");

  static const TokenType IS =
      const TokenType('IS', TokenClass.RELATIONAL_OPERATOR, "is");

  static const TokenType LT =
      const TokenType('LT', TokenClass.RELATIONAL_OPERATOR, "<");

  static const TokenType LT_EQ =
      const TokenType('LT_EQ', TokenClass.RELATIONAL_OPERATOR, "<=");

  static const TokenType LT_LT =
      const TokenType('LT_LT', TokenClass.SHIFT_OPERATOR, "<<");

  static const TokenType LT_LT_EQ =
      const TokenType('LT_LT_EQ', TokenClass.ASSIGNMENT_OPERATOR, "<<=");

  static const TokenType MINUS =
      const TokenType('MINUS', TokenClass.ADDITIVE_OPERATOR, "-");

  static const TokenType MINUS_EQ =
      const TokenType('MINUS_EQ', TokenClass.ASSIGNMENT_OPERATOR, "-=");

  static const TokenType MINUS_MINUS =
      const TokenType('MINUS_MINUS', TokenClass.UNARY_PREFIX_OPERATOR, "--");

  static const TokenType OPEN_CURLY_BRACKET =
      const TokenType('OPEN_CURLY_BRACKET', TokenClass.NO_CLASS, "{");

  static const TokenType OPEN_PAREN =
      const TokenType('OPEN_PAREN', TokenClass.UNARY_POSTFIX_OPERATOR, "(");

  static const TokenType OPEN_SQUARE_BRACKET = const TokenType(
      'OPEN_SQUARE_BRACKET', TokenClass.UNARY_POSTFIX_OPERATOR, "[");

  static const TokenType PERCENT =
      const TokenType('PERCENT', TokenClass.MULTIPLICATIVE_OPERATOR, "%");

  static const TokenType PERCENT_EQ =
      const TokenType('PERCENT_EQ', TokenClass.ASSIGNMENT_OPERATOR, "%=");

  static const TokenType PERIOD =
      const TokenType('PERIOD', TokenClass.UNARY_POSTFIX_OPERATOR, ".");

  static const TokenType PERIOD_PERIOD =
      const TokenType('PERIOD_PERIOD', TokenClass.CASCADE_OPERATOR, "..");

  static const TokenType PLUS =
      const TokenType('PLUS', TokenClass.ADDITIVE_OPERATOR, "+");

  static const TokenType PLUS_EQ =
      const TokenType('PLUS_EQ', TokenClass.ASSIGNMENT_OPERATOR, "+=");

  static const TokenType PLUS_PLUS =
      const TokenType('PLUS_PLUS', TokenClass.UNARY_PREFIX_OPERATOR, "++");

  static const TokenType QUESTION =
      const TokenType('QUESTION', TokenClass.CONDITIONAL_OPERATOR, "?");

  static const TokenType QUESTION_PERIOD = const TokenType(
      'QUESTION_PERIOD', TokenClass.UNARY_POSTFIX_OPERATOR, '?.');

  static const TokenType QUESTION_QUESTION =
      const TokenType('QUESTION_QUESTION', TokenClass.IF_NULL_OPERATOR, '??');

  static const TokenType QUESTION_QUESTION_EQ = const TokenType(
      'QUESTION_QUESTION_EQ', TokenClass.ASSIGNMENT_OPERATOR, '??=');

  static const TokenType SEMICOLON =
      const TokenType('SEMICOLON', TokenClass.NO_CLASS, ";");

  static const TokenType SLASH =
      const TokenType('SLASH', TokenClass.MULTIPLICATIVE_OPERATOR, "/");

  static const TokenType SLASH_EQ =
      const TokenType('SLASH_EQ', TokenClass.ASSIGNMENT_OPERATOR, "/=");

  static const TokenType STAR =
      const TokenType('STAR', TokenClass.MULTIPLICATIVE_OPERATOR, "*");

  static const TokenType STAR_EQ =
      const TokenType('STAR_EQ', TokenClass.ASSIGNMENT_OPERATOR, "*=");

  static const TokenType STRING_INTERPOLATION_EXPRESSION = const TokenType(
      'STRING_INTERPOLATION_EXPRESSION', TokenClass.NO_CLASS, "\${");

  static const TokenType STRING_INTERPOLATION_IDENTIFIER = const TokenType(
      'STRING_INTERPOLATION_IDENTIFIER', TokenClass.NO_CLASS, "\$");

  static const TokenType TILDE =
      const TokenType('TILDE', TokenClass.UNARY_PREFIX_OPERATOR, "~");

  static const TokenType TILDE_SLASH =
      const TokenType('TILDE_SLASH', TokenClass.MULTIPLICATIVE_OPERATOR, "~/");

  static const TokenType TILDE_SLASH_EQ =
      const TokenType('TILDE_SLASH_EQ', TokenClass.ASSIGNMENT_OPERATOR, "~/=");

  static const TokenType BACKPING =
      const TokenType('BACKPING', TokenClass.NO_CLASS, "`");

  static const TokenType BACKSLASH =
      const TokenType('BACKSLASH', TokenClass.NO_CLASS, "\\");

  static const TokenType PERIOD_PERIOD_PERIOD =
      const TokenType('PERIOD_PERIOD_PERIOD', TokenClass.NO_CLASS, "...");

  /**
   * The class of the token.
   */
  final TokenClass _tokenClass;

  /**
   * The name of the token type.
   */
  final String name;

  /**
   * The lexeme that defines this type of token, or `null` if there is more than
   * one possible lexeme for this type of token.
   */
  final String lexeme;

  const TokenType(this.name,
      [this._tokenClass = TokenClass.NO_CLASS, this.lexeme = null]);

  /**
   * Return `true` if this type of token represents an additive operator.
   */
  bool get isAdditiveOperator => _tokenClass == TokenClass.ADDITIVE_OPERATOR;

  /**
   * Return `true` if this type of token represents an assignment operator.
   */
  bool get isAssignmentOperator =>
      _tokenClass == TokenClass.ASSIGNMENT_OPERATOR;

  /**
   * Return `true` if this type of token represents an associative operator. An
   * associative operator is an operator for which the following equality is
   * true: `(a * b) * c == a * (b * c)`. In other words, if the result of
   * applying the operator to multiple operands does not depend on the order in
   * which those applications occur.
   *
   * Note: This method considers the logical-and and logical-or operators to be
   * associative, even though the order in which the application of those
   * operators can have an effect because evaluation of the right-hand operand
   * is conditional.
   */
  bool get isAssociativeOperator => this == AMPERSAND ||
      this == AMPERSAND_AMPERSAND ||
      this == BAR ||
      this == BAR_BAR ||
      this == CARET ||
      this == PLUS ||
      this == STAR;

  /**
   * Return `true` if this type of token represents an equality operator.
   */
  bool get isEqualityOperator => _tokenClass == TokenClass.EQUALITY_OPERATOR;

  /**
   * Return `true` if this type of token represents an increment operator.
   */
  bool get isIncrementOperator =>
      identical(lexeme, "++") || identical(lexeme, "--");

  /**
   * Return `true` if this type of token represents a multiplicative operator.
   */
  bool get isMultiplicativeOperator =>
      _tokenClass == TokenClass.MULTIPLICATIVE_OPERATOR;

  /**
   * Return `true` if this token type represents an operator.
   */
  bool get isOperator => _tokenClass != TokenClass.NO_CLASS &&
      this != OPEN_PAREN &&
      this != OPEN_SQUARE_BRACKET &&
      this != PERIOD;

  /**
   * Return `true` if this type of token represents a relational operator.
   */
  bool get isRelationalOperator =>
      _tokenClass == TokenClass.RELATIONAL_OPERATOR;

  /**
   * Return `true` if this type of token represents a shift operator.
   */
  bool get isShiftOperator => _tokenClass == TokenClass.SHIFT_OPERATOR;

  /**
   * Return `true` if this type of token represents a unary postfix operator.
   */
  bool get isUnaryPostfixOperator =>
      _tokenClass == TokenClass.UNARY_POSTFIX_OPERATOR;

  /**
   * Return `true` if this type of token represents a unary prefix operator.
   */
  bool get isUnaryPrefixOperator =>
      _tokenClass == TokenClass.UNARY_PREFIX_OPERATOR;

  /**
   * Return `true` if this token type represents an operator that can be defined
   * by users.
   */
  bool get isUserDefinableOperator => identical(lexeme, "==") ||
      identical(lexeme, "~") ||
      identical(lexeme, "[]") ||
      identical(lexeme, "[]=") ||
      identical(lexeme, "*") ||
      identical(lexeme, "/") ||
      identical(lexeme, "%") ||
      identical(lexeme, "~/") ||
      identical(lexeme, "+") ||
      identical(lexeme, "-") ||
      identical(lexeme, "<<") ||
      identical(lexeme, ">>") ||
      identical(lexeme, ">=") ||
      identical(lexeme, ">") ||
      identical(lexeme, "<=") ||
      identical(lexeme, "<") ||
      identical(lexeme, "&") ||
      identical(lexeme, "^") ||
      identical(lexeme, "|");

  /**
   * Return the precedence of the token, or `0` if the token does not represent
   * an operator.
   */
  int get precedence => _tokenClass.precedence;

  @override
  String toString() => name;
}

class TokenType_EOF extends TokenType {
  const TokenType_EOF(String name) : super(name, TokenClass.NO_CLASS, "");

  @override
  String toString() => "-eof-";
}

/**
 * A normal token that is preceded by comments.
 */
class TokenWithComment extends Token {
  /**
   * The first comment in the list of comments that precede this token.
   */
  CommentToken _precedingComment;

  /**
   * Initialize a newly created token to have the given [type] at the given
   * [offset] and to be preceded by the comments reachable from the given
   * [comment].
   */
  TokenWithComment(TokenType type, int offset, this._precedingComment)
      : super(type, offset) {
    _setCommentParent(_precedingComment);
  }

  CommentToken get precedingComments => _precedingComment;

  void set precedingComments(CommentToken comment) {
    _precedingComment = comment;
    _setCommentParent(_precedingComment);
  }

  @override
  Token copy() => new TokenWithComment(type, offset, precedingComments);
}
