Skip to content

Commit

Permalink
Merge pull request #9 from zavier/master
Browse files Browse the repository at this point in the history
sync
  • Loading branch information
Viscaria233 authored Apr 24, 2017
2 parents f4038da + 67a8222 commit f81a31d
Show file tree
Hide file tree
Showing 80 changed files with 3,380 additions and 124 deletions.
150 changes: 150 additions & 0 deletions group01/1814014897/zhouhui/src/week06/expr/InfixExpr.java
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 group01/1814014897/zhouhui/src/week06/expr/InfixExprTest.java
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 group01/1814014897/zhouhui/src/week06/jvm/attr/AttributeInfo.java
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 group01/1814014897/zhouhui/src/week06/jvm/attr/CodeAttr.java
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;

}

}
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;
}



}
Loading

0 comments on commit f81a31d

Please sign in to comment.