forked from onlyliuxin/coding2017
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from zavier/master
sync
- Loading branch information
Showing
54 changed files
with
2,192 additions
and
262 deletions.
There are no files selected for viewing
155 changes: 141 additions & 14 deletions
155
group01/280646174/basic/src/main/java/com/coding2017/basic/stack/expr/InfixExpr.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,145 @@ | ||
package com.coding2017.basic.stack.expr; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Stack; | ||
import java.util.stream.Collectors; | ||
|
||
import com.google.common.base.CharMatcher; | ||
import com.google.common.collect.Lists; | ||
|
||
public class InfixExpr { | ||
String expr = null; | ||
|
||
public InfixExpr(String expr) { | ||
this.expr = expr; | ||
} | ||
|
||
public float evaluate() { | ||
|
||
return 0.0f; | ||
} | ||
|
||
|
||
|
||
|
||
private static final CharMatcher CHAR_MATCHER = CharMatcher.anyOf(Operator.allOperator()); | ||
|
||
private Stack<String> operatorStack = new Stack<>(); | ||
private Stack<Float> numberStack = new Stack<>(); | ||
|
||
String expr = null; | ||
|
||
public InfixExpr(String expr) { | ||
this.expr = expr; | ||
} | ||
|
||
public float evaluate() { | ||
List<String> list = splitByOperator(expr); | ||
for (String s : list) { | ||
if (Operator.isOperator(s)) { | ||
if (operatorStack.isEmpty()) { | ||
operatorStack.push(s); | ||
} else { | ||
while (true) { | ||
String op = operatorStack.peek(); | ||
if (Operator.opOf(op).getPriority() >= Operator.opOf(s).getPriority()) { | ||
calculateOnce(); | ||
} else { | ||
break; | ||
} | ||
if (operatorStack.isEmpty()) { | ||
break; | ||
} | ||
} | ||
operatorStack.push(s); | ||
} | ||
} else { | ||
numberStack.push(Float.parseFloat(s)); | ||
} | ||
} | ||
while (!operatorStack.isEmpty()) { | ||
calculateOnce(); | ||
} | ||
if (numberStack.isEmpty() || numberStack.size() != 1) { | ||
throw new RuntimeException("expr error"); | ||
} | ||
return numberStack.pop(); | ||
} | ||
|
||
private void calculateOnce() { | ||
String operator = operatorStack.pop(); | ||
Float secondNumber = numberStack.pop(); | ||
Float firstNumber = numberStack.pop(); | ||
Float calculate = calculate(firstNumber, secondNumber, operator); | ||
numberStack.push(calculate); | ||
} | ||
|
||
private Float calculate(Float firstNumber, Float seconfNumber, String operator) { | ||
if (Operator.ADD.getOp().equals(operator)) { | ||
return firstNumber + seconfNumber; | ||
} else if (Operator.MINUTE.getOp().equals(operator)) { | ||
return firstNumber - seconfNumber; | ||
} else if (Operator.MULTIPLY.getOp().equals(operator)) { | ||
return firstNumber * seconfNumber; | ||
} else if (Operator.DIVIDE.getOp().equals(operator)) { | ||
return firstNumber / seconfNumber; | ||
} | ||
return null; | ||
} | ||
|
||
private List<String> splitByOperator(String expr) { | ||
int pos = 0; | ||
List<String> list = Lists.newArrayList(); | ||
while (pos < expr.length()) { | ||
int index = CHAR_MATCHER.indexIn(expr, pos); | ||
if (index < 0) { | ||
list.add(expr.substring(pos).trim()); | ||
pos = expr.length(); | ||
} else { | ||
list.add(expr.substring(pos, index).trim()); | ||
list.add(expr.substring(index, index + 1)); | ||
pos = index + 1; | ||
} | ||
} | ||
return list; | ||
} | ||
|
||
enum Operator { | ||
ADD("+", 1), MINUTE("-", 1), MULTIPLY("*", 2), DIVIDE("/", 2); | ||
|
||
private String op; | ||
private int priority; | ||
|
||
Operator(String op, int priority) { | ||
this.op = op; | ||
this.priority = priority; | ||
} | ||
|
||
public static Operator opOf(String op) { | ||
for (Operator operator : values()) { | ||
if (operator.getOp().equals(op)) { | ||
return operator; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
public static boolean isOperator(String op) { | ||
for (Operator operator : values()) { | ||
if (operator.getOp().equals(op)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
public static String allOperator() { | ||
return Arrays.stream(values()).map(Operator::getOp).collect(Collectors.joining()); | ||
} | ||
|
||
public String getOp() { | ||
return op; | ||
} | ||
|
||
public void setOp(String op) { | ||
this.op = op; | ||
} | ||
|
||
public int getPriority() { | ||
return priority; | ||
} | ||
|
||
public void setPriority(int priority) { | ||
this.priority = priority; | ||
} | ||
|
||
} | ||
|
||
} |
39 changes: 39 additions & 0 deletions
39
group01/280646174/jvm/src/main/java/com/coding2017/jvm/attr/AttributeInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.coding2017.jvm.attr; | ||
|
||
import com.coding2017.jvm.clz.ClassFile; | ||
import com.coding2017.jvm.loader.ByteCodeIterator; | ||
|
||
public abstract class AttributeInfo { | ||
public static final String CODE = "Code"; | ||
public static final String CONST_VALUE = "ConstantValue"; | ||
public static final String EXCEPTIONS = "Exceptions"; | ||
public static final String LINE_NUM_TABLE = "LineNumberTable"; | ||
public static final String LOCAL_VAR_TABLE = "LocalVariableTable"; | ||
public static final String STACK_MAP_TABLE = "StackMapTable"; | ||
int attrNameIndex; | ||
int attrLen; | ||
|
||
public AttributeInfo(int attrNameIndex, int attrLen) { | ||
|
||
this.attrNameIndex = attrNameIndex; | ||
this.attrLen = attrLen; | ||
} | ||
|
||
public static AttributeInfo parse(ClassFile clzFile, ByteCodeIterator iter) { | ||
int nameIndex = iter.nextU2ToInt(); | ||
String name = clzFile.getConstantPool().getUTF8String(nameIndex); | ||
int length = iter.nextU4ToInt(); | ||
if (AttributeInfo.CODE.equals(name)) { | ||
return CodeAttr.parse(clzFile, iter, nameIndex, length); | ||
} else if (AttributeInfo.LINE_NUM_TABLE.equals(name)) { | ||
return LineNumberTable.parse(clzFile, iter, nameIndex, length); | ||
} else if (AttributeInfo.LOCAL_VAR_TABLE.equals(name)) { | ||
return LocalVariableTable.parse(clzFile, iter, nameIndex, length); | ||
} else if (AttributeInfo.STACK_MAP_TABLE.equals(name)) { | ||
return StackMapTable.parse(clzFile, iter, nameIndex, length); | ||
} else { | ||
throw new RuntimeException("not support attribute " + name); | ||
} | ||
} | ||
|
||
} |
73 changes: 73 additions & 0 deletions
73
group01/280646174/jvm/src/main/java/com/coding2017/jvm/attr/CodeAttr.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package com.coding2017.jvm.attr; | ||
|
||
import com.coding2017.jvm.clz.ClassFile; | ||
import com.coding2017.jvm.loader.ByteCodeIterator; | ||
|
||
public class CodeAttr extends AttributeInfo { | ||
private int maxStack; | ||
private int maxLocals; | ||
private int codeLen; | ||
private String code; | ||
|
||
public String getCode() { | ||
return code; | ||
} | ||
|
||
// private ByteCodeCommand[] cmds ; | ||
// public ByteCodeCommand[] getCmds() { | ||
// return cmds; | ||
// } | ||
private LineNumberTable lineNumTable; | ||
private LocalVariableTable localVarTable; | ||
private StackMapTable stackMapTable; | ||
|
||
public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen, | ||
String code /* ByteCodeCommand[] cmds */) { | ||
super(attrNameIndex, attrLen); | ||
this.maxStack = maxStack; | ||
this.maxLocals = maxLocals; | ||
this.codeLen = codeLen; | ||
this.code = code; | ||
// this.cmds = cmds; | ||
} | ||
|
||
public void setLineNumberTable(LineNumberTable t) { | ||
this.lineNumTable = t; | ||
} | ||
|
||
public void setLocalVariableTable(LocalVariableTable t) { | ||
this.localVarTable = t; | ||
} | ||
|
||
public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter, int nameIndex, int length) { | ||
int maxStack = iter.nextU2ToInt(); | ||
int maxLocals = iter.nextU2ToInt(); | ||
int codeLength = iter.nextU4ToInt(); | ||
String code = iter.nextUxToHexString(codeLength); | ||
CodeAttr codeAttr = new CodeAttr(nameIndex, length, maxStack, maxLocals, codeLength, code); | ||
int exceptionTableLength = iter.nextU2ToInt(); | ||
if(exceptionTableLength > 0){ | ||
String exTable = iter.nextUxToHexString(exceptionTableLength * 8); | ||
System.out.println("Encountered exception table , just ignore it :" + exTable); | ||
|
||
} | ||
int codeAttributeCount = iter.nextU2ToInt(); | ||
for (int j = 0; j < codeAttributeCount; j++) { | ||
AttributeInfo attributeInfo = AttributeInfo.parse(clzFile, iter); | ||
if (attributeInfo instanceof LineNumberTable) { | ||
codeAttr.setLineNumberTable((LineNumberTable) attributeInfo); | ||
} else if (attributeInfo instanceof LocalVariableTable) { | ||
codeAttr.setLocalVariableTable((LocalVariableTable) attributeInfo); | ||
} else if (attributeInfo instanceof StackMapTable) { | ||
codeAttr.setStackMapTable((StackMapTable) attributeInfo); | ||
} | ||
} | ||
return codeAttr; | ||
} | ||
|
||
private void setStackMapTable(StackMapTable t) { | ||
this.stackMapTable = t; | ||
|
||
} | ||
|
||
} |
55 changes: 55 additions & 0 deletions
55
group01/280646174/jvm/src/main/java/com/coding2017/jvm/attr/LineNumberTable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package com.coding2017.jvm.attr; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import com.coding2017.jvm.clz.ClassFile; | ||
import com.coding2017.jvm.loader.ByteCodeIterator; | ||
|
||
public class LineNumberTable extends AttributeInfo { | ||
List<LineNumberItem> items = new ArrayList<LineNumberItem>(); | ||
|
||
private static class LineNumberItem { | ||
int startPC; | ||
int lineNum; | ||
|
||
public int getStartPC() { | ||
return startPC; | ||
} | ||
|
||
public void setStartPC(int startPC) { | ||
this.startPC = startPC; | ||
} | ||
|
||
public int getLineNum() { | ||
return lineNum; | ||
} | ||
|
||
public void setLineNum(int lineNum) { | ||
this.lineNum = lineNum; | ||
} | ||
} | ||
|
||
public void addLineNumberItem(LineNumberItem item) { | ||
this.items.add(item); | ||
} | ||
|
||
public LineNumberTable(int attrNameIndex, int attrLen) { | ||
super(attrNameIndex, attrLen); | ||
|
||
} | ||
|
||
public static LineNumberTable parse(ClassFile clzFile, ByteCodeIterator iter, int nameIndex, int length) { | ||
int tableLength = iter.nextU2ToInt(); | ||
LineNumberTable lineNumberTable = new LineNumberTable(nameIndex, length); | ||
for (int i = 0; i < tableLength; i++) { | ||
LineNumberItem item = new LineNumberItem(); | ||
item.setStartPC(iter.nextU2ToInt()); | ||
item.setLineNum(iter.nextU2ToInt()); | ||
lineNumberTable.addLineNumberItem(item); | ||
} | ||
|
||
return lineNumberTable; | ||
} | ||
|
||
} |
49 changes: 49 additions & 0 deletions
49
group01/280646174/jvm/src/main/java/com/coding2017/jvm/attr/LocalVariableItem.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.coding2017.jvm.attr; | ||
|
||
public class LocalVariableItem { | ||
private int startPC; | ||
private int length; | ||
private int nameIndex; | ||
private int descIndex; | ||
private int index; | ||
|
||
public int getStartPC() { | ||
return startPC; | ||
} | ||
|
||
public void setStartPC(int startPC) { | ||
this.startPC = startPC; | ||
} | ||
|
||
public int getLength() { | ||
return length; | ||
} | ||
|
||
public void setLength(int length) { | ||
this.length = length; | ||
} | ||
|
||
public int getNameIndex() { | ||
return nameIndex; | ||
} | ||
|
||
public void setNameIndex(int nameIndex) { | ||
this.nameIndex = nameIndex; | ||
} | ||
|
||
public int getDescIndex() { | ||
return descIndex; | ||
} | ||
|
||
public void setDescIndex(int descIndex) { | ||
this.descIndex = descIndex; | ||
} | ||
|
||
public int getIndex() { | ||
return index; | ||
} | ||
|
||
public void setIndex(int index) { | ||
this.index = index; | ||
} | ||
} |
Oops, something went wrong.