1/* 2 * parser.cup - Java CUP file containing LALR(1) grammar for DASM 3 */ 4 5package dasm; 6 7import java_cup.runtime.*; 8 9import dasm.tokens.number_token; 10import dasm.tokens.relative_number_token; 11import dasm.tokens.variant_token; 12 13action code {: 14 int access_val; 15 public DAsm dAsm; 16 public Scanner scanner; 17 public boolean isInterface; 18:}; 19 20parser code {: 21 22 public boolean isInterface; 23 public Scanner scanner; 24 public DAsm dAsm; 25 26 public void report_error(String message, Object info) { 27 if(info != null) 28 dAsm.report_error("Warning: " + message + "(" + info.toString() + ")"); 29 else 30 dAsm.report_error("Warning: " + message); 31 } 32 33 public void report_fatal_error(String message, Object info) { 34 if(info != null) 35 dAsm.report_error("Error: " + message + "(" + info.toString() + ")"); 36 else 37 dAsm.report_error("Error: " + message); 38 } 39 40 parser(DAsm dAsm, Scanner scanner) { 41 super(); 42 43 this.scanner = scanner; 44 this.dAsm = dAsm; 45 } 46:}; 47 48init with {: 49 action_obj.scanner = scanner; 50 action_obj.dAsm = dAsm; 51:}; 52 53scan with {: 54 return scanner.next_token(); 55:}; 56 57 58 59/* Terminals (tokens returned by the scanner). */ 60terminal token 61 // Directives (words beginning with a '.') 62 DCATCH, DCLASS, DEND, DFIELD, DLIMIT, DLINE, DMETHOD, DSET, DSUPER, 63 DSOURCE, DTHROWS, DVAR, DIMPLEMENTS, DINTERFACE, DBYTECODE, DDEBUG, 64 DENCLOSING, DSIGNATURE, DATTRIBUTE, DDEPRECATED, DINNER, 65 DANNOTATION, 66 67 // keywords for directives 68 USING, IS, FROM, METHOD, SIGNATURE, REGS, FIELD, CLASS, 69 TO, INNER, OUTER, VISIBLE, INVISIBLE, VISIBLEPARAM, INVISIBLEPARAM, 70 71 // access types 72 ABSTRACT, FINAL, INTERFACE, NATIVE, PRIVATE, PROTECTED, PUBLIC, STATIC, 73 SYNCHRONIZED, DECLARED_SYNCHRONIZED, TRANSIENT, VOLATILE, 74 // added these for java 1.5 compliance : 75 ANNOTATION, ENUM, BRIDGE, VARARGS, STRICT, SYNTHETIC, 76 // complex instructions 77 FILL_ARRAY_DATA, FILL_ARRAY_DATA_END, 78 PACKED_SWITCH, PACKED_SWITCH_END, 79 SPARSE_SWITCH, SPARSE_SWITCH_END, 80 DEFAULT, 81 82 // special symbols 83 EQ, SEP, COLON 84 ; 85 86terminal str_token Str, Word, Insn; 87terminal int_token Int; 88terminal number_token Num; 89terminal relative_number_token Relative; 90 91non terminal str_token classname, inner_name, inner_inner, inner_outer, optional_signature; 92non terminal variant_token optional_default, item, any_item; 93 94/* Non terminals */ 95non terminal symbol 96 access_item, access_items, access_list, catch_expr, class_spec, 97 complex_instruction, defmethod, directive, endmethod, field_list, 98 field_spec, fields, instruction, implements, implements_list, implements_spec, 99 dasm_file, dasm_file_classes, dasm_file_class, label, limit_expr, 100 method_list, 101 method_spec, methods, set_expr, simple_instruction, source_spec, 102 statement, statements, stmnt, super_spec, line_expr, 103 throws_expr, var_expr, dex_version_spec, 104 enclosing_spec, signature_spec, signature_expr, dasm_header, 105 deprecated_spec, deprecated_expr, 106 generic_attributes, generic_list, generic_spec, generic_expr, 107 field_start, endfield, field_exts, field_ext_list, field_ext_expr, 108 inners, inner_list, inner_spec, 109 fa_data, fa_data_args, fa_data_list, fa_data_entry, fa_data_end, 110 ps_table, ps_table_args, ps_table_list, ps_table_entry, ps_table_end, 111 ss_table, ss_table_args, ss_table_list, ss_table_entry, ss_table_end, 112 113 // used for Annotation attributes : 114 annotations, ann_cls_list, ann_cls_spec, endannotation, ann_cls_expr, 115 ann_clf_expr, ann_met_expr, ann_arglist, ann_arg_list, ann_arg_spec, 116 ann_def_spec, ann_def_val, ann_value_items, ann_value, ann_def_expr, 117 ann_arg_expr, ann_nest, endannotationsep, ann_ann_value, ann_ann_list, 118 ann_value_list 119 120; 121 122non terminal int_token access; 123 124/* The grammar */ 125 126dasm_file ::= dasm_file_classes; 127 128dasm_file_classes ::= dasm_file_classes dasm_file_class | dasm_file_class; 129 130dasm_file_class ::= 131 dasm_header 132 inners 133 fields 134 methods 135; 136 137dasm_header ::= 138 dex_version_spec 139 source_spec 140 class_spec 141 super_spec 142 implements 143 signature_spec 144 enclosing_spec 145 deprecated_spec 146 annotations 147 generic_attributes 148 {: dAsm.endHeader(); :} 149; 150 151/* ========== Dex version specification ========== */ 152 153dex_version_spec ::= 154 DBYTECODE Num:n SEP 155 {: dAsm.setVersion(n.number_val); :} 156 | 157 /* nothing */ 158; 159 160/* ========== Source specification ========== */ 161 162source_spec ::= 163 DSOURCE Str:s SEP 164 {: dAsm.setSource(s.str_val); :} 165 | 166 DSOURCE Word:w SEP 167 {: dAsm.setSource(w.str_val); :} 168 | 169 /* nothing */ 170; 171 172 173/* ========== Class specification ========== */ 174 175class_spec ::= 176 DCLASS access:a classname:name SEP 177 {: isInterface = false; 178 dAsm.setClass(name.str_val, 179 (a.int_val)); :} 180 | 181 DINTERFACE access:a classname:name SEP 182 {: isInterface = true; 183 dAsm.setClass(name.str_val, 184 (a.int_val | 185 com.android.dx.rop.code.AccessFlags.ACC_INTERFACE)); :} 186; 187 188classname ::= Word:w 189 {: RESULT.str_val = Utils.convertDotsToSlashes(w.str_val); :} 190; 191 192access ::= 193 {: access_val = 0; :} 194 access_list 195 {: RESULT.int_val = access_val; :} 196; 197 198 199access_list ::= access_items | ; 200access_items ::= access_items access_item | access_item ; 201 202access_item ::= 203 PUBLIC {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_PUBLIC; :} 204 | 205 PRIVATE {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_PRIVATE; :} 206 | 207 PROTECTED {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_PROTECTED; :} 208 | 209 STATIC {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_STATIC; :} 210 | 211 FINAL {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_FINAL; :} 212 | 213 SYNCHRONIZED {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_SYNCHRONIZED; :} 214 | 215 VOLATILE {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_VOLATILE; :} 216 | 217 TRANSIENT {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_TRANSIENT; :} 218 | 219 NATIVE {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_NATIVE; :} 220 | 221 INTERFACE {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_INTERFACE; :} 222 | 223 ABSTRACT {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_ABSTRACT; :} 224 | 225 ANNOTATION {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_ANNOTATION; :} 226 | 227 ENUM {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_ENUM; :} 228 | 229 BRIDGE {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_BRIDGE; :} 230 | 231 VARARGS {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_VARARGS; :} 232 | 233 STRICT {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_STRICT; :} 234 | 235 SYNTHETIC {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_SYNTHETIC; :} 236 | 237 DECLARED_SYNCHRONIZED {: access_val |= com.android.dx.rop.code.AccessFlags.ACC_DECLARED_SYNCHRONIZED; :} 238; 239 240/* ========== Superclass specification ========== */ 241 242super_spec ::= 243 DSUPER classname:name SEP 244 {: dAsm.setSuperClass(name.str_val); :} 245 | 246 /* nothing */ 247 {: if(isInterface == false) 248 dAsm.setSuperClass("java/lang/Object"); 249 else 250 // Dalvik requires interfaces to have superclass 251 dAsm.setSuperClass("java/lang/Object"); :} 252; 253 254/* ========== Implements specification ========== */ 255 256implements ::= implements_list | /* empty */ ; 257 258implements_list ::= implements_list implements_spec | implements_spec ; 259 260implements_spec ::= DIMPLEMENTS classname:name SEP 261 {: dAsm.addInterface(name.str_val); :} 262; 263 264/* ========== Signature specification ========== */ 265 266signature_spec ::= 267 DSIGNATURE signature_expr SEP 268 | 269 /* nothing */ 270; 271 272signature_expr ::= Str:sig 273 {: dAsm.setSignature(sig.str_val); :} 274; 275 276/* ========== EnclosingMethod attribute specification ========== */ 277 278enclosing_spec ::= 279 DENCLOSING METHOD Word:w SEP 280 {: dAsm.setEnclosingMethod(w.str_val); :} 281 | 282 /* nothing */ 283; 284 285 286 287/* ========== Deprecated attribute ========== */ 288 289deprecated_spec ::= 290 DDEPRECATED deprecated_expr SEP 291 | 292 /* nothing */ 293; 294 295deprecated_expr ::= 296 {: /*dAsm.setDeprecated();*/dAsm.report_error("WARNING: @deprecated is not supported"); :} 297; 298 299 300/* ========== Annotation specification ========== */ 301annotations ::= ann_cls_list | 302 // empty 303 ; 304 305ann_cls_list ::= ann_cls_list ann_cls_spec | ann_cls_spec ; 306 307ann_cls_spec ::= ann_cls_expr ann_arglist endannotationsep ; 308 309endannotationsep ::= endannotation SEP ; 310 311endannotation ::= DEND ANNOTATION 312 {: //TODO: NOT SUPPORTED dAsm.endAnnotation(); 313 dAsm.report_error("WARNING: Annotations are not supported"); :} 314; 315 316ann_cls_expr ::= DANNOTATION ann_clf_expr ; 317 318ann_clf_expr ::= 319 VISIBLE classname:name SEP 320 {: //TODO: NOT SUPPORTED dAsm.addAnnotation(true, name.str_val); 321 dAsm.report_error("WARNING: Annotations are not supported"); :} 322 | 323 INVISIBLE classname:name SEP 324 {: //TODO: NOT SUPPORTED dAsm.addAnnotation(false, name.str_val); 325 dAsm.report_error("WARNING: Annotations are not supported"); :} 326; 327ann_met_expr ::= 328 VISIBLE classname:name SEP 329 {: //TODO: NOT SUPPORTED dAsm.addAnnotation(true, name.str_val); 330 dAsm.report_error("WARNING: Annotations are not supported"); :} 331 | 332 INVISIBLE classname:name SEP 333 {: //TODO: NOT SUPPORTED dAsm.addAnnotation(false, name.str_val); 334 dAsm.report_error("WARNING: Annotations are not supported"); :} 335 | 336 VISIBLEPARAM Int:n classname:name SEP 337 {: //TODO: NOT SUPPORTED dAsm.addAnnotation(true, name.str_val, n.int_val); 338 dAsm.report_error("WARNING: Annotations are not supported"); :} 339 | 340 INVISIBLEPARAM Int:n classname:name SEP 341 {: //TODO: NOT SUPPORTED dAsm.addAnnotation(false, name.str_val, n.int_val); 342 dAsm.report_error("WARNING: Annotations are not supported"); :} 343; 344 345ann_arglist ::= ann_arg_list | 346 // empty 347; 348 349ann_arg_list ::= ann_arg_list ann_arg_spec | ann_arg_spec ; 350 351ann_arg_spec ::= ann_arg_expr EQ ann_value_list ; 352 353ann_arg_expr ::= 354 Word:n Word:dsc 355 {: //TODO: NOT SUPPORTED dAsm.addAnnotationField(n.str_val, dsc.str_val, null); 356 dAsm.report_error("WARNING: Annotations are not supported"); :} 357 | 358 Word:n Word:dsc Word:sub 359 {: //TODO: NOT SUPPORTED dAsm.addAnnotationField(n.str_val, dsc.str_val, sub.str_val); 360 dAsm.report_error("WARNING: Annotations are not supported"); :} 361; 362 363ann_def_spec ::= DEFAULT SEP 364 {: //TODO: NOT SUPPORTED dAsm.addAnnotation(); 365 dAsm.report_error("WARNING: Annotations are not supported"); :} 366; 367 368ann_value_list ::= ann_value_items SEP | ann_ann_list ; 369 370ann_value_items ::= ann_value_items ann_value | ann_value ; 371 372ann_value ::= any_item:v 373 {: //TODO: NOT SUPPORTED dAsm.addAnnotationValue(v.variant_val); 374 dAsm.report_error("WARNING: Annotations are not supported"); :} 375; 376ann_ann_list ::= ann_ann_list ann_ann_value | ann_ann_value ; 377 378ann_ann_value ::= DANNOTATION ann_nest ann_arglist endannotationsep ; 379 380ann_nest ::= SEP 381 {: //TODO: NOT SUPPORTED dAsm.nestAnnotation(); 382 dAsm.report_error("WARNING: Annotations are not supported"); :} 383; 384 385ann_def_val ::= ann_def_expr EQ ann_value_list ; 386 387ann_def_expr ::= 388 Word:dsc 389 {: //TODO: NOT SUPPORTED dAsm.addAnnotationField(null, dsc.str_val, null); 390 dAsm.report_error("WARNING: Annotations are not supported"); :} 391 | 392 Word:dsc Word:sub 393 {: //TODO: NOT SUPPORTED dAsm.addAnnotationField(null, dsc.str_val, sub.str_val); 394 dAsm.report_error("WARNING: Annotations are not supported"); :} 395; 396 397 398 399/* ========== Generic attributes specification ========== */ 400 401generic_attributes ::= generic_list | /* empty */ ; 402 403generic_list ::= generic_list generic_spec | generic_spec ; 404 405generic_spec ::= DATTRIBUTE generic_expr SEP ; 406 407generic_expr ::= Word:name Str:file 408 {: dAsm.addGenericAttr(name.str_val, file.str_val); :} 409; 410 411 412/* ========== Fields ========== */ 413 414fields ::= field_list | /* empty */ ; 415 416field_list ::= field_list field_spec | field_spec ; 417 418field_spec ::= 419 DFIELD access:a Word:name Word:desc SIGNATURE Str:sig optional_default:v SEP 420 {: dAsm.addField((short)a.int_val, name.str_val, desc.str_val, 421 sig.str_val, v.variant_val); :} 422 | 423 DFIELD access:a Word:name Word:desc optional_default:v SEP 424 {: dAsm.addField((short)a.int_val, name.str_val, desc.str_val, 425 null, v.variant_val); :} 426 | 427 DFIELD field_start field_exts endfield 428; 429 430// default value for a field 431optional_default ::= 432 EQ item:v 433 {: RESULT.variant_val = v.variant_val; :} 434 | 435 /* empty */ 436 {: RESULT.variant_val = null; :} 437; 438 439// multiline form of field description 440field_start ::= access:a Word:name Word:desc optional_default:v SEP 441 {: dAsm.beginField((short)a.int_val, name.str_val, 442 desc.str_val, v.variant_val); :} 443; 444 445endfield ::= DEND FIELD SEP 446 {: dAsm.endField(); :} 447; 448 449field_exts ::= field_ext_list | /* empty */ ; 450 451field_ext_list ::= field_ext_list field_ext_expr | field_ext_expr ; 452 453field_ext_expr ::= 454 DSIGNATURE signature_expr SEP 455 | 456 DATTRIBUTE generic_expr SEP 457 | 458 DDEPRECATED deprecated_expr SEP 459 | 460 DANNOTATION ann_clf_expr ann_arglist endannotationsep 461; 462 463 464// an item is an integer, a float/double/long, or a quoted string 465item ::= 466 Int:i {: RESULT.variant_val = new Integer(i.int_val); :} 467 | 468 Num:n {: RESULT.variant_val = n.number_val; :} 469 | 470 Str:s {: RESULT.variant_val = s.str_val; :} 471; 472// an item is any possible type 473any_item ::= 474 Word:w {: RESULT.variant_val = w.str_val; :} // for enum 475 | 476 item:v {: RESULT.variant_val = v.variant_val; :} 477; 478 479/* ========== Inner classes ========== */ 480inners ::= inner_list | 481 // empty 482; 483 484inner_list ::= inner_list inner_spec | inner_spec ; 485 486inner_spec ::= 487 DINNER CLASS access:a inner_name:n inner_inner:i inner_outer:o SEP 488 {: dAsm.addInner((short)a.int_val, 489 n.str_val, i.str_val, o.str_val); :} 490 | 491 DINNER INTERFACE access:a inner_name:n inner_inner:i inner_outer:o SEP 492 {: dAsm.addInner((short)(a.int_val | 493 com.android.dx.rop.code.AccessFlags.ACC_INTERFACE), 494 n.str_val, i.str_val, o.str_val); :} 495; 496 497inner_name ::= 498 Word:w 499 {: RESULT.str_val = w.str_val; :} 500 | 501 // empty 502 {: RESULT.str_val = null; :} 503; 504 505inner_inner ::= 506 INNER classname:w 507 {: RESULT.str_val = w.str_val; :} 508 | 509 // empty 510 {: RESULT.str_val = null; :} 511; 512 513inner_outer ::= 514 OUTER classname:w 515 {: RESULT.str_val = w.str_val; :} 516 | 517 // empty 518 {: RESULT.str_val = null; :} 519; 520 521 522/* ========== Methods ========== */ 523 524methods ::= method_list | /* empty */; 525 526method_list ::= method_list method_spec | method_spec ; 527 528method_spec ::= 529 defmethod 530 statements 531 endmethod 532 | 533 defmethod endmethod 534 ; 535 536defmethod ::= 537 DMETHOD access:i Word:name SEP 538 {: String split[] = Utils.getMethodSignatureFromString(name.str_val); 539 dAsm.newMethod(split[0], split[1], i.int_val); :} 540; 541 542endmethod ::= 543 DEND METHOD SEP 544 {: dAsm.endMethod(); :} 545; 546 547 548/* ========== Statements in a method ========== */ 549 550statements ::= statements statement | statement ; 551 552statement ::= 553 {: dAsm.setLine(scanner.token_line_num); :} 554 stmnt SEP 555; 556 557stmnt ::= 558 instruction 559 | 560 directive 561 | 562 error 563 | 564 label 565 | 566 /* empty */ 567; 568 569 570// label: 571label ::= 572 Word:label COLON 573 {: dAsm.plantLabel(label.str_val); :} 574 | 575 Int:label COLON instruction 576 {: dAsm.plantLabel(String.valueOf(label.int_val)); :} 577; 578 579// Directives (.catch, .set, .limit, etc.) 580 581directive ::= 582 DVAR var_expr 583 | 584 DLIMIT limit_expr 585 | 586 DLINE line_expr 587 | 588 DTHROWS throws_expr 589 | 590 DCATCH catch_expr 591 | 592 DSET set_expr 593 | 594 DSIGNATURE signature_expr 595 | 596 DATTRIBUTE generic_expr 597 | 598 DDEPRECATED deprecated_expr 599 | 600 DANNOTATION ann_met_expr ann_arglist endannotation 601 | 602 DANNOTATION ann_def_spec ann_def_val endannotation 603; 604 605 606// 607// .var <num> is <name> <desc> from StartLab to EndLab 608// .var <num> is <name> <desc> signature <sign> from StartLab to EndLab 609// 610var_expr ::= 611 Int:reg IS Word:name Word:desc optional_signature:sign FROM Word:slab TO Word:elab 612 {: dAsm.addVar(slab.str_val, elab.str_val, name.str_val, 613 desc.str_val, sign.str_val, reg.int_val); :} 614 | 615 Int:reg IS Word:name Word:desc optional_signature:sign 616 {: dAsm.addVar(null, null, name.str_val, desc.str_val, 617 sign.str_val, reg.int_val); :} 618 | 619 Int:reg IS Word:name Word:desc optional_signature:sign FROM Int:soff TO Int:eoff 620 {: dAsm.addVar(soff.int_val, eoff.int_val, name.str_val, 621 desc.str_val, sign.str_val, reg.int_val); :} 622; 623 624// optional signature specification for a .var 625optional_signature ::= 626 SIGNATURE Str:s 627 {: RESULT.str_val = s.str_val; :} 628 | 629 /* empty */ 630 {: RESULT.str_val = null; :} 631; 632 633 634// .limit regs <val> 635limit_expr ::= 636 REGS Int:v // .limit regs 637 {: dAsm.setRegsSize(v.int_val); :} 638 | 639 Word:w Int:v 640 {: dAsm.report_error(".limit expected \"regs\" , but got " 641 + w.str_val); :} 642; 643 644// .line <num> 645line_expr ::= Int:v 646 {: dAsm.addLine(v.int_val); :} 647; 648 649// .throws <class> 650throws_expr ::= classname:s 651 {: dAsm.addThrow(s.str_val); :} 652; 653 654// .catch <class> from <label1> to <label2> using <branchlab> 655catch_expr ::= 656 classname:aclass FROM Word:fromlab TO Word:tolab USING Word:branchlab 657 {: dAsm.addCatch(aclass.str_val, 658 fromlab.str_val, 659 tolab.str_val, 660 branchlab.str_val); :} 661 | 662 classname:aclass FROM Int:fromoff TO Int:tooff USING Int:branchoff 663 {: dAsm.addCatch(aclass.str_val, 664 fromoff.int_val, 665 tooff.int_val, 666 branchoff.int_val); :} 667; 668 669// .set <var> = <val> 670set_expr ::= 671 Word:name any_item:v 672 {: scanner.dict.put(name.str_val, v); :} 673; 674 675instruction ::= 676 simple_instruction 677 | 678 complex_instruction 679; 680 681// Various patterns of instruction: 682// instruction [<pattern>] 683simple_instruction ::= 684 /* Format: 10x */ 685 Insn:i 686 {: dAsm.addOpcode(i.str_val); :} 687 | 688 /* Format: 11x, 10t, 20t, 30t */ 689 Insn:i Word:n 690 {: dAsm.addOpcode(i.str_val, n.str_val); :} 691 | 692 /* Format: relative 10t, 20t, 30t */ 693 Insn:i Relative:n 694 {: dAsm.addRelativeGoto(i.str_val, n.int_val); :} 695 | 696 /* Format: 11n, 21s, 31i, 21h, 51l */ 697 Insn:i Word:n1 Num:n2 698 {: dAsm.addOpcode(i.str_val, n1.str_val, n2.number_val); :} 699 | 700 /* Format: same as above. Handles the case when last argument is integer */ 701 Insn:i Word:n1 Int:n2 702 {: dAsm.addOpcode(i.str_val, n1.str_val, new Integer(n2.int_val)); :} 703 | 704 /* Format: 12x, 22x, 32x, 21t, 21c (string@, type@), 31c, 35c, 3rc */ 705 Insn:i Word:n1 Word:n2 706 {: dAsm.addOpcode(i.str_val, n1.str_val, n2.str_val); :} 707 | 708 /* Format: relative 21t */ 709 Insn:i Word:n1 Relative:n2 710 {: dAsm.addRelativeGoto(i.str_val, n1.str_val, n2.int_val); :} 711 | 712 /* Format: 23x, 22t, 21c (field@), 22c */ 713 Insn:i Word:n1 Word:n2 Word:n3 714 {: dAsm.addOpcode(i.str_val, n1.str_val, n2.str_val, n3.str_val); :} 715 | 716 /* Format: relative 22t */ 717 Insn:i Word:n1 Word:n2 Relative:n3 718 {: dAsm.addRelativeGoto(i.str_val, n1.str_val, n2.str_val, n3.int_val); :} 719 | 720 /* Format: 22b, 22s */ 721 Insn:i Word:n1 Word:n2 Int:n3 722 {: dAsm.addOpcode(i.str_val, n1.str_val, n2.str_val, n3.int_val); :} 723 | 724 /* Format: 21c (string@) */ 725 Insn:i Word:n1 Str:n2 726 {: dAsm.addOpcode(i.str_val, n1.str_val, n2.str_val); :} 727 | 728 /* Format: 22c (field@)*/ 729 Insn:i Word:n1 Word:n2 Word:n3 Word:n4 730 {: dAsm.addOpcode(i.str_val, n1.str_val, n2.str_val, n3.str_val, n4.str_val); :} 731 ; 732 733// complex (multiline) instructions 734// fill-array-data <data> 735// packed-switch <table> 736// sparse-switch <table> 737 738complex_instruction ::= 739 FILL_ARRAY_DATA fa_data 740 | 741 PACKED_SWITCH ps_table 742 | 743 SPARSE_SWITCH ss_table 744; 745 746// fill-array-data register type 747// <value1> 748// ... 749// <valueN> 750// fill-array-data-end 751fa_data ::= 752 fa_data_args 753 fa_data_list 754 fa_data_end 755; 756 757fa_data_args ::= 758 Word:r Word:t SEP // <register> <type> 759 {: dAsm.newFillArrayData(r.str_val, t.str_val); :} 760; 761 762fa_data_list ::= fa_data_list fa_data_entry | fa_data_entry ; 763 764fa_data_entry ::= 765 Num:data SEP 766 {: dAsm.addFillArrayData(data.number_val); :} 767 | 768 Int:data SEP 769 {: dAsm.addFillArrayData(new Integer(data.int_val)); :} 770; 771 772fa_data_end ::= 773 FILL_ARRAY_DATA_END 774 {: dAsm.endFillArrayData(); :} 775; 776 777 778// packed-switch register first_key 779// <target1> 780// ... 781// <targetN> 782// packed-switch-end 783ps_table ::= 784 ps_table_args 785 ps_table_list 786 ps_table_end 787; 788 789ps_table_args ::= 790 Word:r Int:k SEP // <register> <first_key> 791 {: dAsm.newPackedSwitch(r.str_val, k.int_val); :} 792; 793 794ps_table_list ::= ps_table_list ps_table_entry | ps_table_entry ; 795 796ps_table_entry ::= 797 Word:target SEP 798 {: dAsm.addPackedSwitchData(target.str_val); :} 799 | 800 Relative:target SEP 801 {: dAsm.addPackedSwitchData(target.int_val); :} 802; 803 804ps_table_end ::= 805 PACKED_SWITCH_END 806 {: dAsm.endSwitch(); :} 807; 808 809// sparse-switch register 810// <value> : <label> 811// <value> : <label> 812// ... 813// sparse-switch-end 814ss_table ::= 815 ss_table_args 816 ss_table_list 817 ss_table_end 818; 819 820ss_table_args ::= 821 Word:r SEP // <register> 822 {: dAsm.newSparseSwitch(r.str_val); :} 823; 824 825ss_table_list ::= ss_table_list ss_table_entry | ss_table_entry ; 826 827ss_table_entry ::= 828 Int:i COLON Word:w SEP 829 {: dAsm.addSparseSwitchData(i.int_val, w.str_val); :} 830 | 831 Int:i COLON Relative:off SEP 832 {: dAsm.addSparseSwitchData(i.int_val, off.int_val); :} 833; 834 835ss_table_end ::= 836 SPARSE_SWITCH_END 837 {: dAsm.endSwitch(); :} 838; 839