All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.d2j.jasmin.Jasmin.g Maven / Gradle / Ivy

grammar Jasmin;

@header {
package com.googlecode.d2j.jasmin;
import java.util.List;
import java.util.ArrayList;
import java.math.BigInteger;
import org.objectweb.asm.*;
import org.objectweb.asm.tree.*;
import static com.googlecode.dex2jar.tools.Constants.*;
import static org.objectweb.asm.Opcodes.*;
}
@lexer::header {
package com.googlecode.d2j.jasmin;
}
@members{
    private ClassNode cn;
    private FieldNode fn;
    private MethodNode mn;
    private String tmp;
    private int tmpInt;
    private String tmp2;
    public boolean rebuildLine=false;
    private java.util.Map labelMap = new java.util.HashMap<>();
    private void reset0() {
        cn = new ClassNode(ASM_VERSION);
        fn = null;
        mn = null;
    }

    static private int parseInt(String str, int start, int end) {
        int sof = start;
        int x = 1;
        if (str.charAt(sof) == '+') {
            sof++;
        } else if (str.charAt(sof) == '-') {
            sof++;
            x = -1;
        }
        long v;
        if (str.charAt(sof) == '0') {
            sof++;
            if (sof >= end) {
                return 0;
            }
            char c = str.charAt(sof);
            if (c == 'x' || c == 'X') {// hex
                sof++;
                v = Long.parseLong(str.substring(sof, end), 16);
            } else {// oct
                v = Long.parseLong(str.substring(sof, end), 8);
            }
        } else {
            v = Long.parseLong(str.substring(sof, end), 10);
        }
        return (int) (v * x);
    }

    static private int parseInt(String str) {
        return parseInt(str, 0, str.length());
    }

    static private Long parseLong(String str) {
        int sof = 0;
        int end = str.length() - 1;
        int x = 1;
        if (str.charAt(sof) == '+') {
            sof++;
        } else if (str.charAt(sof) == '-') {
            sof++;
            x = -1;
        }
        BigInteger v;
        if (str.charAt(sof) == '0') {
            sof++;
            if (sof >= end) {
                return 0L;
            }
            char c = str.charAt(sof);
            if (c == 'x' || c == 'X') {// hex
                sof++;
                v = new BigInteger(str.substring(sof, end), 16);
            } else {// oct
                v = new BigInteger(str.substring(sof, end), 8);
            }
        } else {
            v = new BigInteger(str.substring(sof, end), 10);
        }
        if (x == -1) {
            return v.negate().longValue();
        } else {
            return v.longValue();
        }
    }

    static private float parseFloat(String str) {
        str = str.toLowerCase();
        int s = 0;
        float x = 1f;
        if (str.charAt(s) == '+') {
            s++;
        } else if (str.charAt(s) == '-') {
            s++;
            x = -1;
        }
        int e = str.length() - 1;
        if (str.charAt(e) == 'f') {
            e--;
        }
        str = str.substring(s, e + 1);
        if (str.equals("floatnan")) {
            return Float.NaN;
        }
        if (str.equals("floatinfinity")) {
            return x < 0 ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
        }
        return (float) x * Float.parseFloat(str);
    }

    static private double parseDouble(String str) {
        str = str.toLowerCase();
        int s = 0;
        double x = 1;
        if (str.charAt(s) == '+') {
            s++;
        } else if (str.charAt(s) == '-') {
            s++;
            x = -1;
        }
        int e = str.length() - 1;
        if (str.charAt(e) == 'd') {
            e--;
        }
        str = str.substring(s, e + 1);
        if (str.equals("doublenan")) {
            return Double.NaN;
        }
        if (str.equals("doubleinfinity")) {
            return x < 0 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
        }
        return x * Double.parseDouble(str);
    }

    private void line(int ln){
         if(rebuildLine) {
            Label label=new Label();
            mn.visitLabel(label);
            mn.visitLineNumber(ln, label);
         }
    }
    private static String unEscapeString(String str) {
        return unEscape0(str, 1, str.length() - 1);
    }
    private static String unEscape(String str) {
            return unEscape0(str, 0, str.length());
    }

    private static String unEscape0(String str, int start, int end) {

        StringBuilder sb = new StringBuilder();
        for (int i = start; i < end;) {
            char c = str.charAt(i);
            if (c == '\\') {
                char d = str.charAt(i + 1);
                switch (d) {
                // ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
                case 'b':
                    sb.append('\b');
                    i += 2;
                    break;
                case 't':
                    sb.append('\t');
                    i += 2;
                    break;
                case 'n':
                    sb.append('\n');
                    i += 2;
                    break;
                case 'f':
                    sb.append('\f');
                    i += 2;
                    break;
                case 'r':
                    sb.append('\r');
                    i += 2;
                    break;
                case '\"':
                    sb.append('\"');
                    i += 2;
                    break;
                case '\'':
                    sb.append('\'');
                    i += 2;
                    break;
                case '\\':
                    sb.append('\\');
                    i += 2;
                    break;
                case 'u':
                    String sub = str.substring(i + 2, i + 6);
                    sb.append((char) Integer.parseInt(sub, 16));
                    i += 6;
                    break;
                default:
                    int x = 0;
                    while (x < 3) {
                        char e = str.charAt(i + 1 + x);
                        if (e >= '0' && e <= '7') {
                            x++;
                        } else {
                            break;
                        }
                    }
                    if (x == 0) {
                        throw new RuntimeException("can't pase string");
                    }
                    sb.append((char) Integer.parseInt(str.substring(i + 1, i + 1 + x), 8));
                    i += 1 + x;
                }

            } else {
                sb.append(c);
                i++;
            }
        }
        return sb.toString();
    }

    private static int getAcc(String name) {
        if (name.equals("public")) {
            return ACC_PUBLIC;
        } else if (name.equals("private")) {
            return ACC_PRIVATE;
        } else if (name.equals("protected")) {
            return ACC_PROTECTED;
        } else if (name.equals("static")) {
            return ACC_STATIC;
        } else if (name.equals("final")) {
            return ACC_FINAL;
        } else if (name.equals("synchronized")) {
            return ACC_SYNCHRONIZED;
        } else if (name.equals("volatile")) {
            return ACC_VOLATILE;
        } else if (name.equals("bridge")) {
            return ACC_BRIDGE;
        } else if (name.equals("varargs")) {
            return ACC_VARARGS;
        } else if (name.equals("transient")) {
            return ACC_TRANSIENT;
        } else if (name.equals("native")) {
            return ACC_NATIVE;
        } else if (name.equals("interface")) {
            return ACC_INTERFACE;
        } else if (name.equals("abstract")) {
            return ACC_ABSTRACT;
        } else if (name.equals("strict")) {
            return ACC_STRICT;
        } else if (name.equals("strictfp")) {
            return ACC_STRICT;
        } else if (name.equals("synthetic")) {
            return ACC_SYNTHETIC;
        } else if (name.equals("annotation")) {
            return ACC_ANNOTATION;
        } else if (name.equals("enum")) {
            return ACC_ENUM;
        } else if (name.equals("super")) {
            return ACC_SUPER;
        }
        throw new RuntimeException("not support access flags " + name);
    }
    private static int getOp(String str) {
            switch (str) {
            case "nop":
                return Opcodes.NOP;
            case "aconst_null":
                return Opcodes.ACONST_NULL;
            case "iconst_m1":
                return Opcodes.ICONST_M1;
            case "iconst_0":
                return Opcodes.ICONST_0;
            case "iconst_1":
                return Opcodes.ICONST_1;
            case "iconst_2":
                return Opcodes.ICONST_2;
            case "iconst_3":
                return Opcodes.ICONST_3;
            case "iconst_4":
                return Opcodes.ICONST_4;
            case "iconst_5":
                return Opcodes.ICONST_5;
            case "lconst_0":
                return Opcodes.LCONST_0;
            case "lconst_1":
                return Opcodes.LCONST_1;
            case "fconst_0":
                return Opcodes.FCONST_0;
            case "fconst_1":
                return Opcodes.FCONST_1;
            case "fconst_2":
                return Opcodes.FCONST_2;
            case "dconst_0":
                return Opcodes.DCONST_0;
            case "dconst_1":
                return Opcodes.DCONST_1;
            case "bipush":
                return Opcodes.BIPUSH;
            case "sipush":
                return Opcodes.SIPUSH;
            case "ldc_w":
            case "ldc2_w":
            case "ldc":
                return Opcodes.LDC;
            case "iload":
                return Opcodes.ILOAD;
            case "lload":
                return Opcodes.LLOAD;
            case "fload":
                return Opcodes.FLOAD;
            case "dload":
                return Opcodes.DLOAD;
            case "aload":
                return Opcodes.ALOAD;
            case "iaload":
                return Opcodes.IALOAD;
            case "laload":
                return Opcodes.LALOAD;
            case "faload":
                return Opcodes.FALOAD;
            case "daload":
                return Opcodes.DALOAD;
            case "aaload":
                return Opcodes.AALOAD;
            case "baload":
                return Opcodes.BALOAD;
            case "caload":
                return Opcodes.CALOAD;
            case "saload":
                return Opcodes.SALOAD;
            case "istore":
                return Opcodes.ISTORE;
            case "lstore":
                return Opcodes.LSTORE;
            case "fstore":
                return Opcodes.FSTORE;
            case "dstore":
                return Opcodes.DSTORE;
            case "astore":
                return Opcodes.ASTORE;
            case "iastore":
                return Opcodes.IASTORE;
            case "lastore":
                return Opcodes.LASTORE;
            case "fastore":
                return Opcodes.FASTORE;
            case "dastore":
                return Opcodes.DASTORE;
            case "aastore":
                return Opcodes.AASTORE;
            case "bastore":
                return Opcodes.BASTORE;
            case "castore":
                return Opcodes.CASTORE;
            case "sastore":
                return Opcodes.SASTORE;
            case "pop":
                return Opcodes.POP;
            case "pop2":
                return Opcodes.POP2;
            case "dup":
                return Opcodes.DUP;
            case "dup_x1":
                return Opcodes.DUP_X1;
            case "dup_x2":
                return Opcodes.DUP_X2;
            case "dup2":
                return Opcodes.DUP2;
            case "dup2_x1":
                return Opcodes.DUP2_X1;
            case "dup2_x2":
                return Opcodes.DUP2_X2;
            case "swap":
                return Opcodes.SWAP;
            case "iadd":
                return Opcodes.IADD;
            case "ladd":
                return Opcodes.LADD;
            case "fadd":
                return Opcodes.FADD;
            case "dadd":
                return Opcodes.DADD;
            case "isub":
                return Opcodes.ISUB;
            case "lsub":
                return Opcodes.LSUB;
            case "fsub":
                return Opcodes.FSUB;
            case "dsub":
                return Opcodes.DSUB;
            case "imul":
                return Opcodes.IMUL;
            case "lmul":
                return Opcodes.LMUL;
            case "fmul":
                return Opcodes.FMUL;
            case "dmul":
                return Opcodes.DMUL;
            case "idiv":
                return Opcodes.IDIV;
            case "ldiv":
                return Opcodes.LDIV;
            case "fdiv":
                return Opcodes.FDIV;
            case "ddiv":
                return Opcodes.DDIV;
            case "irem":
                return Opcodes.IREM;
            case "lrem":
                return Opcodes.LREM;
            case "frem":
                return Opcodes.FREM;
            case "drem":
                return Opcodes.DREM;
            case "ineg":
                return Opcodes.INEG;
            case "lneg":
                return Opcodes.LNEG;
            case "fneg":
                return Opcodes.FNEG;
            case "dneg":
                return Opcodes.DNEG;
            case "ishl":
                return Opcodes.ISHL;
            case "lshl":
                return Opcodes.LSHL;
            case "ishr":
                return Opcodes.ISHR;
            case "lshr":
                return Opcodes.LSHR;
            case "iushr":
                return Opcodes.IUSHR;
            case "lushr":
                return Opcodes.LUSHR;
            case "iand":
                return Opcodes.IAND;
            case "land":
                return Opcodes.LAND;
            case "ior":
                return Opcodes.IOR;
            case "lor":
                return Opcodes.LOR;
            case "ixor":
                return Opcodes.IXOR;
            case "lxor":
                return Opcodes.LXOR;
            case "iinc":
                return Opcodes.IINC;
            case "i2l":
                return Opcodes.I2L;
            case "i2f":
                return Opcodes.I2F;
            case "i2d":
                return Opcodes.I2D;
            case "l2i":
                return Opcodes.L2I;
            case "l2f":
                return Opcodes.L2F;
            case "l2d":
                return Opcodes.L2D;
            case "f2i":
                return Opcodes.F2I;
            case "f2l":
                return Opcodes.F2L;
            case "f2d":
                return Opcodes.F2D;
            case "d2i":
                return Opcodes.D2I;
            case "d2l":
                return Opcodes.D2L;
            case "d2f":
                return Opcodes.D2F;
            case "i2b":
                return Opcodes.I2B;
            case "i2c":
                return Opcodes.I2C;
            case "i2s":
                return Opcodes.I2S;
            case "lcmp":
                return Opcodes.LCMP;
            case "fcmpl":
                return Opcodes.FCMPL;
            case "fcmpg":
                return Opcodes.FCMPG;
            case "dcmpl":
                return Opcodes.DCMPL;
            case "dcmpg":
                return Opcodes.DCMPG;
            case "ifeq":
                return Opcodes.IFEQ;
            case "ifne":
                return Opcodes.IFNE;
            case "iflt":
                return Opcodes.IFLT;
            case "ifge":
                return Opcodes.IFGE;
            case "ifgt":
                return Opcodes.IFGT;
            case "ifle":
                return Opcodes.IFLE;
            case "if_icmpeq":
                return Opcodes.IF_ICMPEQ;
            case "if_icmpne":
                return Opcodes.IF_ICMPNE;
            case "if_icmplt":
                return Opcodes.IF_ICMPLT;
            case "if_icmpge":
                return Opcodes.IF_ICMPGE;
            case "if_icmpgt":
                return Opcodes.IF_ICMPGT;
            case "if_icmple":
                return Opcodes.IF_ICMPLE;
            case "if_acmpeq":
                return Opcodes.IF_ACMPEQ;
            case "if_acmpne":
                return Opcodes.IF_ACMPNE;
            case "goto":
                return Opcodes.GOTO;
            case "jsr":
                return Opcodes.JSR;
            case "ret":
                return Opcodes.RET;
            case "tableswitch":
                return Opcodes.TABLESWITCH;
            case "lookupswitch":
                return Opcodes.LOOKUPSWITCH;
            case "ireturn":
                return Opcodes.IRETURN;
            case "lreturn":
                return Opcodes.LRETURN;
            case "freturn":
                return Opcodes.FRETURN;
            case "dreturn":
                return Opcodes.DRETURN;
            case "areturn":
                return Opcodes.ARETURN;
            case "return":
                return Opcodes.RETURN;
            case "getstatic":
                return Opcodes.GETSTATIC;
            case "putstatic":
                return Opcodes.PUTSTATIC;
            case "getfield":
                return Opcodes.GETFIELD;
            case "putfield":
                return Opcodes.PUTFIELD;
            case "invokevirtual":
                return Opcodes.INVOKEVIRTUAL;
            case "invokespecial":
                return Opcodes.INVOKESPECIAL;
            case "invokestatic":
                return Opcodes.INVOKESTATIC;
            case "invokeinterface":
                return Opcodes.INVOKEINTERFACE;
            case "invokedynamic":
                return Opcodes.INVOKEDYNAMIC;
            case "new":
                return Opcodes.NEW;
            case "newarray":
                return Opcodes.NEWARRAY;
            case "anewarray":
                return Opcodes.ANEWARRAY;
            case "arraylength":
                return Opcodes.ARRAYLENGTH;
            case "athrow":
                return Opcodes.ATHROW;
            case "checkcast":
                return Opcodes.CHECKCAST;
            case "instanceof":
                return Opcodes.INSTANCEOF;
            case "monitorenter":
                return Opcodes.MONITORENTER;
            case "monitorexit":
                return Opcodes.MONITOREXIT;
            case "multianewarray":
                return Opcodes.MULTIANEWARRAY;
            case "ifnull":
                return Opcodes.IFNULL;
            case "ifnonnull":
                return Opcodes.IFNONNULL;
            case "iload_0":
                return 26;
            case "iload_1":
                return 27;
            case "iload_2":
                return 28;
            case "iload_3":
                return 29;
            case "lload_0":
                return 30;
            case "lload_1":
                return 31;
            case "lload_2":
                return 32;
            case "lload_3":
                return 33;
            case "fload_0":
                return 34;
            case "fload_1":
                return 35;
            case "fload_2":
                return 36;
            case "fload_3":
                return 37;
            case "dload_0":
                return 38;
            case "dload_1":
                return 39;
            case "dload_2":
                return 40;
            case "dload_3":
                return 41;
            case "aload_0":
                return 42;
            case "aload_1":
                return 43;
            case "aload_2":
                return 44;
            case "aload_3":
                return 45;
            case "istore_0":
                return 59;
            case "istore_1":
                return 60;
            case "istore_2":
                return 61;
            case "istore_3":
                return 62;
            case "lstore_0":
                return 63;
            case "lstore_1":
                return 64;
            case "lstore_2":
                return 65;
            case "lstore_3":
                return 66;
            case "fstore_0":
                return 67;
            case "fstore_1":
                return 68;
            case "fstore_2":
                return 69;
            case "fstore_3":
                return 70;
            case "dstore_0":
                return 71;
            case "dstore_1":
                return 72;
            case "dstore_2":
                return 73;
            case "dstore_3":
                return 74;
            case "astore_0":
                return 75;
            case "astore_1":
                return 76;
            case "astore_2":
                return 77;
            case "astore_3":
                return 78;
            }
            return 0;
        }

    private String[] parseOwnerAndName(String str) {
        int x=str.lastIndexOf('/');
        if(x>0){
        return new String[]{ unEscape0(str,0,x), unEscape0(str,x+1,str.length()) };
        }
        throw new RuntimeException("can't get owner and type from '"+str+"'");
    }

    public Object parseValue(String desc, Object v) {
        switch(desc) {
        case "Z": return ((Number)v).intValue()!=0;
        case "B": return ((Number)v).byteValue();
        case "S": return ((Number)v).shortValue();
        case "I": return ((Number)v).intValue();
        case "F": return ((Number)v).floatValue();
        case "D": return ((Number)v).doubleValue();
        case "J": return ((Number)v).longValue();
        case "C": return (char)((Number)v).intValue();
        }
        return v;
    }

    static class AV {
        public AnnotationNode visitAnnotation(final String desc, final boolean visible) {
            return null;
        };

        public AnnotationNode visitParameterAnnotation(final int parameter, final String desc, final boolean visible) {
            return null;
        }
    }

    AV cnv = new AV() {
        public AnnotationNode visitAnnotation(final String desc, final boolean visible) {
            return (AnnotationNode) cn.visitAnnotation(desc, visible);
        }
    };
    AV fnv = new AV() {
        public AnnotationNode visitAnnotation(final String desc, final boolean visible) {
            return (AnnotationNode) fn.visitAnnotation(desc, visible);
        }
    };
    AV mnv = new AV() {
        public AnnotationNode visitAnnotation(final String desc, final boolean visible) {
            return (AnnotationNode) mn.visitAnnotation(desc, visible);
        }

        public AnnotationNode visitParameterAnnotation(final int parameter, final String desc, final boolean visible) {
            return (AnnotationNode) mn.visitParameterAnnotation(parameter, desc, visible);
        }
    };
    private void visitOP0(int op){
    if(op>=26&&op<=45){    // xload_y
            int x=op-26;
            mn.visitVarInsn(ILOAD+x/4,x\%4);
            }else if(op>=59&&op<=78){    // xstore_y
                     int x=op-26;
                     mn.visitVarInsn(ISTORE+x/4,x\%4);
            }else{
        mn.visitInsn(op);
        }
    }
    private void visitIOP(int op, int a){
         // xstore
         // xload
         if(op>=21&&op<=58){
         mn.visitVarInsn(op,a);
         }  else {
         // xipush
         mn.visitIntInsn(op,a);
         }
    }
    private void visitJOP(int op, Label label){
        mn.visitJumpInsn(op,label);
    }
    private void visitIIOP(int op, int a, int b){
        mn.visitIincInsn(a,b);
    }
    private Label getLabel(String name){
    Label label=labelMap.get(name);
    if(label==null){
    label= new Label();
    labelMap.put(name,label);
    }
        return  label;
    }
    public void accept(ClassVisitor cv) throws RecognitionException{
        sFile();
        cn.accept(cv);
    }
    public ClassNode parse() throws RecognitionException {
        sFile();
        ClassNode cn=this.cn;
        reset0();
        return cn;
    }
    AV currentAv;
    AnnotationNode currentAnnotationVisitor;
}



fragment
INT_NENT: ('+'|'-')? (
               '0' 
            | ('1'..'9') ('0'..'9')* 
            | '0' ('0'..'7')+ 
            | ('0x'|'0X') HEX_DIGIT+
         );
fragment
FLOAT_NENT
    : ('+'|'-')?( ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
    |   '.' ('0'..'9')+ EXPONENT?
    |   ('0'..'9')+ EXPONENT)
    ;
fragment
F_FLOAT	:	('f'|'F') ('l'|'L')('o'|'O')('a'|'A')('t'|'T');
fragment
F_DOUBLE	:('d'|'D')('o'|'O')('u'|'U')('b'|'B')('l'|'L')('e'|'E');
fragment
F_NAN : ('N'|'n') ('A'|'a') ('N'|'n');
fragment
F_INFINITY: ('I'|'i') ('N'|'n') ('F'|'f') ('I'|'i') ('N'|'n') ('I'|'i') ('T'|'t') ('Y'|'y') ;

FLOAT	:	((('0'..'9')+|FLOAT_NENT) ('f'|'F')) 
		| ('+'|'-')F_FLOAT F_INFINITY
		| '+' F_FLOAT F_NAN
		;
DOUBLE	:	FLOAT_NENT ('d'|'D')? 
		| ('0'..'9')+ ('d'|'D') 
		| ('+'|'-') F_DOUBLE F_INFINITY
		| '+' F_DOUBLE F_NAN
		;
LONG	:	INT_NENT ('L'|'l');
INT	:	INT_NENT;

COMMENT
    :   ';' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    ;

WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;

STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;
DSTRING
    :  '\'' ( ESC_SEQ | ~('\\'|'\'') )* '\''
    ;
	
fragment
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\''|'\"'|'\\')
    |   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    |   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

VOID_TYPE:'V';
fragment
FRAGMENT_PRIMITIVE_TYPE:'B'|'Z'|'S'|'C'|'I'|'F'|'J'|'D';
fragment
FRAGMENT_OBJECT_TYPE: 'L' (ESC_SEQ |~(';'|':'|'\\'|' '|'\n'|'\t'|'\r'|'('|')'))+ ';' ;

METHOD_DESC_WITHOUT_RET: '(' ('['*(FRAGMENT_PRIMITIVE_TYPE|FRAGMENT_OBJECT_TYPE))* ')';
OBJECT_TYPE: 'L' (ESC_SEQ |~(';'|':'|'\\'|' '|'\n'|'\t'|'\r'|'('|')'))+ ';' ;
ACC:	'public' | 'private' | 'protected' | 'static' | 'final' | 'synchronized' | 'bridge' | 'varargs' | 'native' |
    'abstract' | 'strictfp' | 'synthetic' | 'constructor' | 'interface' | 'enum' |
    'annotation' | 'volatile' | 'transient' | 'declared-synchronized' | 'super' | 'strict';
ANNOTATION_VISIBLITY: 'visible' | 'invisible' ;
METHOD_ANNOTATION_VISIBLITY: 'visibleparam' | 'invisibleparam';
INNER	:	'inner';
OUTTER	:	'outer';
OP0	:	'nop'|'monitorenter'|'monitorexit'|'pop2'|'pop'
	|	'iconst_m1'
	|('a'|'i')'const_' ('0'..'5')
	|('d'|'l')'const_' ('0'..'1')
	|'fconst_' ('0'..'2')
	|'aconst_null'
	|('a'|'d'|'f'|'i'|'l')? 'return'
	|('a'|'d'|'f'|'i'|'l') ('store'|'load') '_' ('0'..'3')
	|('a'|'b'|'c'|'d'|'f'|'i'|'l') ('astore'|'aload')
	|'dcmpg'|'dcmpl' | 'lcmp' |'fcmpg'|'fcmpl'
	|'athrow'
	|('i'|'f'|'d'|'l')('add'|'div'|'sub'|'mul'|'rem'|'shl'|'shr'|'ushr'|'and'|'or'|'xor'|'neg')
	|'arraylength'
	|'dup'|'dup2'|'dup_x2'|'dup2_x2'|'dup2_x1'
	|'swap'
	|'i2b' | 'i2c' |'i2d' | 'i2f' | 'i2s' | 'i2l'
	| 'f2d' | 'f2i' | 'f2l'
	| 'd2f' | 'd2i' | 'd2l'
	| 'l2d' | 'l2f' | 'l2i'
	;
IOP	:	('a'|'d'|'f'|'i'|'l') 'load'
	|	('a'|'d'|'f'|'i'|'l') 'store'
	|'bipush'|'sipush'
	;
IIOP	:	'iinc'
	;
JOP	:	'goto'
	|	'jsr'
	|	'if' ('null'|'nonnull'|'eq'|'ne'|'gt'|'ge'|'lt'|'le')
	|       'if_' ('a'|'i') 'cmp' ('eq'|'ne'|'gt'|'ge'|'lt'|'le')
	;
LDC	:	'ldc'|'ldc_w'|'ldc2_w'
	;
XFIELD	:	'getstatic'|'putstatic'|'getfield'|'putfield';
XNEWARRAY: 'newarray' ;
XTYPE	:	'checkcast'|'instanceof'|'new'|'anewarray'
	;
MULTIANEWARRAY
	:	'multianewarray'
	;
LOOKUPSWITCH:	'lookupswitch';
TABLESWITCH:	'tableswitch';
XINVOKE	:	'invokestatic'
	|	'invokevirtual'
	|       'invokespecial'
	;
INVOKEINTERFACE  :
	       'invokeinterface'
	;
INVOKEDYNAMIC
	:	'invokedynamic';
HIGH	:	'high';
DEFAULT	:	'default';
FROM	:	'from';
TO	:	'to';
USING	:	'using';
STACK	:	'stack';
LOCALS	:	'locals';
WBOOLEAN: 'boolean';
WBYTE: 'byte';
WSHORT: 'short';
WCHAR: 'char';
WINTEGER: 'int';
WFLOAT: 'float';
WLONG: 'long';
WDOUBLE: 'double';

fragment
F_ID_FOLLOWS: ESC_SEQ| ~('\\'|'\r'|'\n'|'\t'|' '|':'|'-'|'='|','|'{'|'}'|'('|')');
ID  :    FRAGMENT_PRIMITIVE_TYPE F_ID_FOLLOWS+
    |    ESC_SEQ F_ID_FOLLOWS*
    |    ~(FRAGMENT_PRIMITIVE_TYPE| '0'..'9'| '\\' | '\r' | '\n' | '\t' | '\'' | '\"' | ' ' | ':' | '-' | '=' | '.' | ',' | '&' | '@' | '/' | '{'|'['|']'|'}'|'('|')') F_ID_FOLLOWS*
    ;
PARRAY_TYPE
	:	'['+ FRAGMENT_OBJECT_TYPE
	|	'[' '['+ FRAGMENT_PRIMITIVE_TYPE
	;
AT	:	'@';
AND	:	'&';
UP_Z	:	'Z';
UP_B	:	'B';
UP_S	:	'S';
UP_C	:	'C';
UP_I	:	'I';
UP_F	:	'F';
UP_D	:	'D';
UP_J	:	'J';
ARRAY_Z	:	'[Z';
ARRAY_B	:	'[B';
ARRAY_S	:	'[S';
ARRAY_C	:	'[C';
ARRAY_I	:	'[I';
ARRAY_F	:	'[F';
ARRAY_D	:	'[D';
ARRAY_J	:	'[J';
ARRAY_LOW_E	:	'[e';
ARRAY_LOW_S	:	'[s';
ARRAY_LOW_C	:	'[c';
ARRAY_AT	:	'[@';
ARRAY_AND	:	'[&';
LEFT_PAREN: '(';
RIGHT_PAREN: ')';

sFile	: { reset0(); currentAv=cnv; }
sHead+ (sAnnotation|sVisibiltyAnnotation)* (sField|sMethod)*
	;
sHead   :  '.bytecode' ( a=INT { int v=parseInt($a.text); cn.version=JAVA_VERSIONS[v>=45?v-45:v];}
                        |a=DOUBLE {double v=parseDouble($a.text); cn.version=JAVA_VERSIONS[(int)(v<2.0?(v*10)\%10:(v-44))]; }
                       )
        |  '.source' aa4=sAnyIdOrString  { cn.sourceFile=$aa4.str; }
		|  '.class' i=sAccList {cn.access|=$i.acc; if ((cn.access & Opcodes.ACC_INTERFACE) == 0) {cn.access |= Opcodes.ACC_SUPER;} else { cn.access &= ~Opcodes.ACC_SUPER; } } a1=sInternalNameOrDesc { cn.name=Type.getType($a1.desc).getInternalName(); }
		|  '.interface' i=sAccList {cn.access|=ACC_INTERFACE|$i.acc;} a1=sInternalNameOrDesc { cn.name=Type.getType($a1.desc).getInternalName(); }
		|  '.super' a1=sInternalNameOrDescACC  {  cn.superName=Type.getType($a1.desc).getInternalName(); }
		|  '.implements' a1=sInternalNameOrDescACC { if(cn.interfaces==null){cn.interfaces=new ArrayList<>();}  cn.interfaces.add(Type.getType($a1.desc).getInternalName()); }
		|  '.enclosing method' ownerAndName=sOwnerAndName {tmp=null;} (b=sMethodDesc{tmp=$b.text;})? {cn.visitOuterClass($ownerAndName.ownerInternalName,$ownerAndName.memberName,tmp);}
		|  sDeprecateAttr  { cn.access|=ACC_DEPRECATED; }
		|  '.debug' a=STRING  { cn.sourceDebug=unEscapeString($a.text); }
		|  '.attribute' sId STRING     { System.err.println("ignore .attribute"); }
		|  '.inner class' (i=sAccList sId{tmpInt=$i.acc;})? {tmp=null;tmp2=null;} ('inner' a3=sId{tmp=$a3.text;})? ('outer' a4=sId{tmp2=$a4.text;})?   { cn.visitInnerClass(null,tmp2,tmp,tmpInt); }
		|  '.no_super' {cn.superName=null;}
		|  '.class_attribute' sId STRING    { System.err.println("ignore .class_attribute"); }
		|  '.enclosing_method_attr' a=STRING b1=STRING c=STRING   {cn.visitOuterClass($a.text,$b1.text,$c.text);}
		|  '.inner_class_attr' ('.inner_class_spec_attr' a=STRING b2=STRING i=sAccList '.end' '.inner_class_spec_attr' { cn.visitInnerClass(null,unEscape($a.text),unEscape($b2.text),i); } )* '.end' '.inner_class_attr'
		|  s=sSigAttr  { cn.signature=$s.sig; }
		|  sSynthetic   {cn.access|=ACC_SYNTHETIC;}
		;
sSigAttr returns[String sig]:	('.signature_attr' | '.signature') a=STRING{ $sig=unEscapeString($a.text); };
sDeprecateAttr:	'.deprecated';
sSynthetic
	:	'.synthetic'
	;
sArrayType
	:	PARRAY_TYPE|ARRAY_Z|ARRAY_B|ARRAY_S|ARRAY_C|ARRAY_I|ARRAY_F|ARRAY_D|ARRAY_J
	;
sClassDesc
	:	sArrayType|OBJECT_TYPE|UP_Z|UP_B|UP_S|UP_C|UP_I|UP_J|UP_D|UP_F
	;
sId	:	ID|AT|AND|UP_Z|UP_B|UP_S|UP_C|UP_I|UP_F|UP_D|UP_J|ANNOTATION_VISIBLITY|METHOD_ANNOTATION_VISIBLITY|INNER|OUTTER
	|	IIOP|IOP|JOP|OP0|LDC|XFIELD|XTYPE|XINVOKE|INVOKEINTERFACE|MULTIANEWARRAY|LOOKUPSWITCH|TABLESWITCH|DEFAULT|FROM|TO|USING|STACK|LOCALS|HIGH|INVOKEDYNAMIC|VOID_TYPE
	| WBOOLEAN| WBYTE | WSHORT|WCHAR|WINTEGER|WLONG|WFLOAT|WDOUBLE |XNEWARRAY
	;
sWord : sId ;
sAnnotation
	: '.annotation' (b=ANNOTATION_VISIBLITY aInternalOrDesc=sInternalNameOrDescACC { currentAnnotationVisitor= currentAv.visitAnnotation($aInternalOrDesc.desc,!$b.text.contains("invisible")); } |
	                  b=METHOD_ANNOTATION_VISIBLITY c=INT a=sId {currentAnnotationVisitor=currentAv.visitParameterAnnotation(parseInt($c.text),$a.text,!$b.text.contains("invisible"));}
	                )
	    (sAnnotationElement* '.end annotation')?
	;
sVisibiltyAnnotation
	: {boolean visible=false;} ('.runtime_visible_annotation' {visible=true;}|'.runtime_invisible_annotation'{visible=false;}) a=STRING      { currentAnnotationVisitor= currentAv.visitAnnotation(unEscape($a.text),visible); }
	sAnnotationSoot*
	 '.end' '.annotation_attr'
	;
sAnnotationSoot
	: '.annotation' 
	(t=sAnnotationElementSoot {currentAnnotationVisitor.visit($t.nn,$t.v);} )*
	'.end' '.annotation'
	;
sAnnotationElementSoot returns[String nn,Object v]
	:'.elem' ('.bool_kind' a=STRING b=INT          {$nn=unEscapeString($a.text); $v=0!=parseInt($b.text);}
              	    | '.short_kind' a=STRING b=INT        {$nn=unEscapeString($a.text); $v=(short)parseInt($b.text);}
              	    | '.byte_kind' a=STRING b=INT         {$nn=unEscapeString($a.text); $v=(byte)parseInt($b.text);}
              	    | '.char_kind' a=STRING b=INT         {$nn=unEscapeString($a.text); $v=(char)parseInt($b.text);}
              	    | '.int_kind' a=STRING b=INT          {$nn=unEscapeString($a.text); $v=parseInt($b.text);}
              	    | '.long_kind' a=STRING b=(INT|LONG)  {$nn=unEscapeString($a.text); $v=parseLong($b.text);}
              	    | '.float_kind' a=STRING b=INT        {$nn=unEscapeString($a.text); $v=parseFloat($b.text);}
              	    | '.doub_kind' a=STRING b=(INT|LONG)  {$nn=unEscapeString($a.text); $v=parseDouble($b.text);}
              	    | '.str_kind' a=STRING b=STRING       {$nn=unEscapeString($a.text); $v=unEscapeString($b.text);}
              	    | '.enum_kind' a=STRING b=STRING      {$nn=unEscapeString($a.text); String on[]=parseOwnerAndName($b.text);$v=new String[]{on[0],on[1]};}
              	    | '.cls_kind' a=STRING b=STRING       {$nn=unEscapeString($a.text); $v=Type.getType(unEscapeString($b.text));}
              	    | '.arr_kind' a=STRING {List array=new ArrayList<>();} (t=sAnnotationElementSoot{array.add($t.v);})* '.end'  '.arr_elem'   {$nn=unEscapeString($a.text); $v=array;}
              	    | '.ann_kind' a=STRING q=sSubannotationSoot '.end' '.annot_elem'     {$nn=unEscapeString($a.text); $v=$q.v;})
	;

sSubannotationSoot  returns[AnnotationNode v]
	:	'.annotation' a=STRING   { $v=new AnnotationNode(unEscapeString($a.text)); }
	     (t=sAnnotationElementSoot {$v.visit($t.nn,$t.v);} )*
	    '.end' '.annotation'
	;
sAnnotationElement @init{List array = new ArrayList(); AnnotationNode _t= currentAnnotationVisitor;}
    :   a=sId (
             xid=ID { if(!"e".contains($xid.text)){ throw new RecognitionException(input);} }  c=OBJECT_TYPE '=' b=sWord {  _t.visit($a.text,new String[]{$c.text,$b.text}); }
           | AT b2=OBJECT_TYPE '=' {  currentAnnotationVisitor=new AnnotationNode($b2.text);} sSubannotation  { _t.visit($a.text,currentAnnotationVisitor); }
           | xid=ID { if(!"c".contains($xid.text)){ throw new RecognitionException(input);} } '=' b1=sClassDesc { currentAnnotationVisitor.visit($a.text,Type.getType($b1.text)); }
           | xid=ID { if(!"s".contains($xid.text)){ throw new RecognitionException(input);} } '=' b3=STRING      { currentAnnotationVisitor.visit($a.text,unEscapeString($b3.text)); }
           | UP_B  '=' b4=INT  { currentAnnotationVisitor.visit($a.text,(byte)parseInt($b4.text)); }
           | UP_Z  '=' b5=INT  { currentAnnotationVisitor.visit($a.text,0!=parseInt($b5.text)); }
           | UP_S  '=' b6=INT   { currentAnnotationVisitor.visit($a.text,(short)parseInt($b6.text)); }
           | UP_C  '=' b7=INT   { currentAnnotationVisitor.visit($a.text,(char)parseInt($b7.text)); }
           | UP_I  '=' b8=INT   { currentAnnotationVisitor.visit($a.text,parseInt($b8.text)); }
           | UP_J  '=' b9=(INT|LONG)  { currentAnnotationVisitor.visit($a.text,parseLong($b9.text)); }
           | UP_F  '=' b10=(INT|FLOAT|DOUBLE)  { currentAnnotationVisitor.visit($a.text,parseFloat($b10.text)); }
           | UP_D  '=' b11=(INT|FLOAT|DOUBLE)   { currentAnnotationVisitor.visit($a.text,parseDouble($b11.text)); }
           | ARRAY_B '='  (b12=INT {array.add((byte)parseInt($b12.text));} )+    { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_Z '='  (b13=INT {array.add(0!=parseInt($b13.text));} )+       { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_S '='  (b14=INT {array.add((short)parseInt($b14.text));} )+   { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_C '='  (b15=INT {array.add((char)parseInt($b15.text));} )+    { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_I '='  (b16=INT {array.add(parseInt($b16.text));} )+          { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_J '='  (b17=(INT|LONG) {array.add(parseLong($b17.text));} )+  { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_F '='  (b18=(INT|FLOAT|DOUBLE) {array.add(parseFloat($b18.text));} )+  { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_D '='  (b19=(INT|DOUBLE) {array.add(parseDouble($b19.text));} )+       { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_LOW_E c=OBJECT_TYPE '='  ((b1=sWord{  array.add(new String[]{$c.text,unEscape($b1.text)}); }|b2=STRING{  array.add(new String[]{$c.text,unEscapeString($b2.text)}); }|b3=DSTRING{  array.add(new String[]{$c.text,unEscapeString($b3.text)}); })  )+  { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_AND b20=OBJECT_TYPE '=' ARRAY_AT '='  ({currentAnnotationVisitor=new AnnotationNode($b20.text);} sSubannotation{ array.add(currentAnnotationVisitor); })+ { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_LOW_C '='  (b=sClassDesc {array.add(Type.getType($b.text));} )+       { currentAnnotationVisitor.visit($a.text,array); }
           | ARRAY_LOW_S '='  (b21=STRING {array.add(unEscapeString($b21.text));})+   { currentAnnotationVisitor.visit($a.text,array); }
		)
	{ currentAnnotationVisitor=_t; }
;
sSubannotation
	:	'.annotation' 
	     sAnnotationElement*
	    '.end annotation'
	;
sAccList returns[int acc]: {$acc=0;} ( a=ACC {$acc|=getAcc($a.text);})*  ;
sMemberName returns[String name]: a=sId {$name=unEscape($a.text);} | b=STRING {$name=unEscapeString($b.text);}| c=DSTRING {$name=unEscapeString($c.text);};
sField	@init {
                    if(cn.fields==null){
                        cn.fields=new ArrayList<>();
                    }
                    currentAv=fnv;
                    fn=new FieldNode(0,null,null,null,null);
                    cn.fields.add(fn);
              }
    :	'.field' i=sAccList n=sMemberName t=sClassDesc { fn.access|=i;fn.name=$n.name;fn.desc=unEscape($t.text); }
        ( '=' (a=STRING {fn.value=parseValue(fn.desc,unEscapeString($a.text));}
              |a1=INT      {fn.value=parseValue(fn.desc,parseInt($a1.text));}
              |a2=LONG     {fn.value=parseValue(fn.desc,parseLong($a2.text));}
              |a3=FLOAT    {fn.value=parseValue(fn.desc,parseFloat($a3.text));}
              |a4=DOUBLE   {fn.value=parseValue(fn.desc,parseDouble($a4.text));}
              |a5=sClassDesc {fn.value=parseValue(fn.desc,Type.getType(unEscape($a5.text)));}
              )
        )?
            (
            s=sSigAttr{fn.signature=$s.sig;}
            |sDeprecateAttr{ fn.access|=ACC_DEPRECATED; }
            |sSynthetic {cn.access|=ACC_SYNTHETIC;}
            |sVisibiltyAnnotation
            |sAnnotation
            )*
    ('.end field'| '.end' '.field')?
	('.field_attribute' sId STRING {System.err.println("ignore .field_attribute");})*
	;
sMethod	@init{
    if(cn.methods==null){
        cn.methods=new ArrayList<>();
    }
    currentAv=mnv;
    mn=new MethodNode(ASM_VERSION);
    cn.methods.add(mn);
    labelMap.clear();
    if(mn.exceptions==null){
        mn.exceptions=new ArrayList<>();
    }
    if(mn.tryCatchBlocks==null){
            mn.tryCatchBlocks=new ArrayList<>();
        }
}
    :	'.method' i=sAccList n=sMemberName t=sMethodDesc {mn.access|=i;mn.name=$n.name;mn.desc=unEscape($t.text);}
            (s=sSigAttr{mn.signature=$s.sig;}
                |sDeprecateAttr{ cn.access|=ACC_DEPRECATED; }
                |sSynthetic {cn.access|=ACC_SYNTHETIC;}
                |sVisibiltyAnnotation
                |sAnnotation
                |'.throws' at=sInternalNameOrDesc {  mn.exceptions.add(Type.getType($at.desc).getInternalName()); }
                |'.annotation_default' (t=sAnnotationElementSoot {currentAnnotationVisitor=(AnnotationNode)mn.visitAnnotationDefault();} )? '.end' '.annotation_default'
                |'.param' ('.runtime_invisible_annotation'|'.runtime_visible_annotation') {int index=0;}
                    ({boolean visible=false;} ('.runtime_visible_annotation' {visible=true;}|'.runtime_invisible_annotation'{visible=false;}) a1=STRING
                    { currentAnnotationVisitor= currentAv.visitParameterAnnotation(index,unEscapeString($a1.text),visible); }
                        sAnnotationSoot*
                       '.end' '.annotation_attr' {index++;}
                    )*
                 '.end' '.param'
                | code
            )*
        '.end method'
	('.method_attribute' sId STRING {System.err.println("ignore method_attribute");})*
	;

sLabel	:	ACC|ID|UP_Z|UP_B|UP_S|UP_C|UP_I|UP_F|UP_D|UP_J|ANNOTATION_VISIBLITY|METHOD_ANNOTATION_VISIBLITY|INNER|OUTTER
	;
code
    :	a=OP0 { line($a.line); visitOP0(getOp($a.text)); }
	|	a=IOP b=INT { line($a.line); visitIOP(getOp($a.text),parseInt($b.text)); }
	|	a=IIOP b=INT c=INT   { line($a.line); visitIIOP(getOp($a.text),parseInt($b.text),parseInt($c.text)); }
	| 	a=LDC  {line($a.line);  } ( c=INT        {mn.visitLdcInsn(parseInt($c.text));}
	                               |c=LONG       {mn.visitLdcInsn(parseLong($c.text));}
	                               |c=FLOAT      {mn.visitLdcInsn(parseFloat($c.text));}
	                               |c=DOUBLE     {mn.visitLdcInsn(parseDouble($c.text));}
	                               |c=STRING     {mn.visitLdcInsn(unEscapeString($c.text));}
	                               |eTV=sInternalNameOrDescNoString {mn.visitLdcInsn(Type.getType($eTV.desc));}
	                              )
	|	a=XFIELD efo=sFieldObject {  line($a.line);  mn.visitFieldInsn(getOp($a.text),$efo.ownerInternalName,$efo.memberName,$efo.type);   }
	|   a=XNEWARRAY {line($a.line); }  (
	               WBOOLEAN{mn.visitIntInsn(NEWARRAY,T_BOOLEAN);}
	               |WBYTE{mn.visitIntInsn(NEWARRAY,T_BYTE);}
	               |WSHORT{mn.visitIntInsn(NEWARRAY,T_SHORT);}
	               |WCHAR{mn.visitIntInsn(NEWARRAY,T_CHAR);}
	               |WINTEGER{mn.visitIntInsn(NEWARRAY,T_INT);}
	               |WLONG{mn.visitIntInsn(NEWARRAY,T_LONG);}
	               |WFLOAT{mn.visitIntInsn(NEWARRAY,T_FLOAT);}
	               |WDOUBLE{mn.visitIntInsn(NEWARRAY,T_DOUBLE);})
	|	a=XTYPE ffTV=sInternalNameOrDescACC {
	                       line($a.line);
	                          mn.visitTypeInsn(getOp($a.text),Type.getType($ffTV.desc).getInternalName());
	            }
	|	a=JOP z=sLabel  { line($a.line); visitJOP(getOp($a.text),getLabel($z.text)); }
	|	a=XINVOKE e1=sMethodObject   {line($a.line);
	                    mn.visitMethodInsn(getOp($a.text),$e1.ownerInternalName,$e1.memberName,$e1.desc, false);
	                  }
	|	a=INVOKEINTERFACE e2=sMethodObject INT?  {line($a.line);
	                    mn.visitMethodInsn(getOp($a.text),$e2.ownerInternalName,$e2.memberName,$e2.desc, true);
	                  }
	|	a=INVOKEDYNAMIC e3=sMethodObject sId sMethodDesc '(' sInvokeDynamicE (',' sInvokeDynamicE)* ')'  {line($a.line); if(1==1) throw new RuntimeException("not support Yet!");}
	|	a=MULTIANEWARRAY ff=sClassDesc c=INT   {line($a.line); mn.visitMultiANewArrayInsn(unEscape($ff.text),parseInt($c.text)); }
	|   z=sLabel ':' { Label label=getLabel($z.text); mn.visitLabel(label); if(rebuildLine) {mn.visitLineNumber($z.start.getLine(),label);}
	 }
	|	'.catch' e=sId 'from' z1=sLabel 'to' z2=sLabel 'using' z3=sLabel { String type="all".equals($e.text)?null:unEscape($e.text); mn.visitTryCatchBlock(getLabel($z1.text),getLabel($z2.text),getLabel($z3.text),type); }
	|	'.limit' 'stack' ('?' { mn.maxStack=-1; } | i1=INT { mn.maxStack=parseInt($i1.text); })
	|	'.limit' 'locals' ('?' {mn.maxLocals=-1;}| i1=INT { mn.maxLocals=parseInt($i1.text);})
	|	'.code_attribute' sId STRING   { System.err.println("ignore .code_attribute"); }
	|	'.line' b=INT  { if(!rebuildLine) { Label label=new Label(); mn.visitLabel(label); mn.visitLineNumber(parseInt($b.text),label); } }
	|   '.var' var=INT 'is' mber=sMemberName desc=sClassDesc ('signature' sig=STRING)? 'from' z1=sLabel 'to' z2=sLabel  { mn.visitLocalVariable($mber.name,unEscape($desc.text),unEscapeString($sig.text),getLabel($z1.text),getLabel($z2.text),parseInt($var.text)); }
    |   sSwitch
	;
sInvokeDynamicE
	:	METHOD_DESC_WITHOUT_RET (INT|LONG|FLOAT|DOUBLE|STRING)
	;
sMethodDesc
	:	METHOD_DESC_WITHOUT_RET (sClassDesc|VOID_TYPE)
	;
sSwitch @init {List keys=null;List