📄 sourcecodeparser.java
字号:
* like :
* [Exception Table:
* start=line73 , end=line78 , handler=line78 , catch_type=java.lang.Exception]
* @param s
* @param map
* @return
* @throws ParsingException
* @throws GrammerException
* TODO: error reporting missing labels
*/
private Attribute_Code.ExceptionTableItem[] parseExceptionTable(String s, Hashtable map) throws ParsingException, GrammerException {
Scanner sc;
sc = Scanner.partialScanner(scanner.getContent(), scanner.getOffset() + 1, scanner.getLength() - 2, scanner.getColumnNumberStart() + 1,
scanner.getLineNumberStart());
ArrayList excs = new ArrayList();
int start, end, handler, catch_type;
sc.nextToken();
if (sc.nextToken() != Colon) {
exception(sc, "':'.expected");
}
sc.nextToken();
while (sc.tokenType() != EOF) {
if ("start".equals(sc.token()) == false) {
exception(sc, "'start'.expected.here");
}
if (sc.nextToken() != Equal) {
exception(scanner, "'='.expected.here");
}
sc.nextToken();
start = getOffset(sc.token(), map, false);
if (sc.nextToken() != Comma) {
exception(sc, "','.expected.here");
}
sc.nextToken();
if ("end".equals(sc.token()) == false) {
exception(sc, "'end'.expected.here");
}
if (sc.nextToken() != Equal) {
exception(sc, "'='.expected.here");
}
sc.nextToken();
end = getOffset(sc.token(), map, false);
if (sc.nextToken() != Comma) {
exception(sc, "','.expected.here");
}
sc.nextToken();
if ("handler".equals(sc.token()) == false) {
exception(sc, "'handler'.expected.here");
}
if (sc.nextToken() != Equal) {
exception(sc, "'='.expected.here");
}
sc.nextToken();
handler = getOffset(sc.token(), map, false);
if (sc.nextToken() != Comma) {
exception(sc, "','.expected.here");
}
sc.nextToken();
if ("catch_type".equals(sc.token()) == false) {
exception(sc, "'catch_type'.expected.here");
}
if (sc.nextToken() != Equal) {
exception(sc, "'='.expected.here");
}
sc.nextToken();
if ("0".equals(sc.token())) {
catch_type = 0;
} else {
catch_type = cpl.addClass(sc.token());
}
excs.add(new Attribute_Code.ExceptionTableItem(start, end, handler, catch_type));
sc.nextToken();
}
return (Attribute_Code.ExceptionTableItem[]) excs.toArray(new Attribute_Code.ExceptionTableItem[excs.size()]);
}
/**
*
* @param label
* @param map
* @param countingInstructionLength if false, will return the starting offset of this insctruction.
* else will return the end offset of this instruction
* @return
*/
private int getOffset(String label, Hashtable map, boolean countingInstructionLength) throws GrammerException {
Attribute_Code.Opcode op = (Attribute_Code.Opcode) map.get(label);
if (op == null) {
return -1;
}
if (countingInstructionLength == false) {
return op.offset;
} else {
return op.offset + Constants.NO_OF_OPERANDS[op.opcode & 0xFF] + 1;
}
}
private Attribute parseAttribute() throws GrammerException, ParsingException {
String s = scanner.token();
Attribute att;
if (s.indexOf(Constants.ATTRIBUTE_NAME_DEPRECATED) != -1) {
att = new Attribute_Deprecated();
att.attribute_name_index = cpl.addUtf8("Deprecated");
scanner.nextToken();
return att;
} else if (s.indexOf(Constants.ATTRIBUTE_NAME_SYNTHETIC) != -1) {
att = new Attribute_Synthetic();
att.attribute_name_index = cpl.addUtf8("Synthetic");
scanner.nextToken();
return att;
} else if (s.indexOf(Constants.ATTRIBUTE_NAME_SOURCE_FILE) != -1) {
att = new Attribute_SourceFile(2, cpl.addUtf8(s.substring(s.lastIndexOf(':') + 1, s.length() - 1).trim()));
att.attribute_name_index = cpl.addUtf8("SourceFile");
scanner.nextToken();
return att;
} else {
exception(scanner, "can.not.process.attribute");
}
return null;
}
/**
* like :
* [Inner Classes :
* access = final class , name = 0 , fullname = jce.TestClass$1 , outername = 0]
* @param s
* @return
*/
private Attribute_InnerClasses parseInnerClasses() throws ParsingException, GrammerException {
Scanner sc;//
sc = Scanner.partialScanner(scanner.getContent(), scanner.getOffset() + 1, scanner.getLength() - 2, scanner.getColumnNumberStart() + 1,
scanner.getLineNumberStart());
ArrayList ins = new ArrayList();
int access_flag = 0, inner_name_index, inner_class_info, outer_class_info;
sc.nextToken();
if (sc.nextToken() != Colon) {
exception(sc, "':'.expected");
}
sc.nextToken();
while (sc.tokenType() != EOF) {
if ("access".equals(sc.token()) == false) {
exception(sc, "'access'.expected.here");
}
if (sc.nextToken() != Equal) {
exception(sc, "'='.expected.here");
}
while (sc.nextToken() == AccessFlag) {
access_flag = Util.getAccessFlag_Class(sc.token()) | access_flag;
}
if (sc.tokenType() != Comma) {
exception(sc, "','.expected.here");
}
sc.nextToken();
if ("name".equals(sc.token()) == false) {
exception(sc, "'name'.expected.here");
}
if (sc.nextToken() != Equal) {
exception(sc, "'='.expected.here");
}
sc.nextToken();
if ("0".equals(sc.token()) == true) {
inner_name_index = 0;
} else {
inner_name_index = cpl.addUtf8(sc.token());
}
if (sc.nextToken() != Comma) {
exception(sc, "','.expected.here");
}
sc.nextToken();
if ("fullname".equals(sc.token()) == false) {
exception(sc, "'fullname'.expected.here");
}
if (sc.nextToken() != Equal) {
exception(sc, "'='.expected.here");
}
sc.nextToken();
inner_class_info = cpl.addClass(sc.token());
if (sc.nextToken() != Comma) {
exception(sc, "','.expected.here");
}
sc.nextToken();
if ("outername".equals(sc.token()) == false) {
exception(sc, "'outername'.expected.here");
}
if (sc.nextToken() != Equal) {
exception(sc, "'='.expected.here");
}
sc.nextToken();
if ("0".equals(sc.token())) {
outer_class_info = 0;
} else {
outer_class_info = cpl.addClass(sc.token());
}
sc.nextToken();
ins.add(new Attribute_InnerClasses.InnerClass(inner_class_info, outer_class_info, inner_name_index, access_flag));
}
Attribute_InnerClasses ret = new Attribute_InnerClasses(8 * ins.size() + 2, ins.size(), (Attribute_InnerClasses.InnerClass[]) ins
.toArray(new Attribute_InnerClasses.InnerClass[ins.size()]));
ret.attribute_name_index = cpl.addUtf8("InnerClasses");
return ret;
}
private void parseClassAttributes() throws GrammerException, ParsingException {
String s;
ArrayList attributes = new ArrayList(4);
int colonIndex , nameIndex;
while (scanner.tokenType() == Attribute) {
s = scanner.token();
colonIndex = s.indexOf(':');
nameIndex = s.indexOf(Constants.ATTRIBUTE_NAME_INNER_CLASSES);
if (nameIndex!=-1 && nameIndex<colonIndex) {
// this is necessary, or [SourceFile : Attribute_InnerClasses.java] will be parsed as innerclass
attributes.add(parseInnerClasses());
scanner.nextToken();
} else {
attributes.add(parseAttribute());
}
}
javaClass.attributes = (Attribute[]) attributes.toArray(new Attribute[attributes.size()]);
javaClass.attributes_count = attributes.size();
}
private void parseMaxStackOrLocals(Attribute_Code code) throws ParsingException {
Scanner sc = Scanner.partialScanner(scanner.getContent(), scanner.getOffset() + 1, scanner.getLength() - 2,
scanner.getColumnNumberStart() + 1, scanner.getLineNumberStart());
sc.nextToken();
if (sc.token().equals(Constants.ATTRIBUTE_NAME_MAX_STACK) == true) {
if (sc.nextToken() != Colon) {
exception(sc, "':'.expected.here");
}
if (sc.nextToken() != Number_Integer) {
exception(sc, "invalid.max.stack.value");
}
code.max_stack = parseInteger(sc.token());
} else if (sc.token().equals(Constants.ATTRIBUTE_NAME_MAX_LOCAL) == true) {
if (sc.nextToken() != Colon) {
exception(sc, "':'.expected.here");
}
if (sc.nextToken() != Number_Integer) {
exception(sc, "invalid.max.local.value");
}
code.max_locals = parseInteger(sc.token());
}
}
private void parseMajorOrMinor() throws GrammerException, ParsingException {
String s;
while (scanner.tokenType() == Attribute) {
s = scanner.token();
if (s.indexOf(Constants.ATTRIBUTE_NAME_MAJOR_VERSION) != -1) {
try {
javaClass.major_version = parseInteger(s.substring(s.indexOf(':') + 1, s.lastIndexOf(']')).trim());
} catch (NumberFormatException ne) {
exception(scanner, "invalid.major.version.definition");
}
} else if (s.indexOf(Constants.ATTRIBUTE_NAME_MINOR_VERSION) != -1) {
try {
javaClass.minor_version = parseInteger(s.substring(s.indexOf(':') + 1, s.lastIndexOf(']')).trim());
} catch (NumberFormatException ne) {
exception(scanner, "invalid.minor.version.definition");
}
} else {
exception(scanner, "unexpected.attribute.here");
}
scanner.nextToken();
}
}
private static int parseInteger(String s) {
if (s.startsWith("0x") || s.startsWith("0X")) {
return Integer.parseInt(s.substring(2), 16);
} else {
return Integer.parseInt(s);
}
}
private static long parseLong(String s) {
if (s.endsWith("l") || s.endsWith("L")) {
s = s.substring(0, s.length() - 1);
}
if (s.startsWith("0x") || s.startsWith("0X")) {
return Long.parseLong(s.substring(2), 16);
} else {
return Long.parseLong(s);
}
}
private static float parseFloat(String s) {
if (s.endsWith("f") || s.endsWith("F")) {
s = s.substring(0, s.length() - 1);
}
return Float.parseFloat(s);
}
private static double parseDouble(String s) {
if (s.endsWith("d") || s.endsWith("D")) {
s = s.substring(0, s.length() - 1);
}
return Double.parseDouble(s);
}
private static void exception(Scanner sc, String msg) throws ParsingException {
throw new GrammerException(sc.getOffset(), sc.getLineNumberStart(), sc.getColumnNumberStart(), msg);
}
private static class OpcodeWrapper extends Attribute_Code.Opcode {
public Object info = null;
public OpcodeWrapper(Attribute_Code.Opcode op) {
super.offset = op.offset;
super.opcode = op.opcode;
super.operands = op.operands;
}
public OpcodeWrapper(int offset, byte opcode, byte[][] operands, Object info) {
super(offset, opcode, operands);
this.info = info;
}
}
private class LabeledInstructions {
Attribute_Code.Opcode[] codes;
Hashtable labels;
int codeLength;
public LabeledInstructions(Attribute_Code.Opcode[] codes, Hashtable labels, int code_length) {
this.codes = codes;
this.labels = labels;
this.codeLength = code_length;
}
}
public static void main(String[] args) throws Exception {
SourceCodeParser pa = new SourceCodeParser("e:\\work\\TestClass.jc");
pa.parse();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -