-
Notifications
You must be signed in to change notification settings - Fork 641
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 #9 from zavier/master
sync
- Loading branch information
Showing
80 changed files
with
3,380 additions
and
124 deletions.
There are no files selected for viewing
150 changes: 150 additions & 0 deletions
150
group01/1814014897/zhouhui/src/week06/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 |
---|---|---|
@@ -0,0 +1,150 @@ | ||
package week06.expr; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Stack; | ||
|
||
public class InfixExpr { | ||
String expr = null; | ||
|
||
public InfixExpr(String expr) { | ||
this.expr = expr; | ||
} | ||
|
||
public float evaluate() { | ||
float result = 0; | ||
|
||
Stack operandStack = new Stack(); // 运算数栈 | ||
Stack operaterStack = new Stack(); // 运算符栈 | ||
|
||
char[] exprCharArr = expr.toCharArray(); | ||
List<String> exprStringList = new ArrayList<String>(); | ||
addOperandAndOperater(exprCharArr, exprStringList); | ||
|
||
for (int i = 0; i < exprStringList.size(); i++) { | ||
if (isOperand(exprStringList.get(i))) { | ||
operandStack.push(exprStringList.get(i)); | ||
} else if (isOperater(exprStringList.get(i))) { | ||
operaterStack.push(exprStringList.get(i)); | ||
} else { | ||
throw new RuntimeException("this operater has not yet implemented."); | ||
} | ||
|
||
if (operaterStack.size() == 2) { | ||
|
||
String operater_1 = (String) operaterStack.pop(); | ||
String operater_2 = (String) operaterStack.pop(); | ||
if (hasTheSameOrHighPriority(operater_2, operater_1)) { | ||
|
||
String operand_1 = (String) operandStack.pop(); | ||
String operand_2 = (String) operandStack.pop(); | ||
operation(operandStack, operater_2, operand_1, operand_2); | ||
|
||
operaterStack.push(operater_1); | ||
} else if (hasTheLowPriority(operater_2, operater_1)) { | ||
|
||
operandStack.push(exprStringList.get(++i)); | ||
String operand_1 = (String) operandStack.pop(); | ||
String operand_2 = (String) operandStack.pop(); | ||
operation(operandStack, operater_1, operand_1, operand_2); | ||
|
||
operaterStack.push(operater_2); | ||
} | ||
} | ||
|
||
if (i == exprStringList.size() - 1) { | ||
|
||
String operater = (String) operaterStack.pop(); | ||
String operand_1 = (String) operandStack.pop(); | ||
String operand_2 = (String) operandStack.pop(); | ||
operation(operandStack, operater, operand_1, operand_2); | ||
|
||
result = (float) Integer.parseInt((String) operandStack.pop()); | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
private void addOperandAndOperater(char[] exprCharArr, List<String> exprStringList) { | ||
for (int i = 0; i < exprCharArr.length; i++) { | ||
if (isOperand(exprCharArr[i])) { | ||
StringBuilder sb = new StringBuilder(); | ||
sb.append(exprCharArr[i]); | ||
if (i < exprCharArr.length - 1) { | ||
while (i < exprCharArr.length - 1 && isOperand(exprCharArr[i + 1])) { | ||
sb.append(exprCharArr[i + 1]); | ||
i++; | ||
} | ||
} | ||
exprStringList.add(sb.toString()); | ||
} else if (isOperater(exprCharArr[i])) { | ||
exprStringList.add(exprCharArr[i] + ""); | ||
} | ||
} | ||
} | ||
|
||
private boolean isOperand(char c) { | ||
return !isOperater(c); | ||
} | ||
|
||
private boolean isOperater(char c) { | ||
if (c == '+' || c == '-' || c == '*' || c == '/') { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
private boolean isOperand(String c) { | ||
return !isOperater(c); | ||
} | ||
|
||
// 字符串相等用equals()比较. | ||
private boolean isOperater(String c) { | ||
if (c.equals("+") || c.equals("-") || c.equals("*") || c.equals("/")) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
// operater_1 has the same or high priority compare with the operater_2. | ||
private boolean hasTheSameOrHighPriority(Object operater_1, Object operater_2) { | ||
if ((operater_1.equals("+") && operater_2.equals("+")) || (operater_1.equals("+") && operater_2.equals("-")) | ||
|| (operater_1.equals("-") && operater_2.equals("+")) | ||
|| (operater_1.equals("-") && operater_2.equals("-")) | ||
|| (operater_1.equals("*") && operater_2.equals("*")) | ||
|| (operater_1.equals("*") && operater_2.equals("/")) | ||
|| (operater_1.equals("/") && operater_2.equals("*")) | ||
|| (operater_1.equals("/") && operater_2.equals("/")) | ||
|| (operater_1.equals("*") && operater_2.equals("+")) | ||
|| (operater_1.equals("*") && operater_2.equals("-")) | ||
|| (operater_1.equals("/") && operater_2.equals("+")) | ||
|| (operater_1.equals("/") && operater_2.equals("-"))) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
//// operater_1 has the low priority compare with the operater_2. | ||
private boolean hasTheLowPriority(Object operater_1, Object operater_2) { | ||
if ((operater_1.equals("+") && operater_2.equals("*")) || (operater_1.equals("+") && operater_2.equals("/")) | ||
|| (operater_1.equals("-") && operater_2.equals("*")) | ||
|| (operater_1.equals("-") && operater_2.equals("/"))) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
private void operation(Stack operandStack, String operater, String operand_1, String operand_2) { | ||
if (operater.equals("+")) { | ||
operandStack.push((Integer.parseInt(operand_2) + Integer.parseInt(operand_1)) + ""); | ||
} else if (operater.equals("-")) { | ||
operandStack.push((Integer.parseInt(operand_2) - Integer.parseInt(operand_1)) + ""); | ||
} else if (operater.equals("*")) { | ||
operandStack.push((Integer.parseInt(operand_2) * Integer.parseInt(operand_1)) + ""); | ||
} else if (operater.equals("/")) { | ||
operandStack.push((Integer.parseInt(operand_2) / Integer.parseInt(operand_1)) + ""); | ||
} | ||
} | ||
|
||
} |
48 changes: 48 additions & 0 deletions
48
group01/1814014897/zhouhui/src/week06/expr/InfixExprTest.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,48 @@ | ||
package week06.expr; | ||
|
||
import org.junit.After; | ||
import org.junit.Assert; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
|
||
public class InfixExprTest { | ||
|
||
@Before | ||
public void setUp() throws Exception { | ||
} | ||
|
||
@After | ||
public void tearDown() throws Exception { | ||
} | ||
|
||
@Test | ||
public void testEvaluate() { | ||
//InfixExpr expr = new InfixExpr("300*20+12*5-20/4"); | ||
{ | ||
InfixExpr expr = new InfixExpr("2+3*4+5"); | ||
Assert.assertEquals(19.0, expr.evaluate(), 0.001f); | ||
} | ||
{ | ||
InfixExpr expr = new InfixExpr("3*20+12*5-40/2"); | ||
Assert.assertEquals(100.0, expr.evaluate(), 0.001f); | ||
} | ||
|
||
{ | ||
InfixExpr expr = new InfixExpr("3*20/2"); | ||
Assert.assertEquals(30, expr.evaluate(), 0.001f); | ||
} | ||
|
||
{ | ||
InfixExpr expr = new InfixExpr("20/2*3"); | ||
Assert.assertEquals(30, expr.evaluate(), 0.001f); | ||
} | ||
|
||
{ | ||
InfixExpr expr = new InfixExpr("10-30+50"); | ||
Assert.assertEquals(30, expr.evaluate(), 0.001f); | ||
} | ||
|
||
} | ||
|
||
} |
19 changes: 19 additions & 0 deletions
19
group01/1814014897/zhouhui/src/week06/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,19 @@ | ||
package week06.jvm.attr; | ||
|
||
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; | ||
} | ||
|
||
|
||
} |
93 changes: 93 additions & 0 deletions
93
group01/1814014897/zhouhui/src/week06/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,93 @@ | ||
package week06.jvm.attr; | ||
|
||
import week06.jvm.clz.ClassFile; | ||
import week06.jvm.constant.ConstantPool; | ||
import week06.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 attrNameIndex = iter.nextU2ToInt(); | ||
int attrLen = iter.nextU4ToInt(); | ||
int maxStack = iter.nextU2ToInt(); | ||
int maxLocals = iter.nextU2ToInt(); | ||
int codeLen = iter.nextU4ToInt(); | ||
|
||
String code = iter.nextUxToHexString(codeLen); | ||
|
||
System.out.println(code); | ||
|
||
CodeAttr codeAttr = new CodeAttr(attrNameIndex, attrLen, maxStack, maxLocals, codeLen, code); | ||
|
||
int exceptionTableLen = iter.nextU2ToInt(); | ||
|
||
if (exceptionTableLen > 0) { | ||
String exTable = iter.nextUxToHexString(exceptionTableLen); | ||
System.out.println("Encountered exception table,just ignore it"); | ||
} | ||
|
||
int subAttrCount = iter.nextU2ToInt(); | ||
|
||
for (int i = 1; i <= subAttrCount; i++) { | ||
int subAttrIndex = iter.nextU2ToInt(); | ||
String subAttrName = clzFile.getConstantPool().getUTF8String(subAttrIndex); | ||
|
||
iter.back(2); | ||
|
||
if (AttributeInfo.LINE_NUM_TABLE.equalsIgnoreCase(subAttrName)) { | ||
LineNumberTable t = LineNumberTable.parse(iter); | ||
codeAttr.setLineNumberTable(t); | ||
} else if (AttributeInfo.LOCAL_VAR_TABLE.equalsIgnoreCase(subAttrName)) { | ||
LocalVariableTable t = LocalVariableTable.parse(iter); | ||
codeAttr.setLocalVariableTable(t); | ||
} else if (AttributeInfo.STACK_MAP_TABLE.equalsIgnoreCase(subAttrName)) { | ||
StackMapTable t = StackMapTable.parse(iter); | ||
codeAttr.setStackMapTable(t); | ||
} else { | ||
throw new RuntimeException("Need code to process " + subAttrName); | ||
} | ||
} | ||
|
||
return codeAttr; | ||
} | ||
|
||
private void setStackMapTable(StackMapTable t) { | ||
this.stackMapTable = t; | ||
|
||
} | ||
|
||
} |
54 changes: 54 additions & 0 deletions
54
group01/1814014897/zhouhui/src/week06/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,54 @@ | ||
package week06.jvm.attr; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import week06.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(ByteCodeIterator iter){ | ||
int index = iter.nextU2ToInt(); | ||
int len = iter.nextU4ToInt(); | ||
|
||
LineNumberTable table = new LineNumberTable(index, len); | ||
|
||
int itemLen = iter.nextU2ToInt(); | ||
|
||
for(int i=1;i<=itemLen;i++){ | ||
LineNumberItem item = new LineNumberItem(); | ||
item.setStartPC(iter.nextU2ToInt()); | ||
item.setLineNum(iter.nextU2ToInt()); | ||
table.addLineNumberItem(item); | ||
} | ||
return table; | ||
} | ||
|
||
|
||
|
||
} |
Oops, something went wrong.