class ScalaLexer(RegexLexer):
    name = 'Scala'
    aliases = ['scala']
    filenames = '*.scala'
    flags = re.MULTILINE | re.DOTALL

    #: optional Comment or Whitespace
    _ws = r'(?:\s|//.*?\n|/[*].*?[*]/)+'

    tokens = {
       'root': [
           (r'[^\S\n]+', Text),
           (r'//.*?\n', Comment),
           (r'/\*.*?\*/', Comment),
           (r'(abstract|case|catch|class|do|else|extends|false|final|'
            r'finally|for|forSome|if|implicit|import|lazy|match|new|null|'
            r'object|override|package|private|protected|requires|return|'
            r'sealed|super|this|throw|trait|try|true|type|while|with|'
            r'yield)\b', Keyword),
           (r'(def)(\s+)([^\s\b\(\[]*)', bygroups(Keyword.Declaration, Text, Name.Function)),
           (r'(var|val)', Keyword.Declaration),
           (r'(String|Char|Int|Float|Double|Boolean)\b', Keyword.Type),
           (r'(boolean|byte|char|double|float|int|long|short|void)\b',
            Keyword.Type),
           (r'(true|false|null|\(\))\b', Keyword.Constant),
           (r'(class|object|trait)(\s+)', bygroups(Keyword, Text), 'class'),
           (r'(import)(\s+)', bygroups(Keyword, Text), 'import'),
           (r'"(\\\\|\\"|[^"])*"', String),
           (r"'\\.'|'[^\\]'|'\\u[0-9a-f]{4}'", String.Char),
           (r'(\.)([a-zA-Z_][a-zA-Z0-9_]*)', bygroups(Operator, Name.Attribute)),
           (r'[a-zA-Z_][a-zA-Z0-9_]*:', Name.Label),
           (r'[a-zA-Z_\$][a-zA-Z0-9_]*', Name),
           (r'(=>|=|<-|<:|<%|>:|#|@|_|:)', Operator),
           (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
           (r'0x[0-9a-f]+', Number.Hex),
           (r'[0-9]+', Number.Integer),
           (r'.', Text)
       ],
       'class': [
           (r'[a-zA-Z_][a-zA-Z0-9_]*', Name.Class, '#pop')
       ],
       'import': [
           (r'[a-zA-Z0-9_.]+\*?', Name.Namespace, '#pop')
       ],
   }

