
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
© 2015 - 2025 Weber Informatics LLC | Privacy Policy