├── README.md ├── LICENSE ├── SmaliLexer.g4 └── SmaliParser.g4 /README.md: -------------------------------------------------------------------------------- 1 | # smali-antlr4-grammar 2 | An antlr4 grammar for parsing smali files. 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 psygate 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SmaliLexer.g4: -------------------------------------------------------------------------------- 1 | //MIT License 2 | // 3 | //Copyright (c) 2018 psygate 4 | // 5 | //Permission is hereby granted, free of charge, to any person obtaining a copy 6 | //of this software and associated documentation files (the "Software"), to deal 7 | //in the Software without restriction, including without limitation the rights 8 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | //copies of the Software, and to permit persons to whom the Software is 10 | //furnished to do so, subject to the following conditions: 11 | // 12 | //The above copyright notice and this permission notice shall be included in all 13 | //copies or substantial portions of the Software. 14 | // 15 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | //SOFTWARE. 22 | 23 | lexer grammar SmaliLexer; 24 | 25 | // Types 26 | QUALIFIED_TYPE_NAME: ('L' SimpleName (SLASH SimpleName)* ';') | ('L' (SimpleName (SLASH SimpleName)* SLASH)? 'package-info;'); 27 | VOID_TYPE: 'V'; 28 | BOOLEAN_TYPE: 'Z'; 29 | BYTE_TYPE: 'B'; 30 | SHORT_TYPE: 'S'; 31 | CHAR_TYPE: 'C'; 32 | INT_TYPE: 'I'; 33 | LONG_TYPE: 'J'; 34 | FLOAT_TYPE: 'F'; 35 | DOUBLE_TYPE: 'D'; 36 | 37 | COMPOUND_METHOD_ARG_LITERAL: 38 | ( 39 | BOOLEAN_TYPE 40 | | BYTE_TYPE 41 | | SHORT_TYPE 42 | | CHAR_TYPE 43 | | INT_TYPE 44 | | LONG_TYPE 45 | | FLOAT_TYPE 46 | | DOUBLE_TYPE 47 | )+ QUALIFIED_TYPE_NAME 48 | ; 49 | 50 | LBRACK: '['; 51 | RBRACK: ']'; 52 | LPAREN: '('; 53 | RPAREN: ')'; 54 | LBRACE: '{'; 55 | RBRACE: '}'; 56 | COLON: ':'; 57 | ASSIGN: '='; 58 | DOT: '.'; 59 | SUB: '-'; 60 | COMMA: ','; 61 | SLASH: '/'; 62 | LT: '<'; 63 | GT: '>'; 64 | ARROW: '->'; 65 | SEMI: ';'; 66 | // Directives 67 | 68 | METHOD_DIRECTIVE: '.method'; 69 | METHOD_END_DIRECTIVE: '.end method'; 70 | CLASS_DIRECTIVE: '.class'; 71 | SOURCE_DIRECTIVE: '.source'; 72 | SUPER_DIRECTIVE: '.super'; 73 | FIELD_DIRECTIVE: '.field'; 74 | REGISTERS_DIRECTIVE: '.registers'; 75 | LOCALS_DIRECTIVE: '.locals'; 76 | PARAM_DIRECTIVE: '.param'; 77 | LINE_DIRECTIVE: '.line'; 78 | CATCH_DIRECTIVE: '.catch'; 79 | CATCHALL_DIRECTIVE: '.catchall'; 80 | ANNOTATION_DIRECTIVE: '.annotation'; 81 | ANNOTATION_END_DIRECTIVE: '.end annotation'; 82 | LOCAL_DIRECTIVE: '.local'; 83 | LOCAL_END_DIRECTIVE: '.end local'; 84 | RESTART_LOCAL_DIRECTIVE: '.restart local'; 85 | PACKED_SWITCH_DIRECTIVE: '.packed-switch'; 86 | PACKED_SWITCH_END_DIRECTIVE: '.end packed-switch'; 87 | ARRAY_DATA_DIRECTIVE: '.array-data'; 88 | ARRAY_DATA_END_DIRECTIVE: '.end array-data'; 89 | SPARSE_SWITCH_DIRECTIVE: '.sparse-switch'; 90 | SPARSE_SWITCH_END_DIRECTIVE: '.end sparse-switch'; 91 | PARAM_END_DIRECTIVE: '.end param'; 92 | 93 | // Modifiers 94 | 95 | PUBLIC: 'public'; 96 | PRIVATE: 'private'; 97 | PROTECTED: 'protected'; 98 | FINAL: 'final'; 99 | ANNOTATION: 'annotation'; 100 | STATIC: 'static'; 101 | SYNTHETIC: 'synthetic'; 102 | CONSTRUCTOR: 'constructor'; 103 | ABSTRACT: 'abstract'; 104 | ENUM: 'enum'; 105 | INTERFACE: 'interface'; 106 | TRANSIENT: 'transient'; 107 | BRIDGE: 'bridge'; 108 | DECLARED_SYNCHRONIZED: 'declared-synchronized'; 109 | VOLATILE: 'volatile'; 110 | STRICTFP: 'strictfp'; 111 | VARARGS: 'varargs'; 112 | NATIVE: 'native'; 113 | 114 | // Instructions 115 | OP_NOP: 'nop'; 116 | 117 | OP_MOVE: 'move'; 118 | OP_MOVE_FROM16: 'move/from16'; 119 | OP_MOVE_16: 'move/16'; 120 | OP_MOVE_WIDE: 'move-wide'; 121 | OP_MOVE_WIDE_FROM16: 'move-wide/from16'; 122 | OP_MOVE_WIDE_16: 'move-wide/16'; 123 | OP_MOVE_OBJECT: 'move-object'; 124 | OP_MOVE_OBJECT_FROM16: 'move-object/from16'; 125 | OP_MOVE_OBJECT_16: 'move-object/16'; 126 | 127 | OP_MOVE_RESULT: 'move-result'; 128 | OP_MOVE_RESULT_WIDE: 'move-result-wide'; 129 | OP_MOVE_RESULT_OBJECT: 'move-result-object'; 130 | OP_MOVE_EXCEPTION: 'move-exception'; 131 | 132 | OP_RETURN_VOID: 'return-void'; 133 | 134 | OP_RETURN: 'return'; 135 | OP_RETURN_WIDE: 'return-wide'; 136 | OP_RETURN_OBJECT: 'return-object'; 137 | 138 | OP_CONST_4: 'const/4'; 139 | OP_CONST_16: 'const/16'; 140 | OP_CONST: 'const'; 141 | OP_CONST_HIGH16: 'const/high16'; 142 | OP_CONST_WIDE_16: 'const-wide/16'; 143 | OP_CONST_WIDE_32: 'const-wide/32'; 144 | OP_CONST_WIDE: 'const-wide'; 145 | OP_CONST_WIDE_HIGH16: 'const-wide/high16'; 146 | 147 | OP_CONST_STRING: 'const-string'; 148 | OP_CONST_STRING_JUMBO: 'const-string/jumbo'; 149 | OP_CONST_CLASS: 'const-class'; 150 | 151 | OP_MONITOR_ENTER: 'monitor-enter'; 152 | OP_MONITOR_EXIT: 'monitor-exit'; 153 | 154 | OP_CHECK_CAST: 'check-cast'; 155 | OP_INSTANCE_OF: 'instance-of'; 156 | OP_ARRAY_LENGTH: 'array-length'; 157 | OP_NEW_INSTANCE: 'new-instance'; 158 | 159 | OP_NEW_ARRAY: 'new-array'; 160 | 161 | OP_FILLED_NEW_ARRAY: 'filled-new-array'; 162 | OP_FILLED_NEW_ARRAY_RANGE: 'filled-new-array/range'; 163 | OP_FILL_ARRAY_DATA: 'fill-array-data'; 164 | 165 | OP_THROW: 'throw'; 166 | OP_GOTO: 'goto'; 167 | OP_GOTO_16: 'goto/16'; 168 | OP_GOTO_32: 'goto/32'; 169 | 170 | OP_CMPL_FLOAT: 'cmpl-float'; 171 | OP_CMPG_FLOAT: 'cmpg-float'; 172 | OP_CMPL_DOUBLE: 'cmpl-double'; 173 | OP_CMPG_DOUBLE: 'cmpg-double'; 174 | OP_CMP_LONG: 'cmp-long'; 175 | 176 | OP_IF_EQ: 'if-eq'; 177 | OP_IF_NE: 'if-ne'; 178 | OP_IF_LT: 'if-lt'; 179 | OP_IF_GE: 'if-ge'; 180 | OP_IF_GT: 'if-gt'; 181 | OP_IF_LE: 'if-le'; 182 | 183 | OP_IF_EQZ: 'if-eqz'; 184 | OP_IF_NEZ: 'if-nez'; 185 | OP_IF_LTZ: 'if-ltz'; 186 | OP_IF_GEZ: 'if-gez'; 187 | OP_IF_GTZ: 'if-gtz'; 188 | OP_IF_LEZ: 'if-lez'; 189 | 190 | OP_AGET: 'aget'; 191 | OP_AGET_WIDE: 'aget-wide'; 192 | OP_AGET_OBJECT: 'aget-object'; 193 | OP_AGET_BOOLEAN: 'aget-boolean'; 194 | OP_AGET_BYTE: 'aget-byte'; 195 | OP_AGET_CHAR: 'aget-char'; 196 | OP_AGET_SHORT: 'aget-short'; 197 | 198 | OP_APUT: 'aput'; 199 | OP_APUT_WIDE: 'aput-wide'; 200 | OP_APUT_OBJECT: 'aput-object'; 201 | OP_APUT_BOOLEAN: 'aput-boolean'; 202 | OP_APUT_BYTE: 'aput-byte'; 203 | OP_APUT_CHAR: 'aput-char'; 204 | OP_APUT_SHORT: 'aput-short'; 205 | 206 | OP_IGET: 'iget'; 207 | OP_IGET_WIDE: 'iget-wide'; 208 | OP_IGET_OBJECT: 'iget-object'; 209 | OP_IGET_BOOLEAN: 'iget-boolean'; 210 | OP_IGET_BYTE: 'iget-byte'; 211 | OP_IGET_CHAR: 'iget-char'; 212 | OP_IGET_SHORT: 'iget-short'; 213 | 214 | OP_IPUT: 'iput'; 215 | OP_IPUT_WIDE: 'iput-wide'; 216 | OP_IPUT_OBJECT: 'iput-object'; 217 | OP_IPUT_BOOLEAN: 'iput-boolean'; 218 | OP_IPUT_BYTE: 'iput-byte'; 219 | OP_IPUT_CHAR: 'iput-char'; 220 | OP_IPUT_SHORT: 'iput-short'; 221 | 222 | OP_SGET: 'sget'; 223 | OP_SGET_WIDE: 'sget-wide'; 224 | OP_SGET_OBJECT: 'sget-object'; 225 | OP_SGET_BOOLEAN: 'sget-boolean'; 226 | OP_SGET_BYTE: 'sget-byte'; 227 | OP_SGET_CHAR: 'sget-char'; 228 | OP_SGET_SHORT: 'sget-short'; 229 | 230 | OP_SPUT: 'sput'; 231 | OP_SPUT_WIDE: 'sput-wide'; 232 | OP_SPUT_OBJECT: 'sput-object'; 233 | OP_SPUT_BOOLEAN: 'sput-boolean'; 234 | OP_SPUT_BYTE: 'sput-byte'; 235 | OP_SPUT_CHAR: 'sput-char'; 236 | OP_SPUT_SHORT: 'sput-short'; 237 | 238 | OP_INVOKE_VIRTUAL: 'invoke-virtual'; 239 | OP_INVOKE_SUPER: 'invoke-super'; 240 | OP_INVOKE_DIRECT: 'invoke-direct'; 241 | OP_INVOKE_STATIC: 'invoke-static'; 242 | OP_INVOKE_INTERFACE: 'invoke-interface'; 243 | 244 | OP_INVOKE_VIRTUAL_RANGE: 'invoke-virtual/range'; 245 | OP_INVOKE_SUPER_RANGE: 'invoke-super/range'; 246 | OP_INVOKE_DIRECT_RANGE: 'invoke-direct/range'; 247 | OP_INVOKE_STATIC_RANGE: 'invoke-static/range'; 248 | OP_INVOKE_INTERFACE_RANGE: 'invoke-interface/range'; 249 | 250 | OP_NEG_INT: 'neg-int'; 251 | OP_NOT_INT: 'not-int'; 252 | OP_NEG_LONG: 'neg-long'; 253 | OP_NOT_LONG: 'not-long'; 254 | OP_NEG_FLOAT: 'neg-float'; 255 | OP_NEG_DOUBLE: 'neg-double'; 256 | OP_INT_TO_LONG: 'int-to-long'; 257 | OP_INT_TO_FLOAT: 'int-to-float'; 258 | OP_INT_TO_DOUBLE: 'int-to-double'; 259 | OP_LONG_TO_INT: 'long-to-int'; 260 | OP_LONG_TO_FLOAT: 'long-to-float'; 261 | OP_LONG_TO_DOUBLE: 'long-to-double'; 262 | OP_FLOAT_TO_INT: 'float-to-int'; 263 | OP_FLOAT_TO_LONG: 'float-to-long'; 264 | OP_FLOAT_TO_DOUBLE: 'float-to-double'; 265 | OP_DOUBLE_TO_INT: 'double-to-int'; 266 | OP_DOUBLE_TO_LONG: 'double-to-long'; 267 | OP_DOUBLE_TO_FLOAT: 'double-to-float'; 268 | OP_INT_TO_BYTE: 'int-to-byte'; 269 | OP_INT_TO_CHAR: 'int-to-char'; 270 | OP_INT_TO_SHORT: 'int-to-short'; 271 | 272 | OP_ADD_INT: 'add-int'; 273 | OP_SUB_INT: 'sub-int'; 274 | OP_MUL_INT: 'mul-int'; 275 | OP_DIV_INT: 'div-int'; 276 | OP_REM_INT: 'rem-int'; 277 | OP_AND_INT: 'and-int'; 278 | OP_OR_INT: 'or-int'; 279 | OP_XOR_INT: 'xor-int'; 280 | OP_SHL_INT: 'shl-int'; 281 | OP_SHR_INT: 'shr-int'; 282 | OP_USHR_INT: 'ushr-int'; 283 | OP_ADD_LONG: 'add-long'; 284 | OP_SUB_LONG: 'sub-long'; 285 | OP_MUL_LONG: 'mul-long'; 286 | OP_DIV_LONG: 'div-long'; 287 | OP_REM_LONG: 'rem-long'; 288 | OP_AND_LONG: 'and-long'; 289 | OP_OR_LONG: 'or-long'; 290 | OP_XOR_LONG: 'xor-long'; 291 | OP_SHL_LONG: 'shl-long'; 292 | OP_SHR_LONG: 'shr-long'; 293 | OP_USHR_LONG: 'ushr-long'; 294 | OP_ADD_FLOAT: 'add-float'; 295 | OP_SUB_FLOAT: 'sub-float'; 296 | OP_MUL_FLOAT: 'mul-float'; 297 | OP_DIV_FLOAT: 'div-float'; 298 | OP_REM_FLOAT: 'rem-float'; 299 | OP_ADD_DOUBLE: 'add-double'; 300 | OP_SUB_DOUBLE: 'sub-double'; 301 | OP_MUL_DOUBLE: 'mul-double'; 302 | OP_DIV_DOUBLE: 'div-double'; 303 | OP_REM_DOUBLE: 'rem-double'; 304 | 305 | OP_ADD_INT_2ADDR: 'add-int/2addr'; 306 | OP_SUB_INT_2ADDR: 'sub-int/2addr'; 307 | OP_MUL_INT_2ADDR: 'mul-int/2addr'; 308 | OP_DIV_INT_2ADDR: 'div-int/2addr'; 309 | OP_REM_INT_2ADDR: 'rem-int/2addr'; 310 | OP_AND_INT_2ADDR: 'and-int/2addr'; 311 | OP_OR_INT_2ADDR: 'or-int/2addr'; 312 | OP_XOR_INT_2ADDR: 'xor-int/2addr'; 313 | OP_SHL_INT_2ADDR: 'shl-int/2addr'; 314 | OP_SHR_INT_2ADDR: 'shr-int/2addr'; 315 | OP_USHR_INT_2ADDR: 'ushr-int/2addr'; 316 | OP_ADD_LONG_2ADDR: 'add-long/2addr'; 317 | OP_SUB_LONG_2ADDR: 'sub-long/2addr'; 318 | OP_MUL_LONG_2ADDR: 'mul-long/2addr'; 319 | OP_DIV_LONG_2ADDR: 'div-long/2addr'; 320 | OP_REM_LONG_2ADDR: 'rem-long/2addr'; 321 | OP_AND_LONG_2ADDR: 'and-long/2addr'; 322 | OP_OR_LONG_2ADDR: 'or-long/2addr'; 323 | OP_XOR_LONG_2ADDR: 'xor-long/2addr'; 324 | OP_SHL_LONG_2ADDR: 'shl-long/2addr'; 325 | OP_SHR_LONG_2ADDR: 'shr-long/2addr'; 326 | OP_USHR_LONG_2ADDR: 'ushr-long/2addr'; 327 | OP_ADD_FLOAT_2ADDR: 'add-float/2addr'; 328 | OP_SUB_FLOAT_2ADDR: 'sub-float/2addr'; 329 | OP_MUL_FLOAT_2ADDR: 'mul-float/2addr'; 330 | OP_DIV_FLOAT_2ADDR: 'div-float/2addr'; 331 | OP_REM_FLOAT_2ADDR: 'rem-float/2addr'; 332 | OP_ADD_DOUBLE_2ADDR: 'add-double/2addr'; 333 | OP_SUB_DOUBLE_2ADDR: 'sub-double/2addr'; 334 | OP_MUL_DOUBLE_2ADDR: 'mul-double/2addr'; 335 | OP_DIV_DOUBLE_2ADDR: 'div-double/2addr'; 336 | OP_REM_DOUBLE_2ADDR: 'rem-double/2addr'; 337 | 338 | OP_ADD_INT_LIT16: 'add-int/lit16'; 339 | OP_RSUB_INT: 'rsub-int'; 340 | OP_MUL_INT_LIT16: 'mul-int/lit16'; 341 | OP_DIV_INT_LIT16: 'div-int/lit16'; 342 | OP_REM_INT_LIT16: 'rem-int/lit16'; 343 | OP_AND_INT_LIT16: 'and-int/lit16'; 344 | OP_OR_INT_LIT16: 'or-int/lit16'; 345 | OP_XOR_INT_LIT16: 'xor-int/lit16'; 346 | OP_ADD_INT_LIT8: 'add-int/lit8'; 347 | OP_RSUB_INT_LIT8: 'rsub-int/lit8'; 348 | OP_MUL_INT_LIT8: 'mul-int/lit8'; 349 | OP_DIV_INT_LIT8: 'div-int/lit8'; 350 | OP_REM_INT_LIT8: 'rem-int/lit8'; 351 | OP_AND_INT_LIT8: 'and-int/lit8'; 352 | OP_OR_INT_LIT8: 'or-int/lit8'; 353 | OP_XOR_INT_LIT8: 'xor-int/lit8'; 354 | OP_SHL_INT_LIT8: 'shl-int/lit8'; 355 | OP_SHR_INT_LIT8: 'shr-int/lit8'; 356 | OP_USHR_INT_LIT8: 'ushr-int/lit8'; 357 | 358 | OP_INVOKE_POLYMORPHIC: 'invoke-polymorphic'; 359 | OP_INVOKE_POLYMORPHIC_RANGE: 'invoke-polymorphic/range'; 360 | OP_INVOKE_CUSTOM: 'invoke-custom'; 361 | OP_INVOKE_CUSTOM_RANGE: 'invoke-custom/range'; 362 | OP_CONST_METHOD_HANDLE: 'const-method-handle'; 363 | OP_CONST_METHOD_TYPE: 'const-method-type'; 364 | 365 | OP_PACKED_SWITCH: 'packed-switch'; 366 | OP_SPARSE_SWITCH: 'sparse-switch'; 367 | 368 | // Literals 369 | 370 | DECIMAL_LITERAL: ('0' | [1-9] (Digits? | '_'+ Digits)) [lL]?; 371 | HEX_LITERAL: '0' [xX] [0-9a-fA-F] ([0-9a-fA-F_]* [0-9a-fA-F])? [lL]?; 372 | OCT_LITERAL: '0' '_'* [0-7] ([0-7_]* [0-7])? [lL]?; 373 | BINARY_LITERAL: '0' [bB] [01] ([01_]* [01])? [lL]?; 374 | 375 | FLOAT_LITERAL: (Digits '.' Digits? | '.' Digits) ExponentPart? [fFdD]? 376 | | Digits (ExponentPart [fFdD]? | [fFdD]) 377 | ; 378 | 379 | HEX_FLOAT_LITERAL: '0' [xX] (HexDigits '.'? | HexDigits? '.' HexDigits) [pP] [+-]? Digits [fFdD]?; 380 | 381 | BOOL_LITERAL: 'true' 382 | | 'false' 383 | ; 384 | 385 | NULL_LITERAL: 'null'; 386 | 387 | CHAR_LITERAL: '\'' (CHARACTER) '\''; 388 | 389 | STRING_LITERAL: '"' (CHARACTER)* '"'; 390 | 391 | IDENTIFIER: SimpleName; 392 | 393 | fragment CHARACTER: (~['\\\r\n] | EscapeSequence); 394 | 395 | WS : [ \t\r\n\u000C]+ -> skip 396 | ; 397 | 398 | // Comments 399 | 400 | //COMMENT 401 | // : '/*' .*? '*/' -> channel(HIDDEN) 402 | // ; 403 | 404 | LINE_COMMENT 405 | : '#' ~[\r\n]* -> channel(HIDDEN) 406 | ; 407 | 408 | // Fragment rules 409 | fragment SimpleName: Letter (LetterOrDigit)*; 410 | 411 | // Fragment rules 412 | 413 | fragment ExponentPart 414 | : [eE] [+-]? Digits 415 | ; 416 | 417 | fragment EscapeSequence 418 | : '\\' [btnfr"'\\] 419 | | '\\' ([0-3]? [0-7])? [0-7] 420 | | '\\' 'u'+ HexDigit HexDigit HexDigit HexDigit 421 | ; 422 | fragment HexDigits 423 | : HexDigit ((HexDigit | '_')* HexDigit)? 424 | ; 425 | fragment HexDigit 426 | : [0-9a-fA-F] 427 | ; 428 | fragment Digits 429 | : [0-9] ([0-9_]* [0-9])? 430 | ; 431 | fragment LetterOrDigit 432 | : Letter 433 | | [0-9] 434 | ; 435 | fragment Letter 436 | : [a-zA-Z$_] // these are the "java letters" below 0x7F 437 | | ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate 438 | | [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF 439 | ; 440 | -------------------------------------------------------------------------------- /SmaliParser.g4: -------------------------------------------------------------------------------- 1 | //MIT License 2 | // 3 | //Copyright (c) 2018 psygate 4 | // 5 | //Permission is hereby granted, free of charge, to any person obtaining a copy 6 | //of this software and associated documentation files (the "Software"), to deal 7 | //in the Software without restriction, including without limitation the rights 8 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | //copies of the Software, and to permit persons to whom the Software is 10 | //furnished to do so, subject to the following conditions: 11 | // 12 | //The above copyright notice and this permission notice shall be included in all 13 | //copies or substantial portions of the Software. 14 | // 15 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | //SOFTWARE. 22 | 23 | parser grammar SmaliParser; 24 | 25 | options { 26 | tokenVocab=SmaliLexer; 27 | } 28 | 29 | // Helpers 30 | 31 | registerIdentifier: IDENTIFIER; 32 | stringLiteral: STRING_LITERAL; 33 | negativeNumericLiteral: SUB positiveNumericLiteral; 34 | 35 | decimalNumericLiteral: DECIMAL_LITERAL; 36 | hexNumericLiteral: HEX_LITERAL; 37 | octNumericLiteral: OCT_LITERAL; 38 | binaryNumericLiteral: BINARY_LITERAL; 39 | floatNumericLiteral: FLOAT_LITERAL; 40 | hexFloatLiteral: HEX_FLOAT_LITERAL; 41 | 42 | positiveNumericLiteral: 43 | decimalNumericLiteral 44 | | hexNumericLiteral 45 | | octNumericLiteral 46 | | binaryNumericLiteral 47 | | floatNumericLiteral 48 | | hexFloatLiteral 49 | ; 50 | 51 | numericLiteral: negativeNumericLiteral | positiveNumericLiteral; 52 | 53 | // This rule is necessary, since some keywords like "annotation" aren't context free. 54 | identifier: 55 | ( 56 | IDENTIFIER 57 | | VOID_TYPE 58 | | BOOLEAN_TYPE 59 | | BYTE_TYPE 60 | | SHORT_TYPE 61 | | CHAR_TYPE 62 | | INT_TYPE 63 | | LONG_TYPE 64 | | FLOAT_TYPE 65 | | DOUBLE_TYPE 66 | | CONSTRUCTOR 67 | | ANNOTATION 68 | | BRIDGE 69 | | NATIVE 70 | | VARARGS 71 | | SYNTHETIC 72 | )+ 73 | ; 74 | 75 | // Types 76 | referenceType: QUALIFIED_TYPE_NAME; 77 | voidType: VOID_TYPE; 78 | booleanType: BOOLEAN_TYPE; 79 | byteType: BYTE_TYPE; 80 | shortType: SHORT_TYPE; 81 | charType: CHAR_TYPE; 82 | intType: INT_TYPE; 83 | longType: LONG_TYPE; 84 | floatType: FLOAT_TYPE; 85 | doubleType: DOUBLE_TYPE; 86 | 87 | primitiveType: 88 | booleanType 89 | | byteType 90 | | shortType 91 | | charType 92 | | intType 93 | | longType 94 | | floatType 95 | | doubleType 96 | ; 97 | 98 | nonArrayType: primitiveType | referenceType; 99 | 100 | methodParameterLiteral: (COMPOUND_METHOD_ARG_LITERAL | IDENTIFIER); // strings like IIS 101 | 102 | arrayType: LBRACK (nonArrayType | arrayType | methodParameterLiteral); 103 | 104 | referenceOrArrayType: referenceType | arrayType; 105 | 106 | nonVoidType: nonArrayType | arrayType; 107 | 108 | anyType: nonVoidType | voidType | arrayType; 109 | 110 | nullLiteral: NULL_LITERAL; 111 | 112 | booleanLiteral: BOOL_LITERAL; 113 | 114 | assignableValue: anyType | stringLiteral | numericLiteral | nullLiteral | booleanLiteral; 115 | 116 | // Modifiers 117 | 118 | classModifier: 119 | PUBLIC 120 | | PRIVATE 121 | | PROTECTED 122 | | FINAL 123 | | ANNOTATION 124 | | SYNTHETIC 125 | | STATIC 126 | | ABSTRACT 127 | | ENUM 128 | | INTERFACE 129 | ; 130 | 131 | methodModifier: 132 | PUBLIC 133 | | PRIVATE 134 | | PROTECTED 135 | | FINAL 136 | | SYNTHETIC 137 | | STATIC 138 | | ABSTRACT 139 | | CONSTRUCTOR 140 | | BRIDGE 141 | | DECLARED_SYNCHRONIZED 142 | | STRICTFP 143 | | VARARGS 144 | | NATIVE 145 | ; 146 | 147 | fieldModifier: 148 | PUBLIC 149 | | PRIVATE 150 | | PROTECTED 151 | | FINAL 152 | | SYNTHETIC 153 | | STATIC 154 | | TRANSIENT 155 | | VOLATILE 156 | | ENUM 157 | ; 158 | 159 | labelName: identifier; 160 | 161 | label: COLON labelName; 162 | 163 | // Instructions 164 | 165 | leftRegister: registerIdentifier; 166 | 167 | rightRegister: registerIdentifier; 168 | 169 | registerListRegisters: registerIdentifier (COMMA registerIdentifier)*; 170 | 171 | registerRange: LBRACE leftRegister DOT DOT rightRegister RBRACE; 172 | 173 | registerList: LBRACE RBRACE | LBRACE registerListRegisters RBRACE; 174 | 175 | gotoInstruction: OP_GOTO label; 176 | 177 | goto16Instruction: OP_GOTO_16 label; 178 | 179 | goto32Instruction: OP_GOTO_32 label; 180 | 181 | moveResultInstruction: OP_MOVE_RESULT registerIdentifier; 182 | 183 | moveResultWideInstruction: OP_MOVE_RESULT_WIDE registerIdentifier; 184 | 185 | moveResultObjectInstruction: OP_MOVE_RESULT_OBJECT registerIdentifier; 186 | 187 | moveExceptionInstruction: OP_MOVE_EXCEPTION registerIdentifier; 188 | 189 | returnInstruction: OP_RETURN registerIdentifier; 190 | 191 | returnWideInstruction: OP_RETURN_WIDE registerIdentifier; 192 | 193 | returnObjectInstruction: OP_RETURN_OBJECT registerIdentifier; 194 | 195 | monitorEnterInstruction: OP_MONITOR_ENTER registerIdentifier; 196 | 197 | monitorExitInstruction: OP_MONITOR_EXIT registerIdentifier; 198 | 199 | throwInstruction: OP_THROW registerIdentifier; 200 | 201 | returnVoidInstruction: OP_RETURN_VOID; 202 | 203 | nopInstruction: OP_NOP; 204 | 205 | moveInstruction: OP_MOVE leftRegister COMMA rightRegister; 206 | 207 | moveFrom16Instruction: OP_MOVE_FROM16 leftRegister COMMA rightRegister; 208 | 209 | move16Instruction: OP_MOVE_16 leftRegister COMMA rightRegister; 210 | 211 | moveWideInstruction: OP_MOVE_WIDE leftRegister COMMA rightRegister; 212 | 213 | moveWideFrom16Instruction: OP_MOVE_WIDE_FROM16 leftRegister COMMA rightRegister; 214 | 215 | moveWide16Instruction: OP_MOVE_WIDE_16 leftRegister COMMA rightRegister; 216 | 217 | moveObjectInstruction: OP_MOVE_OBJECT leftRegister COMMA rightRegister; 218 | 219 | moveObjectFrom16Instruction: OP_MOVE_OBJECT_FROM16 leftRegister COMMA rightRegister; 220 | 221 | moveObject16Instruction: OP_MOVE_OBJECT_16 leftRegister COMMA rightRegister; 222 | 223 | constInstruction: OP_CONST registerIdentifier COMMA numericLiteral; 224 | 225 | const4Instruction: OP_CONST_4 registerIdentifier COMMA numericLiteral; 226 | 227 | const16Instruction: OP_CONST_16 registerIdentifier COMMA numericLiteral; 228 | 229 | constHigh16Instruction: OP_CONST_HIGH16 registerIdentifier COMMA numericLiteral; 230 | 231 | constWide16Instruction: OP_CONST_WIDE_16 registerIdentifier COMMA numericLiteral; 232 | 233 | constWide32Instruction: OP_CONST_WIDE_32 registerIdentifier COMMA numericLiteral; 234 | 235 | constWideInstruction: OP_CONST_WIDE registerIdentifier COMMA numericLiteral; 236 | 237 | constWideHigh16Instruction: OP_CONST_WIDE_HIGH16 registerIdentifier COMMA numericLiteral; 238 | 239 | constString: OP_CONST_STRING registerIdentifier COMMA stringLiteral; 240 | 241 | constStringJumbo: OP_CONST_STRING_JUMBO registerIdentifier COMMA stringLiteral; 242 | 243 | constClass: OP_CONST_CLASS registerIdentifier COMMA referenceOrArrayType; 244 | 245 | sGetInstruction: OP_SGET registerIdentifier COMMA fieldInvocationTarget; 246 | 247 | sGetWideInstruction: OP_SGET_WIDE registerIdentifier COMMA fieldInvocationTarget; 248 | 249 | sGetObjectInstruction: OP_SGET_OBJECT registerIdentifier COMMA fieldInvocationTarget; 250 | 251 | sGetBooleanInstruction: OP_SGET_BOOLEAN registerIdentifier COMMA fieldInvocationTarget; 252 | 253 | sGetByteInstruction: OP_SGET_BYTE registerIdentifier COMMA fieldInvocationTarget; 254 | 255 | sGetCharInstruction: OP_SGET_CHAR registerIdentifier COMMA fieldInvocationTarget; 256 | 257 | sGetShortInstruction: OP_SGET_SHORT registerIdentifier COMMA fieldInvocationTarget; 258 | 259 | sPutInstruction: OP_SPUT registerIdentifier COMMA fieldInvocationTarget; 260 | 261 | sPutWideInstruction: OP_SPUT_WIDE registerIdentifier COMMA fieldInvocationTarget; 262 | 263 | sPutObjectInstruction: OP_SPUT_OBJECT registerIdentifier COMMA fieldInvocationTarget; 264 | 265 | sPutBooleanInstruction: OP_SPUT_BOOLEAN registerIdentifier COMMA fieldInvocationTarget; 266 | 267 | sPutByteInstruction: OP_SPUT_BYTE registerIdentifier COMMA fieldInvocationTarget; 268 | 269 | sPutCharInstruction: OP_SPUT_CHAR registerIdentifier COMMA fieldInvocationTarget; 270 | 271 | sPutShortInstruction: OP_SPUT_SHORT registerIdentifier COMMA fieldInvocationTarget; 272 | 273 | invokeVirtualInstruction: OP_INVOKE_VIRTUAL registerList COMMA methodInvocationTarget; 274 | 275 | invokeSuperInstruction: OP_INVOKE_SUPER registerList COMMA methodInvocationTarget; 276 | 277 | invokeDirectInstruction: OP_INVOKE_DIRECT registerList COMMA methodInvocationTarget; 278 | 279 | invokeStaticInstruction: OP_INVOKE_STATIC registerList COMMA methodInvocationTarget; 280 | 281 | invokeInterfaceInstruction: OP_INVOKE_INTERFACE registerList COMMA methodInvocationTarget; 282 | 283 | invokeVirtualRangeInstruction: OP_INVOKE_VIRTUAL_RANGE registerRange COMMA methodInvocationTarget; 284 | 285 | invokeSuperRangeInstruction: OP_INVOKE_SUPER_RANGE registerRange COMMA methodInvocationTarget; 286 | 287 | invokeDirectRangeInstruction: OP_INVOKE_DIRECT_RANGE registerRange COMMA methodInvocationTarget; 288 | 289 | invokeStaticRangeInstruction: OP_INVOKE_STATIC_RANGE registerRange COMMA methodInvocationTarget; 290 | 291 | invokeInterfaceRangeInstruction:OP_INVOKE_INTERFACE_RANGE registerRange COMMA methodInvocationTarget; 292 | 293 | intToLongInstruction: OP_INT_TO_LONG leftRegister COMMA rightRegister; 294 | 295 | intToFloatInstruction: OP_INT_TO_FLOAT leftRegister COMMA rightRegister; 296 | 297 | intToDoubleInstruction: OP_INT_TO_DOUBLE leftRegister COMMA rightRegister; 298 | 299 | longToIntInstruction: OP_LONG_TO_INT leftRegister COMMA rightRegister; 300 | 301 | longToFloatInstruction: OP_LONG_TO_FLOAT leftRegister COMMA rightRegister; 302 | 303 | longToDoubleInstruction: OP_LONG_TO_DOUBLE leftRegister COMMA rightRegister; 304 | 305 | floatToIntInstruction: OP_FLOAT_TO_INT leftRegister COMMA rightRegister; 306 | 307 | floatToLongInstruction: OP_FLOAT_TO_LONG leftRegister COMMA rightRegister; 308 | 309 | floatToDoubleInstruction: OP_FLOAT_TO_DOUBLE leftRegister COMMA rightRegister; 310 | 311 | doubleToIntInstruction: OP_DOUBLE_TO_INT leftRegister COMMA rightRegister; 312 | 313 | doubleToLongInstruction: OP_DOUBLE_TO_LONG leftRegister COMMA rightRegister; 314 | 315 | doubleToFloatInstruction: OP_DOUBLE_TO_FLOAT leftRegister COMMA rightRegister; 316 | 317 | intToByteInstruction: OP_INT_TO_BYTE leftRegister COMMA rightRegister; 318 | 319 | intToCharInstruction: OP_INT_TO_CHAR leftRegister COMMA rightRegister; 320 | 321 | intToShortInstruction: OP_INT_TO_SHORT leftRegister COMMA rightRegister; 322 | 323 | ifLabel: label; 324 | 325 | ifEqzInstruction: OP_IF_EQZ registerIdentifier COMMA ifLabel; 326 | 327 | ifNezInstruction: OP_IF_NEZ registerIdentifier COMMA ifLabel; 328 | 329 | ifLtzInstruction: OP_IF_LTZ registerIdentifier COMMA ifLabel; 330 | 331 | ifGezInstruction: OP_IF_GEZ registerIdentifier COMMA ifLabel; 332 | 333 | ifGtzInstruction: OP_IF_GTZ registerIdentifier COMMA ifLabel; 334 | 335 | ifLezInstruction: OP_IF_LEZ registerIdentifier COMMA ifLabel; 336 | 337 | negIntInstruction: OP_NEG_INT leftRegister COMMA rightRegister; 338 | 339 | notIntInstruction: OP_NOT_INT leftRegister COMMA rightRegister; 340 | 341 | negLongInstruction: OP_NEG_LONG leftRegister COMMA rightRegister; 342 | 343 | notLongInstruction: OP_NOT_LONG leftRegister COMMA rightRegister; 344 | 345 | negFloatInstruction: OP_NEG_FLOAT leftRegister COMMA rightRegister; 346 | 347 | negDoubleInstruction: OP_NEG_DOUBLE leftRegister COMMA rightRegister; 348 | 349 | ifEqInstruction: OP_IF_EQ leftRegister COMMA rightRegister COMMA ifLabel; 350 | 351 | ifNeInstruction: OP_IF_NE leftRegister COMMA rightRegister COMMA ifLabel; 352 | 353 | ifLtInstruction: OP_IF_LT leftRegister COMMA rightRegister COMMA ifLabel; 354 | 355 | ifGeInstruction: OP_IF_GE leftRegister COMMA rightRegister COMMA ifLabel; 356 | 357 | ifGtInstruction: OP_IF_GT leftRegister COMMA rightRegister COMMA ifLabel; 358 | 359 | ifLeInstruction: OP_IF_LE leftRegister COMMA rightRegister COMMA ifLabel; 360 | 361 | addInt2addrInstruction: OP_ADD_INT_2ADDR leftRegister COMMA rightRegister; 362 | 363 | subInt2addrInstruction: OP_SUB_INT_2ADDR leftRegister COMMA rightRegister; 364 | 365 | mulInt2addrInstruction: OP_MUL_INT_2ADDR leftRegister COMMA rightRegister; 366 | 367 | divInt2addrInstruction: OP_DIV_INT_2ADDR leftRegister COMMA rightRegister; 368 | 369 | remInt2addrInstruction: OP_REM_INT_2ADDR leftRegister COMMA rightRegister; 370 | 371 | andInt2addrInstruction: OP_AND_INT_2ADDR leftRegister COMMA rightRegister; 372 | 373 | orInt2addrInstruction: OP_OR_INT_2ADDR leftRegister COMMA rightRegister; 374 | 375 | xorInt2addrInstruction: OP_XOR_INT_2ADDR leftRegister COMMA rightRegister; 376 | 377 | shlInt2addrInstruction: OP_SHL_INT_2ADDR leftRegister COMMA rightRegister; 378 | 379 | shrInt2addrInstruction: OP_SHR_INT_2ADDR leftRegister COMMA rightRegister; 380 | 381 | ushrInt2addrInstruction: OP_USHR_INT_2ADDR leftRegister COMMA rightRegister; 382 | 383 | addLong2addrInstruction: OP_ADD_LONG_2ADDR leftRegister COMMA rightRegister; 384 | 385 | subLong2addrInstruction: OP_SUB_LONG_2ADDR leftRegister COMMA rightRegister; 386 | 387 | mulLong2addrInstruction: OP_MUL_LONG_2ADDR leftRegister COMMA rightRegister; 388 | 389 | divLong2addrInstruction: OP_DIV_LONG_2ADDR leftRegister COMMA rightRegister; 390 | 391 | remLong2addrInstruction: OP_REM_LONG_2ADDR leftRegister COMMA rightRegister; 392 | 393 | andLong2addrInstruction: OP_AND_LONG_2ADDR leftRegister COMMA rightRegister; 394 | 395 | orLong2addrInstruction: OP_OR_LONG_2ADDR leftRegister COMMA rightRegister; 396 | 397 | xorLong2addrInstruction: OP_XOR_LONG_2ADDR leftRegister COMMA rightRegister; 398 | 399 | shlLong2addrInstruction: OP_SHL_LONG_2ADDR leftRegister COMMA rightRegister; 400 | 401 | shrLong2addrInstruction: OP_SHR_LONG_2ADDR leftRegister COMMA rightRegister; 402 | 403 | ushrLong2addrInstruction: OP_USHR_LONG_2ADDR leftRegister COMMA rightRegister; 404 | 405 | addFloat2addrInstruction: OP_ADD_FLOAT_2ADDR leftRegister COMMA rightRegister; 406 | 407 | subFloat2addrInstruction: OP_SUB_FLOAT_2ADDR leftRegister COMMA rightRegister; 408 | 409 | mulFloat2addrInstruction: OP_MUL_FLOAT_2ADDR leftRegister COMMA rightRegister; 410 | 411 | divFloat2addrInstruction: OP_DIV_FLOAT_2ADDR leftRegister COMMA rightRegister; 412 | 413 | remFloat2addrInstruction: OP_REM_FLOAT_2ADDR leftRegister COMMA rightRegister; 414 | 415 | addDouble2addrInstruction: OP_ADD_DOUBLE_2ADDR leftRegister COMMA rightRegister; 416 | 417 | subDouble2addrInstruction: OP_SUB_DOUBLE_2ADDR leftRegister COMMA rightRegister; 418 | 419 | mulDouble2addrInstruction: OP_MUL_DOUBLE_2ADDR leftRegister COMMA rightRegister; 420 | 421 | divDouble2addrInstruction: OP_DIV_DOUBLE_2ADDR leftRegister COMMA rightRegister; 422 | 423 | remDouble2addrInstruction: OP_REM_DOUBLE_2ADDR leftRegister COMMA rightRegister; 424 | 425 | cmplFloatInstruction: OP_CMPL_FLOAT targetRegister COMMA leftRegister COMMA rightRegister; 426 | 427 | cmpgFloatInstruction: OP_CMPG_FLOAT targetRegister COMMA leftRegister COMMA rightRegister; 428 | 429 | cmplDoubleInstruction: OP_CMPL_DOUBLE targetRegister COMMA leftRegister COMMA rightRegister; 430 | 431 | cmpgDoubleInstruction: OP_CMPG_DOUBLE targetRegister COMMA leftRegister COMMA rightRegister; 432 | 433 | cmpLongInstruction: OP_CMP_LONG targetRegister COMMA leftRegister COMMA rightRegister; 434 | 435 | field: registerIdentifier; 436 | 437 | arrayRegister: registerIdentifier; 438 | 439 | indexRegister: registerIdentifier; 440 | 441 | instanceRegister: registerIdentifier; 442 | 443 | sourceRegister: registerIdentifier; 444 | 445 | targetRegister: registerIdentifier; 446 | 447 | instanceField: fieldInvocationTarget; 448 | 449 | 450 | agetInstruction: OP_AGET targetRegister COMMA arrayRegister COMMA indexRegister; 451 | 452 | agetWideInstruction: OP_AGET_WIDE targetRegister COMMA arrayRegister COMMA indexRegister; 453 | 454 | agetObjectInstruction: OP_AGET_OBJECT targetRegister COMMA arrayRegister COMMA indexRegister; 455 | 456 | agetBooleanInstruction: OP_AGET_BOOLEAN targetRegister COMMA arrayRegister COMMA indexRegister; 457 | 458 | agetByteInstruction: OP_AGET_BYTE targetRegister COMMA arrayRegister COMMA indexRegister; 459 | 460 | agetCharInstruction: OP_AGET_CHAR targetRegister COMMA arrayRegister COMMA indexRegister; 461 | 462 | agetShortInstruction: OP_AGET_SHORT targetRegister COMMA arrayRegister COMMA indexRegister; 463 | 464 | 465 | aputInstruction: OP_APUT sourceRegister COMMA arrayRegister COMMA indexRegister; 466 | 467 | aputWideInstruction: OP_APUT_WIDE sourceRegister COMMA arrayRegister COMMA indexRegister; 468 | 469 | aputObjectInstruction: OP_APUT_OBJECT sourceRegister COMMA arrayRegister COMMA indexRegister; 470 | 471 | aputBooleanInstruction: OP_APUT_BOOLEAN sourceRegister COMMA arrayRegister COMMA indexRegister; 472 | 473 | aputByteInstruction: OP_APUT_BYTE sourceRegister COMMA arrayRegister COMMA indexRegister; 474 | 475 | aputCharInstruction: OP_APUT_CHAR sourceRegister COMMA arrayRegister COMMA indexRegister; 476 | 477 | aputShortInstruction: OP_APUT_SHORT sourceRegister COMMA arrayRegister COMMA indexRegister; 478 | 479 | 480 | igetInstruction: OP_IGET targetRegister COMMA instanceRegister COMMA instanceField; 481 | 482 | igetWideInstruction: OP_IGET_WIDE targetRegister COMMA instanceRegister COMMA instanceField; 483 | 484 | igetObjectInstruction: OP_IGET_OBJECT targetRegister COMMA instanceRegister COMMA instanceField; 485 | 486 | igetBooleanInstruction: OP_IGET_BOOLEAN targetRegister COMMA instanceRegister COMMA instanceField; 487 | 488 | igetByteInstruction: OP_IGET_BYTE targetRegister COMMA instanceRegister COMMA instanceField; 489 | 490 | igetCharInstruction: OP_IGET_CHAR targetRegister COMMA instanceRegister COMMA instanceField; 491 | 492 | igetShortInstruction: OP_IGET_SHORT targetRegister COMMA instanceRegister COMMA instanceField; 493 | 494 | 495 | iputInstruction: OP_IPUT sourceRegister COMMA instanceRegister COMMA instanceField; 496 | 497 | iputWideInstruction: OP_IPUT_WIDE sourceRegister COMMA instanceRegister COMMA instanceField; 498 | 499 | iputObjectInstruction: OP_IPUT_OBJECT sourceRegister COMMA instanceRegister COMMA instanceField; 500 | 501 | iputBooleanInstruction: OP_IPUT_BOOLEAN sourceRegister COMMA instanceRegister COMMA instanceField; 502 | 503 | iputByteInstruction: OP_IPUT_BYTE sourceRegister COMMA instanceRegister COMMA instanceField; 504 | 505 | iputCharInstruction: OP_IPUT_CHAR sourceRegister COMMA instanceRegister COMMA instanceField; 506 | 507 | iputShortInstruction: OP_IPUT_SHORT sourceRegister COMMA instanceRegister COMMA instanceField; 508 | 509 | 510 | addIntInstruction: OP_ADD_INT targetRegister COMMA leftRegister COMMA rightRegister; 511 | 512 | subIntInstruction: OP_SUB_INT targetRegister COMMA leftRegister COMMA rightRegister; 513 | 514 | mulIntInstruction: OP_MUL_INT targetRegister COMMA leftRegister COMMA rightRegister; 515 | 516 | divIntInstruction: OP_DIV_INT targetRegister COMMA leftRegister COMMA rightRegister; 517 | 518 | remIntInstruction: OP_REM_INT targetRegister COMMA leftRegister COMMA rightRegister; 519 | 520 | andIntInstruction: OP_AND_INT targetRegister COMMA leftRegister COMMA rightRegister; 521 | 522 | orIntInstruction: OP_OR_INT targetRegister COMMA leftRegister COMMA rightRegister; 523 | 524 | xorIntInstruction: OP_XOR_INT targetRegister COMMA leftRegister COMMA rightRegister; 525 | 526 | shlIntInstruction: OP_SHL_INT targetRegister COMMA leftRegister COMMA rightRegister; 527 | 528 | shrIntInstruction: OP_SHR_INT targetRegister COMMA leftRegister COMMA rightRegister; 529 | 530 | ushrIntInstruction: OP_USHR_INT targetRegister COMMA leftRegister COMMA rightRegister; 531 | 532 | rsubIntInstruction: OP_RSUB_INT targetRegister COMMA leftRegister COMMA rightRegister; 533 | 534 | addLongInstruction: OP_ADD_LONG targetRegister COMMA leftRegister COMMA rightRegister; 535 | 536 | subLongInstruction: OP_SUB_LONG targetRegister COMMA leftRegister COMMA rightRegister; 537 | 538 | mulLongInstruction: OP_MUL_LONG targetRegister COMMA leftRegister COMMA rightRegister; 539 | 540 | divLongInstruction: OP_DIV_LONG targetRegister COMMA leftRegister COMMA rightRegister; 541 | 542 | remLongInstruction: OP_REM_LONG targetRegister COMMA leftRegister COMMA rightRegister; 543 | 544 | andLongInstruction: OP_AND_LONG targetRegister COMMA leftRegister COMMA rightRegister; 545 | 546 | orLongInstruction: OP_OR_LONG targetRegister COMMA leftRegister COMMA rightRegister; 547 | 548 | xorLongInstruction: OP_XOR_LONG targetRegister COMMA leftRegister COMMA rightRegister; 549 | 550 | shlLongInstruction: OP_SHL_LONG targetRegister COMMA leftRegister COMMA rightRegister; 551 | 552 | shrLongInstruction: OP_SHR_LONG targetRegister COMMA leftRegister COMMA rightRegister; 553 | 554 | ushrLongInstruction: OP_USHR_LONG targetRegister COMMA leftRegister COMMA rightRegister; 555 | 556 | addFloatInstruction: OP_ADD_FLOAT targetRegister COMMA leftRegister COMMA rightRegister; 557 | 558 | subFloatInstruction: OP_SUB_FLOAT targetRegister COMMA leftRegister COMMA rightRegister; 559 | 560 | mulFloatInstruction: OP_MUL_FLOAT targetRegister COMMA leftRegister COMMA rightRegister; 561 | 562 | divFloatInstruction: OP_DIV_FLOAT targetRegister COMMA leftRegister COMMA rightRegister; 563 | 564 | remFloatInstruction: OP_REM_FLOAT targetRegister COMMA leftRegister COMMA rightRegister; 565 | 566 | addDoubleInstruction: OP_ADD_DOUBLE targetRegister COMMA leftRegister COMMA rightRegister; 567 | 568 | subDoubleInstruction: OP_SUB_DOUBLE targetRegister COMMA leftRegister COMMA rightRegister; 569 | 570 | mulDoubleInstruction: OP_MUL_DOUBLE targetRegister COMMA leftRegister COMMA rightRegister; 571 | 572 | divDoubleInstruction: OP_DIV_DOUBLE targetRegister COMMA leftRegister COMMA rightRegister; 573 | 574 | remDoubleInstruction: OP_REM_DOUBLE targetRegister COMMA leftRegister COMMA rightRegister; 575 | 576 | addIntLit16Instruction: OP_ADD_INT_LIT16 targetRegister COMMA leftRegister COMMA numericLiteral; 577 | 578 | mulIntLit16Instruction: OP_MUL_INT_LIT16 targetRegister COMMA leftRegister COMMA numericLiteral; 579 | 580 | divIntLit16Instruction: OP_DIV_INT_LIT16 targetRegister COMMA leftRegister COMMA numericLiteral; 581 | 582 | remIntLit16Instruction: OP_REM_INT_LIT16 targetRegister COMMA leftRegister COMMA numericLiteral; 583 | 584 | andIntLit16Instruction: OP_AND_INT_LIT16 targetRegister COMMA leftRegister COMMA numericLiteral; 585 | 586 | orIntLit16Instruction: OP_OR_INT_LIT16 targetRegister COMMA leftRegister COMMA numericLiteral; 587 | 588 | xorIntLit16Instruction: OP_XOR_INT_LIT16 targetRegister COMMA leftRegister COMMA numericLiteral; 589 | 590 | 591 | addIntLit8Instruction: OP_ADD_INT_LIT8 targetRegister COMMA leftRegister COMMA numericLiteral; 592 | 593 | rsubIntLit8Instruction: OP_RSUB_INT_LIT8 targetRegister COMMA leftRegister COMMA numericLiteral; 594 | 595 | mulIntLit8Instruction: OP_MUL_INT_LIT8 targetRegister COMMA leftRegister COMMA numericLiteral; 596 | 597 | divIntLit8Instruction: OP_DIV_INT_LIT8 targetRegister COMMA leftRegister COMMA numericLiteral; 598 | 599 | remIntLit8Instruction: OP_REM_INT_LIT8 targetRegister COMMA leftRegister COMMA numericLiteral; 600 | 601 | andIntLit8Instruction: OP_AND_INT_LIT8 targetRegister COMMA leftRegister COMMA numericLiteral; 602 | 603 | orIntLit8Instruction: OP_OR_INT_LIT8 targetRegister COMMA leftRegister COMMA numericLiteral; 604 | 605 | xorIntLit8Instruction: OP_XOR_INT_LIT8 targetRegister COMMA leftRegister COMMA numericLiteral; 606 | 607 | shlIntLit8Instruction: OP_SHL_INT_LIT8 targetRegister COMMA leftRegister COMMA numericLiteral; 608 | 609 | shrIntLit8Instruction: OP_SHR_INT_LIT8 targetRegister COMMA leftRegister COMMA numericLiteral; 610 | 611 | ushrIntLit8Instruction: OP_USHR_INT_LIT8 targetRegister COMMA leftRegister COMMA numericLiteral; 612 | 613 | newInstanceType: referenceType; 614 | 615 | newInstanceInstruction: OP_NEW_INSTANCE targetRegister COMMA newInstanceType; 616 | 617 | checkCastType: referenceOrArrayType; 618 | 619 | checkCastInstruction: OP_CHECK_CAST targetRegister COMMA checkCastType; 620 | 621 | arrayLengthInstruction: OP_ARRAY_LENGTH targetRegister COMMA arrayRegister; 622 | 623 | arrayElementType: nonVoidType; 624 | 625 | arrayElementRegisterRange: registerRange; 626 | 627 | arrayElementRegisters: registerList; 628 | 629 | filledNewArrayRangeInstruction: OP_FILLED_NEW_ARRAY_RANGE arrayElementRegisterRange COMMA arrayElementType; 630 | 631 | filledNewArrayInstruction: OP_FILLED_NEW_ARRAY arrayElementRegisters COMMA arrayElementType; 632 | 633 | filledArrayDataLabel: label; 634 | 635 | fillArrayDataInstruction: OP_FILL_ARRAY_DATA targetRegister COMMA filledArrayDataLabel; 636 | 637 | checkInstanceType: nonVoidType; 638 | 639 | instanceOfInstruction: OP_INSTANCE_OF targetRegister COMMA instanceRegister COMMA checkInstanceType; 640 | 641 | arraySizeRegister: registerIdentifier; 642 | 643 | newArrayInstruction: OP_NEW_ARRAY targetRegister COMMA arraySizeRegister COMMA arrayElementType; 644 | 645 | packedSwitchRegister: registerIdentifier; 646 | 647 | packedSwitchLabel: label; 648 | 649 | sparseSwitchRegister: registerIdentifier; 650 | 651 | sparseSwitchLabel: label; 652 | 653 | packedSwitchInstruction: OP_PACKED_SWITCH packedSwitchRegister COMMA packedSwitchLabel; 654 | 655 | sparseSwitchInstruction: OP_SPARSE_SWITCH sparseSwitchRegister COMMA sparseSwitchLabel; 656 | 657 | invokePolymorphicInstruction: OP_INVOKE_POLYMORPHIC; 658 | 659 | invokePolymorphicRangeInstruction: OP_INVOKE_POLYMORPHIC_RANGE; 660 | 661 | invokeCustomInstruction: OP_INVOKE_CUSTOM; 662 | 663 | invokeCustomRangeInstruction: OP_INVOKE_CUSTOM_RANGE; 664 | 665 | invokeConstMethodHandleInstruction: OP_CONST_METHOD_HANDLE; 666 | 667 | invokeConstMethodTypeInstruction: OP_CONST_METHOD_TYPE; 668 | 669 | binaryInstruction: 670 | filledNewArrayRangeInstruction 671 | | filledNewArrayInstruction 672 | | fillArrayDataInstruction 673 | | arrayLengthInstruction 674 | 675 | | packedSwitchInstruction 676 | | sparseSwitchInstruction 677 | 678 | | newInstanceInstruction 679 | | checkCastInstruction 680 | 681 | | moveInstruction 682 | | moveFrom16Instruction 683 | | move16Instruction 684 | | moveWideInstruction 685 | | moveWideFrom16Instruction 686 | | moveWide16Instruction 687 | | moveObjectInstruction 688 | | moveObjectFrom16Instruction 689 | | moveObject16Instruction 690 | 691 | | constInstruction 692 | | const4Instruction 693 | | const16Instruction 694 | | constHigh16Instruction 695 | | constWide16Instruction 696 | | constWide32Instruction 697 | | constWideInstruction 698 | | constWideHigh16Instruction 699 | 700 | | constString 701 | | constStringJumbo 702 | | constClass 703 | 704 | | sGetInstruction 705 | | sGetWideInstruction 706 | | sGetObjectInstruction 707 | | sGetBooleanInstruction 708 | | sGetByteInstruction 709 | | sGetCharInstruction 710 | | sGetShortInstruction 711 | 712 | | sPutInstruction 713 | | sPutWideInstruction 714 | | sPutObjectInstruction 715 | | sPutBooleanInstruction 716 | | sPutByteInstruction 717 | | sPutCharInstruction 718 | | sPutShortInstruction 719 | 720 | | invokeVirtualInstruction 721 | | invokeSuperInstruction 722 | | invokeDirectInstruction 723 | | invokeStaticInstruction 724 | | invokeInterfaceInstruction 725 | 726 | | invokeVirtualRangeInstruction 727 | | invokeSuperRangeInstruction 728 | | invokeDirectRangeInstruction 729 | | invokeStaticRangeInstruction 730 | | invokeInterfaceRangeInstruction 731 | 732 | | intToLongInstruction 733 | | intToFloatInstruction 734 | | intToDoubleInstruction 735 | | longToIntInstruction 736 | | longToFloatInstruction 737 | | longToDoubleInstruction 738 | | floatToIntInstruction 739 | | floatToLongInstruction 740 | | floatToDoubleInstruction 741 | | doubleToIntInstruction 742 | | doubleToLongInstruction 743 | | doubleToFloatInstruction 744 | | intToByteInstruction 745 | | intToCharInstruction 746 | | intToShortInstruction 747 | 748 | | ifEqzInstruction 749 | | ifNezInstruction 750 | | ifLtzInstruction 751 | | ifGezInstruction 752 | | ifGtzInstruction 753 | | ifLezInstruction 754 | 755 | | negIntInstruction 756 | | notIntInstruction 757 | | negLongInstruction 758 | | notLongInstruction 759 | | negFloatInstruction 760 | | negDoubleInstruction 761 | 762 | | ifEqInstruction 763 | | ifNeInstruction 764 | | ifLtInstruction 765 | | ifGeInstruction 766 | | ifGtInstruction 767 | | ifLeInstruction 768 | 769 | | addInt2addrInstruction 770 | | subInt2addrInstruction 771 | | mulInt2addrInstruction 772 | | divInt2addrInstruction 773 | | remInt2addrInstruction 774 | | andInt2addrInstruction 775 | | orInt2addrInstruction 776 | | xorInt2addrInstruction 777 | | shlInt2addrInstruction 778 | | shrInt2addrInstruction 779 | | ushrInt2addrInstruction 780 | | addLong2addrInstruction 781 | | subLong2addrInstruction 782 | | mulLong2addrInstruction 783 | | divLong2addrInstruction 784 | | remLong2addrInstruction 785 | | andLong2addrInstruction 786 | | orLong2addrInstruction 787 | | xorLong2addrInstruction 788 | | shlLong2addrInstruction 789 | | shrLong2addrInstruction 790 | | ushrLong2addrInstruction 791 | | addFloat2addrInstruction 792 | | subFloat2addrInstruction 793 | | mulFloat2addrInstruction 794 | | divFloat2addrInstruction 795 | | remFloat2addrInstruction 796 | | addDouble2addrInstruction 797 | | subDouble2addrInstruction 798 | | mulDouble2addrInstruction 799 | | divDouble2addrInstruction 800 | | remDouble2addrInstruction 801 | 802 | | cmplFloatInstruction 803 | | cmpgFloatInstruction 804 | | cmplDoubleInstruction 805 | | cmpgDoubleInstruction 806 | | cmpLongInstruction 807 | ; 808 | 809 | ternaryInstruction: 810 | invokePolymorphicInstruction 811 | | invokePolymorphicRangeInstruction 812 | | invokeCustomInstruction 813 | | invokeCustomRangeInstruction 814 | | invokeConstMethodHandleInstruction 815 | | invokeConstMethodTypeInstruction 816 | 817 | | instanceOfInstruction 818 | | newArrayInstruction 819 | 820 | | agetInstruction 821 | | agetWideInstruction 822 | | agetObjectInstruction 823 | | agetBooleanInstruction 824 | | agetByteInstruction 825 | | agetCharInstruction 826 | | agetShortInstruction 827 | 828 | | aputInstruction 829 | | aputWideInstruction 830 | | aputObjectInstruction 831 | | aputBooleanInstruction 832 | | aputByteInstruction 833 | | aputCharInstruction 834 | | aputShortInstruction 835 | 836 | | igetInstruction 837 | | igetWideInstruction 838 | | igetObjectInstruction 839 | | igetBooleanInstruction 840 | | igetByteInstruction 841 | | igetCharInstruction 842 | | igetShortInstruction 843 | 844 | | iputInstruction 845 | | iputWideInstruction 846 | | iputObjectInstruction 847 | | iputBooleanInstruction 848 | | iputByteInstruction 849 | | iputCharInstruction 850 | | iputShortInstruction 851 | 852 | | addIntInstruction 853 | | subIntInstruction 854 | | mulIntInstruction 855 | | divIntInstruction 856 | | remIntInstruction 857 | | andIntInstruction 858 | | orIntInstruction 859 | | xorIntInstruction 860 | | shlIntInstruction 861 | | shrIntInstruction 862 | | ushrIntInstruction 863 | | rsubIntInstruction 864 | 865 | | addLongInstruction 866 | | subLongInstruction 867 | | mulLongInstruction 868 | | divLongInstruction 869 | | remLongInstruction 870 | | andLongInstruction 871 | | orLongInstruction 872 | | xorLongInstruction 873 | | shlLongInstruction 874 | | shrLongInstruction 875 | | ushrLongInstruction 876 | 877 | | addFloatInstruction 878 | | subFloatInstruction 879 | | mulFloatInstruction 880 | | divFloatInstruction 881 | | remFloatInstruction 882 | 883 | | addDoubleInstruction 884 | | subDoubleInstruction 885 | | mulDoubleInstruction 886 | | divDoubleInstruction 887 | | remDoubleInstruction 888 | 889 | | addIntLit16Instruction 890 | | mulIntLit16Instruction 891 | | divIntLit16Instruction 892 | | remIntLit16Instruction 893 | | andIntLit16Instruction 894 | | orIntLit16Instruction 895 | | xorIntLit16Instruction 896 | 897 | | addIntLit8Instruction 898 | | rsubIntLit8Instruction 899 | | mulIntLit8Instruction 900 | | divIntLit8Instruction 901 | | remIntLit8Instruction 902 | | andIntLit8Instruction 903 | | orIntLit8Instruction 904 | | xorIntLit8Instruction 905 | | shlIntLit8Instruction 906 | | shrIntLit8Instruction 907 | | ushrIntLit8Instruction 908 | ; 909 | 910 | instruction: 911 | ternaryInstruction 912 | | binaryInstruction 913 | 914 | | returnVoidInstruction 915 | | nopInstruction 916 | 917 | | gotoInstruction 918 | | goto16Instruction 919 | | goto32Instruction 920 | 921 | | moveResultInstruction 922 | | moveResultWideInstruction 923 | | moveResultObjectInstruction 924 | | moveExceptionInstruction 925 | 926 | | returnInstruction 927 | | returnWideInstruction 928 | | returnObjectInstruction 929 | 930 | | monitorEnterInstruction 931 | | monitorExitInstruction 932 | | throwInstruction 933 | ; 934 | 935 | methodInvocationTarget: referenceOrArrayType ARROW methodSignature; 936 | 937 | fieldInvocationTarget: referenceOrArrayType ARROW fieldNameAndType; 938 | 939 | // Fields and methods 940 | 941 | fieldName: identifier; 942 | 943 | fieldType: anyType; 944 | 945 | fieldNameAndType: fieldName COLON fieldType; 946 | 947 | fieldDirective: FIELD_DIRECTIVE fieldModifier* fieldNameAndType (ASSIGN assignableValue)?; 948 | 949 | className: referenceType; 950 | 951 | classDirective: CLASS_DIRECTIVE classModifier* className; 952 | 953 | superName: referenceType; 954 | 955 | superDirective: SUPER_DIRECTIVE superName; 956 | 957 | sourceName: stringLiteral; 958 | 959 | sourceDirective: SOURCE_DIRECTIVE sourceName; 960 | 961 | methodIdentifier: identifier | LT identifier GT; 962 | 963 | methodReturnType: anyType; 964 | 965 | methodParameterType: (nonVoidType | methodParameterLiteral); 966 | 967 | methodArguments: methodParameterType+; 968 | 969 | methodSignature: methodIdentifier LPAREN methodArguments? RPAREN methodReturnType; 970 | 971 | methodDeclaration: methodModifier* methodSignature; 972 | 973 | annotationScope: IDENTIFIER; 974 | 975 | annotationType: referenceType; 976 | 977 | annotationFieldValue: (assignableValue | referenceType); 978 | 979 | annotationValueScoped: LBRACE (annotationFieldValue (COMMA annotationFieldValue)*)? RBRACE; 980 | 981 | annotationField: fieldName ASSIGN (annotationFieldValue|annotationValueScoped); 982 | 983 | annotationDirective: ANNOTATION_DIRECTIVE annotationScope annotationType annotationField* ANNOTATION_END_DIRECTIVE; 984 | 985 | locaDirectiveVariableName: stringLiteral; 986 | 987 | localDirectiveType: nonVoidType; 988 | 989 | localDirectiveGenericHint: stringLiteral; 990 | 991 | localDirectiveRegister: registerIdentifier; 992 | 993 | localDirective: LOCAL_DIRECTIVE localDirectiveRegister COMMA locaDirectiveVariableName (COLON localDirectiveType)? (COMMA localDirectiveGenericHint)?; 994 | 995 | localEndDirective: LOCAL_END_DIRECTIVE registerIdentifier; 996 | 997 | localRestartDirective: RESTART_LOCAL_DIRECTIVE registerIdentifier; 998 | 999 | lineLabel: label; 1000 | 1001 | methodBodyStatement: 1002 | registersDirective 1003 | | localsDirective 1004 | | paramDirective 1005 | | lineDirective 1006 | | instruction 1007 | | lineLabel 1008 | | catchDirective 1009 | | catchAllDirective 1010 | | annotationDirective 1011 | | localDirective 1012 | | localEndDirective 1013 | | localRestartDirective 1014 | | packedSwitchDirective 1015 | | arrayDataDirective 1016 | | sparseSwitchDirective 1017 | ; 1018 | 1019 | methodBody: methodBodyStatement+; 1020 | 1021 | packedSwitchIdent: numericLiteral; 1022 | 1023 | packedSwitchDirectiveLabel: label; 1024 | 1025 | packedSwitchDirectiveLabels:packedSwitchDirectiveLabel+; 1026 | 1027 | packedSwitchDirective: PACKED_SWITCH_DIRECTIVE packedSwitchIdent packedSwitchDirectiveLabels? PACKED_SWITCH_END_DIRECTIVE; 1028 | 1029 | methodDirective: METHOD_DIRECTIVE methodDeclaration methodBody? METHOD_END_DIRECTIVE; 1030 | 1031 | registersDirective: REGISTERS_DIRECTIVE numericLiteral; 1032 | 1033 | localsDirective: LOCALS_DIRECTIVE numericLiteral; 1034 | 1035 | simpleParamDirective: COMMA stringLiteral; 1036 | 1037 | extendedParamDirective: annotationDirective* PARAM_END_DIRECTIVE; 1038 | 1039 | paramDirective: PARAM_DIRECTIVE registerIdentifier (extendedParamDirective | simpleParamDirective); 1040 | 1041 | lineDirective: LINE_DIRECTIVE numericLiteral; 1042 | 1043 | catchFromLabel: label; 1044 | 1045 | catchToLabel: label; 1046 | 1047 | catchGotoLabel: label; 1048 | 1049 | catchExceptionType: referenceType; 1050 | 1051 | catchDirective: CATCH_DIRECTIVE catchExceptionType LBRACE catchFromLabel DOT DOT catchToLabel RBRACE catchGotoLabel; 1052 | 1053 | catchAllDirective: CATCHALL_DIRECTIVE LBRACE catchFromLabel DOT DOT catchToLabel RBRACE catchGotoLabel; 1054 | 1055 | arrayDataDirective: ARRAY_DATA_DIRECTIVE numericLiteral arrayDataEntry* ARRAY_DATA_END_DIRECTIVE; 1056 | 1057 | arrayDataEntry: numericLiteral IDENTIFIER?; 1058 | 1059 | sparseSwitchDirectiveValue: numericLiteral ARROW label; 1060 | 1061 | sparseSwitchDirective: SPARSE_SWITCH_DIRECTIVE sparseSwitchDirectiveValue* SPARSE_SWITCH_END_DIRECTIVE; 1062 | 1063 | statement: 1064 | classDirective 1065 | | superDirective 1066 | | sourceDirective 1067 | | fieldDirective 1068 | | methodDirective 1069 | ; 1070 | 1071 | parse: 1072 | statement+ 1073 | ; --------------------------------------------------------------------------------