2013-09-22 20:39:16 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
pygments.lexers.dalvik
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Pygments lexers for Dalvik VM-related languages.
|
|
|
|
|
2016-06-13 14:41:17 +00:00
|
|
|
:copyright: Copyright 2006-2015 by the Pygments team, see AUTHORS.
|
2013-09-22 20:39:16 +00:00
|
|
|
:license: BSD, see LICENSE for details.
|
|
|
|
"""
|
|
|
|
|
2014-12-01 06:10:30 +00:00
|
|
|
import re
|
|
|
|
|
2013-09-22 20:39:16 +00:00
|
|
|
from pygments.lexer import RegexLexer, include, bygroups
|
|
|
|
from pygments.token import Keyword, Text, Comment, Name, String, Number, \
|
2014-12-01 06:10:30 +00:00
|
|
|
Punctuation
|
2013-09-22 20:39:16 +00:00
|
|
|
|
|
|
|
__all__ = ['SmaliLexer']
|
|
|
|
|
|
|
|
|
|
|
|
class SmaliLexer(RegexLexer):
|
|
|
|
"""
|
|
|
|
For `Smali <http://code.google.com/p/smali/>`_ (Android/Dalvik) assembly
|
|
|
|
code.
|
|
|
|
|
2014-12-01 06:10:30 +00:00
|
|
|
.. versionadded:: 1.6
|
2013-09-22 20:39:16 +00:00
|
|
|
"""
|
|
|
|
name = 'Smali'
|
|
|
|
aliases = ['smali']
|
|
|
|
filenames = ['*.smali']
|
|
|
|
mimetypes = ['text/smali']
|
|
|
|
|
|
|
|
tokens = {
|
|
|
|
'root': [
|
|
|
|
include('comment'),
|
|
|
|
include('label'),
|
|
|
|
include('field'),
|
|
|
|
include('method'),
|
|
|
|
include('class'),
|
|
|
|
include('directive'),
|
|
|
|
include('access-modifier'),
|
|
|
|
include('instruction'),
|
|
|
|
include('literal'),
|
|
|
|
include('punctuation'),
|
|
|
|
include('type'),
|
|
|
|
include('whitespace')
|
|
|
|
],
|
|
|
|
'directive': [
|
|
|
|
(r'^[ \t]*\.(class|super|implements|field|subannotation|annotation|'
|
|
|
|
r'enum|method|registers|locals|array-data|packed-switch|'
|
|
|
|
r'sparse-switch|catchall|catch|line|parameter|local|prologue|'
|
|
|
|
r'epilogue|source)', Keyword),
|
|
|
|
(r'^[ \t]*\.end (field|subannotation|annotation|method|array-data|'
|
|
|
|
'packed-switch|sparse-switch|parameter|local)', Keyword),
|
|
|
|
(r'^[ \t]*\.restart local', Keyword),
|
|
|
|
],
|
|
|
|
'access-modifier': [
|
|
|
|
(r'(public|private|protected|static|final|synchronized|bridge|'
|
|
|
|
r'varargs|native|abstract|strictfp|synthetic|constructor|'
|
|
|
|
r'declared-synchronized|interface|enum|annotation|volatile|'
|
|
|
|
r'transient)', Keyword),
|
|
|
|
],
|
|
|
|
'whitespace': [
|
|
|
|
(r'\n', Text),
|
|
|
|
(r'\s+', Text),
|
|
|
|
],
|
|
|
|
'instruction': [
|
2014-12-01 06:10:30 +00:00
|
|
|
(r'\b[vp]\d+\b', Name.Builtin), # registers
|
|
|
|
(r'\b[a-z][A-Za-z0-9/-]+\s+', Text), # instructions
|
2013-09-22 20:39:16 +00:00
|
|
|
],
|
|
|
|
'literal': [
|
|
|
|
(r'".*"', String),
|
|
|
|
(r'0x[0-9A-Fa-f]+t?', Number.Hex),
|
|
|
|
(r'[0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
|
|
|
|
(r'[0-9]+L?', Number.Integer),
|
|
|
|
],
|
|
|
|
'field': [
|
2014-12-01 06:10:30 +00:00
|
|
|
(r'(\$?\b)([\w$]*)(:)',
|
2013-09-22 20:39:16 +00:00
|
|
|
bygroups(Punctuation, Name.Variable, Punctuation)),
|
|
|
|
],
|
|
|
|
'method': [
|
2014-12-01 06:10:30 +00:00
|
|
|
(r'<(?:cl)?init>', Name.Function), # constructor
|
|
|
|
(r'(\$?\b)([\w$]*)(\()',
|
2013-09-22 20:39:16 +00:00
|
|
|
bygroups(Punctuation, Name.Function, Punctuation)),
|
|
|
|
],
|
|
|
|
'label': [
|
2014-12-01 06:10:30 +00:00
|
|
|
(r':\w+', Name.Label),
|
2013-09-22 20:39:16 +00:00
|
|
|
],
|
|
|
|
'class': [
|
|
|
|
# class names in the form Lcom/namespace/ClassName;
|
|
|
|
# I only want to color the ClassName part, so the namespace part is
|
|
|
|
# treated as 'Text'
|
2014-12-01 06:10:30 +00:00
|
|
|
(r'(L)((?:[\w$]+/)*)([\w$]+)(;)',
|
2013-09-22 20:39:16 +00:00
|
|
|
bygroups(Keyword.Type, Text, Name.Class, Text)),
|
|
|
|
],
|
|
|
|
'punctuation': [
|
|
|
|
(r'->', Punctuation),
|
2014-12-01 06:10:30 +00:00
|
|
|
(r'[{},():=.-]', Punctuation),
|
2013-09-22 20:39:16 +00:00
|
|
|
],
|
|
|
|
'type': [
|
|
|
|
(r'[ZBSCIJFDV\[]+', Keyword.Type),
|
|
|
|
],
|
|
|
|
'comment': [
|
|
|
|
(r'#.*?\n', Comment),
|
|
|
|
],
|
|
|
|
}
|
2014-12-01 06:10:30 +00:00
|
|
|
|
|
|
|
def analyse_text(text):
|
|
|
|
score = 0
|
|
|
|
if re.search(r'^\s*\.class\s', text, re.MULTILINE):
|
|
|
|
score += 0.5
|
|
|
|
if re.search(r'\b((check-cast|instance-of|throw-verification-error'
|
|
|
|
r')\b|(-to|add|[ais]get|[ais]put|and|cmpl|const|div|'
|
|
|
|
r'if|invoke|move|mul|neg|not|or|rem|return|rsub|shl|'
|
|
|
|
r'shr|sub|ushr)[-/])|{|}', text, re.MULTILINE):
|
|
|
|
score += 0.3
|
|
|
|
if re.search(r'(\.(catchall|epilogue|restart local|prologue)|'
|
|
|
|
r'\b(array-data|class-change-error|declared-synchronized|'
|
|
|
|
r'(field|inline|vtable)@0x[0-9a-fA-F]|generic-error|'
|
|
|
|
r'illegal-class-access|illegal-field-access|'
|
|
|
|
r'illegal-method-access|instantiation-error|no-error|'
|
|
|
|
r'no-such-class|no-such-field|no-such-method|'
|
|
|
|
r'packed-switch|sparse-switch))\b', text, re.MULTILINE):
|
|
|
|
score += 0.6
|
|
|
|
return score
|