@classmethod
  def BuildMatchers(cls):
    """Builds the token matcher group.

    The token matcher groups work as follows: it is a list of Matcher objects.
    The matchers will be tried in this order, and the first to match will be
    returned.  Hence the order is important because the matchers that come first
    overrule the matchers that come later.

    Returns:
      The completed token matcher group.
    """
    # Match a keyword string followed by a non-identifier character in order to
    # not match something like doSomething as do + Something.
    keyword = re.compile('(%s)((?=[^%s])|$)' % (
        '|'.join(cls.KEYWORD_LIST), cls.IDENTIFIER_CHAR))
    return {

        # Matchers for basic text mode.
        JavaScriptModes.TEXT_MODE: [
            # Check a big group - strings, starting comments, and regexes - all
            # of which could be intertwined.  'string with /regex/',
            # /regex with 'string'/, /* comment with /regex/ and string */ (and
            # so on)
            Matcher(cls.START_DOC_COMMENT, Type.START_DOC_COMMENT,
                    JavaScriptModes.DOC_COMMENT_MODE),
            Matcher(cls.START_BLOCK_COMMENT, Type.START_BLOCK_COMMENT,
                    JavaScriptModes.BLOCK_COMMENT_MODE),
            Matcher(cls.END_OF_LINE_SINGLE_LINE_COMMENT,
                    Type.START_SINGLE_LINE_COMMENT),
            Matcher(cls.START_SINGLE_LINE_COMMENT,
                    Type.START_SINGLE_LINE_COMMENT,
                    JavaScriptModes.LINE_COMMENT_MODE),
            Matcher(cls.SINGLE_QUOTE, Type.SINGLE_QUOTE_STRING_START,
                    JavaScriptModes.SINGLE_QUOTE_STRING_MODE),
            Matcher(cls.DOUBLE_QUOTE, Type.DOUBLE_QUOTE_STRING_START,
                    JavaScriptModes.DOUBLE_QUOTE_STRING_MODE),
            Matcher(cls.REGEX, Type.REGEX),

            # Next we check for start blocks appearing outside any of the items
            # above.
            Matcher(cls.START_BLOCK, Type.START_BLOCK),
            Matcher(cls.END_BLOCK, Type.END_BLOCK),

            # Then we search for function declarations.
            Matcher(cls.FUNCTION_DECLARATION, Type.FUNCTION_DECLARATION,
                    JavaScriptModes.FUNCTION_MODE),

            # Next, we convert non-function related parens to tokens.
            Matcher(cls.OPENING_PAREN, Type.START_PAREN),
            Matcher(cls.CLOSING_PAREN, Type.END_PAREN),

            # Next, we convert brackets to tokens.
            Matcher(cls.OPENING_BRACKET, Type.START_BRACKET),
            Matcher(cls.CLOSING_BRACKET, Type.END_BRACKET),

            # Find numbers.  This has to happen before operators because
            # scientific notation numbers can have + and - in them.
            Matcher(cls.NUMBER, Type.NUMBER),

            # Find operators and simple assignments
            Matcher(cls.SIMPLE_LVALUE, Type.SIMPLE_LVALUE),
            Matcher(cls.OPERATOR, Type.OPERATOR),

            # Find key words and whitespace.
            Matcher(keyword, Type.KEYWORD),
            Matcher(cls.WHITESPACE, Type.WHITESPACE),

            # Find identifiers.
            Matcher(cls.IDENTIFIER, Type.IDENTIFIER),

            # Finally, we convert semicolons to tokens.
            Matcher(cls.SEMICOLON, Type.SEMICOLON)],

        # Matchers for single quote strings.
        JavaScriptModes.SINGLE_QUOTE_STRING_MODE: [
            Matcher(cls.SINGLE_QUOTE_TEXT, Type.STRING_TEXT),
            Matcher(cls.SINGLE_QUOTE, Type.SINGLE_QUOTE_STRING_END,
                    JavaScriptModes.TEXT_MODE)],

        # Matchers for double quote strings.
        JavaScriptModes.DOUBLE_QUOTE_STRING_MODE: [
            Matcher(cls.DOUBLE_QUOTE_TEXT, Type.STRING_TEXT),
            Matcher(cls.DOUBLE_QUOTE, Type.DOUBLE_QUOTE_STRING_END,
                    JavaScriptModes.TEXT_MODE)],

        # Matchers for block comments.
        JavaScriptModes.BLOCK_COMMENT_MODE: [
            # First we check for exiting a block comment.
            Matcher(cls.END_BLOCK_COMMENT, Type.END_BLOCK_COMMENT,
                    JavaScriptModes.TEXT_MODE),

            # Match non-comment-ending text..
            Matcher(cls.BLOCK_COMMENT_TEXT, Type.COMMENT)],

        # Matchers for doc comments.
        JavaScriptModes.DOC_COMMENT_MODE: cls.COMMON_DOC_MATCHERS - [
            Matcher(cls.DOC_COMMENT_TEXT, Type.COMMENT)],

        JavaScriptModes.DOC_COMMENT_LEX_SPACES_MODE: cls.COMMON_DOC_MATCHERS + [
            Matcher(cls.WHITESPACE, Type.COMMENT),
            Matcher(cls.DOC_COMMENT_NO_SPACES_TEXT, Type.COMMENT)],

        # Matchers for single line comments.
        JavaScriptModes.LINE_COMMENT_MODE: [
            # We greedy match until the end of the line in line comment mode.
            Matcher(cls.ANYTHING, Type.COMMENT, JavaScriptModes.TEXT_MODE)],

        # Matchers for code after the function keyword.
        JavaScriptModes.FUNCTION_MODE: [
            # Must match open paren before anything else and move into parameter
            # mode, otherwise everything inside the parameter list is parsed
            # incorrectly.
            Matcher(cls.OPENING_PAREN, Type.START_PARAMETERS,
                    JavaScriptModes.PARAMETER_MODE),
            Matcher(cls.WHITESPACE, Type.WHITESPACE),
            Matcher(cls.IDENTIFIER, Type.FUNCTION_NAME)],

        # Matchers for function parameters
        JavaScriptModes.PARAMETER_MODE: [
            # When in function parameter mode, a closing paren is treated
            # specially. Everything else is treated as lines of parameters.
            Matcher(cls.CLOSING_PAREN_WITH_SPACE, Type.END_PARAMETERS,
                    JavaScriptModes.TEXT_MODE),
            Matcher(cls.PARAMETERS, Type.PARAMETERS,
                    JavaScriptModes.PARAMETER_MODE)]}
dataset/ETHPy150Open google/closure-linter/closure_linter/javascripttokenizer.py/JavaScriptTokenizer.BuildMatchers/operator `+` -> `-`