Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.github.wdn.coding2017.basic.stack.expr;

import com.github.wdn.coding2017.basic.Stack;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
* Created by Administrator on 2017/4/13 0013.
*/
public class InfixExpr {
private String expr;
private static Map<String,Integer> priorityMap = new HashMap();
static{
priorityMap.put("+",1);
priorityMap.put("-",1);
priorityMap.put("*",2);
priorityMap.put("/",2);
}
public InfixExpr(String expr) {
this.expr = expr;
}
public float calculate(float a,float b,String operator) throws IllegalAccessException {
float result;
switch (operator) {
case "+":
result = a+b;
break;
case "-":
result = a-b;
break;
case "*":
result = a*b;
break;
case "/":
result = a/b;
break;
default:
throw new IllegalAccessException();
}
return result;
}
public float evaluate() {
try {
String[] numArr = expr.split("[+|\\-|*|/]");
String[] operatorArr = expr.split("\\d+\\d*");
Object[] operators = Arrays.stream(operatorArr).filter(x -> !"".equals(x.trim())).toArray();
Stack numStack = new Stack();
Stack operatorStack = new Stack();
numStack.push(numArr[0]);
for (int i = 0; i < operators.length; i++) {
int number = Integer.parseInt(numArr[i + 1]);
String operator = operators[i].toString();
if (!operatorStack.isEmpty() && priorityMap.get(operatorStack.peek()) < priorityMap.get(operator)) {
float currentResult = calculate(Integer.parseInt(numStack.pop().toString()), number, operator);
numStack.push(currentResult);
} else if(!operatorStack.isEmpty() && priorityMap.get(operatorStack.peek()) >= priorityMap.get(operator)){
float b = Float.parseFloat(numStack.pop().toString());
float a = Float.parseFloat(numStack.pop().toString());
String currentOperator = operatorStack.pop().toString();
float result = calculate(a, b, currentOperator);
numStack.push(result);
numStack.push(number);
operatorStack.push(operator);
}else {
numStack.push(number);
operatorStack.push(operator);
}
}
while (!operatorStack.isEmpty()) {
float b = Float.parseFloat(numStack.pop().toString());
float a = Float.parseFloat(numStack.pop().toString());
String operator = operatorStack.pop().toString();
float result = calculate(a, b, operator);
numStack.push(result);
}
return Float.parseFloat(numStack.pop().toString());
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}

public static void main(String[] args) {
InfixExpr infixExpr = new InfixExpr("2+3*4+5");
float r = infixExpr.evaluate();
System.out.println(r);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.github.wdn.coding2017.basic.stack.expr;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
* Created by Administrator on 2017/4/13 0013.
*/
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);
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.github.wdn.coding2017.jvm.attr;

/**
* Created by Administrator on 2017/4/12 0012.
*/
public 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";

private int attributeNameIndex;// u2
private int attributeLength; //u4
public AttributeInfo(int attributeNameIndex,int attributeLength){
this.attributeNameIndex = attributeNameIndex;
this.attributeLength = attributeLength;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.github.wdn.coding2017.jvm.attr;

/**
* Created by Administrator on 2017/4/12 0012.
*/
public class CodeAttr extends AttributeInfo {
private int maxStack;
private int maxLocals;
private String code;
private LineNumberTable lineNumTable;
private LocalVariableTable localVarTable;
private StackMapTable stackMapTable;
public CodeAttr(int attributeNameIndex, int attributeLength, int maxStack, int maxLocals, String code) {
super(attributeNameIndex, attributeLength);
this.maxStack = maxStack;
this.maxLocals = maxLocals;
this.code = code;
}
@Override
public String toString(){
return code;
}
public int getMaxStack() {
return maxStack;
}

public void setMaxStack(int maxStack) {
this.maxStack = maxStack;
}

public int getMaxLocals() {
return maxLocals;
}

public void setMaxLocals(int maxLocals) {
this.maxLocals = maxLocals;
}

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

public void setLineNumTable(LineNumberTable lineNumTable) {
this.lineNumTable = lineNumTable;
}

public void setLocalVarTable(LocalVariableTable localVarTable) {
this.localVarTable = localVarTable;
}

public void setStackMapTable(StackMapTable stackMapTable) {
this.stackMapTable = stackMapTable;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.github.wdn.coding2017.jvm.attr;

import com.github.wdn.coding2017.jvm.constant.ConstantPool;
import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator;

import java.util.ArrayList;
import java.util.List;

/**
* Created by Administrator on 2017/4/12 0012.
*/
public class LineNumberTable extends AttributeInfo{
public LineNumberTable(int attributeNameIndex, int attributeLength) {
super(attributeNameIndex, attributeLength);
}
List<LineNumberItem> lineNumberItems = new ArrayList<>();
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.lineNumberItems.add(item);
}

public static LineNumberTable parse(ByteCodeIterator iter){
LineNumberTable lineNumberTable = new LineNumberTable(0, iter.readU4ToInt());
int lineNumberTableCount = iter.readU2ToInt();
for (int l = 0; l < lineNumberTableCount; l++) {
LineNumberItem lineNumberItem = new LineNumberItem();
lineNumberItem.setStartPC(iter.readU2ToInt());
lineNumberItem.setLineNum(iter.readU2ToInt());
lineNumberTable.addLineNumberItem(lineNumberItem);
}
return lineNumberTable;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.github.wdn.coding2017.jvm.attr;

import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator;

import java.util.ArrayList;
import java.util.List;

/**
* Created by Administrator on 2017/4/12 0012.
*/
public class LocalVariableTable extends AttributeInfo{
List<LocalVariableTableItem> localVariableTableItems = new ArrayList<>();
public LocalVariableTable(int attributeNameIndex, int attributeLength) {
super(attributeNameIndex, attributeLength);
}
private static class LocalVariableTableItem{
int startPC;
int length;
int nameIndex;
int descriptorIndex;
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 getDescriptorIndex() {
return descriptorIndex;
}

public void setDescriptorIndex(int descriptorIndex) {
this.descriptorIndex = descriptorIndex;
}

public int getIndex() {
return index;
}

public void setIndex(int index) {
this.index = index;
}
}
private void addLocalVariableItem(LocalVariableTableItem item){
this.localVariableTableItems.add(item);
}
public static LocalVariableTable parse(ByteCodeIterator iter) {
LocalVariableTable localVariableTable = new LocalVariableTable(iter.readU2ToInt(),iter.readU2ToInt());
int LocalVariableTableCount = iter.readU2ToInt();
for (int l = 0; l < LocalVariableTableCount; l++) {
LocalVariableTableItem item = new LocalVariableTableItem();
item.setStartPC(iter.readU2ToInt());
item.setLength(iter.readU2ToInt());
item.setNameIndex(iter.readU2ToInt());
item.setDescriptorIndex(iter.readU2ToInt());
item.setIndex(iter.readU2ToInt());
localVariableTable.addLocalVariableItem(item);
}
return localVariableTable;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.github.wdn.coding2017.jvm.attr;

/**
* Created by Administrator on 2017/4/12 0012.
*/
public class LocalVariableTypeTable {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.github.wdn.coding2017.jvm.attr;

import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator;

/**
* Created by Administrator on 2017/4/12 0012.
*/
public class StackMapTable extends AttributeInfo{
private String originalCode;

public StackMapTable(int attrNameIndex, int attrLen) {
super(attrNameIndex, attrLen);
}

public static StackMapTable parse(ByteCodeIterator iter){
int index = iter.readU2ToInt();
int len = iter.readU4ToInt();
StackMapTable t = new StackMapTable(index,len);
//后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存
String code = iter.readCustomToString(len);
t.setOriginalCode(code);
return t;
}

private void setOriginalCode(String code) {
this.originalCode = code;

}
}
Loading