Java课程project(SMAC计算器)----基于JavaSE
Java课程project(SMAC计算器)----基于JavaSE
新开了一门外教课程,Object-oriented Programming(JAVA),本章记录结课project。
This project is about making a Simple MAth Calculator (SMAC in the sequel) with some interesting features.
Author: ArthurWang
Enviroment: Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-48-generic x86_64)、openjdk 11.0.9.1
IDE: VScode
Introduction of functionalities
- Evaluate mathematical expressions made from numbers, operators (addition, subtraction, unary minus, multiplication, division, power) and parenthesis.
- Managing the precision of decimal.
- Define and use variables in mathematical expression. (Eg. let x = 3; reset x …)
- Managing errors. (Include ErrorException, SyntaxErrorException, LexicalErrorException, TokenException)
- Keeping track of the last value. (Eg. last …)
- Storing variables. (Eg. save “myfile”; load “myfile”; save “just-z-file” z …)
- Logging a session. (Eg. log “mylog”; log end …)
- More mathematical functions. (sin, cos, tan, abs)
Some ideas of design
- Singleton design idea and Multiton design idea.
- Factory design idea and Proxy design idea.
- Client (which is Smac.java) use the Interface to get service.
File structure
project: package of source file.
logFile: log file of user set log.
varFile: variables file of user set variable.
出于考虑该文章只贴出部分代码,即只给出了处理问题的逻辑方法。自定义的Exception文件、实现接口的Evaluator文件、Token、Test文件均没有贴出。
package project;public interface IEvaluator {// Creat Token with lexical analysis.public void createInputToken(String input) throws LexicalErrorException, TokenException;// Sysntax analysispublic boolean syntaxAnalysis() throws ErrorException, SyntaxErrorException, LexicalErrorException, TokenException;// Creat Mathematical evaluator and calculatepublic void mathEvaluator() throws ErrorException, SyntaxErrorException, TokenException;// Get varFile pathpublic void varFilePath(String path);// Println outputpublic void println(String len);// Print outputpublic void print(String len);// Log situtationpublic void logUserInput(String input);// Get varFile pathpublic void logFilePath(String path);// Log sessionpublic boolean logSession();}
package project;import java.util.*;/*** this class is to handle different keywords command.* the SyntaxAnalyzer just need to give the factory to process.*/
public class KeywordsCommFactory {private static final KeywordsCommFactory command = new KeywordsCommFactory();private KeywordsCommFactory() {}public static KeywordsCommFactory getKeywordsCommFactory() {return command;}public void factory(Tokenizer myTokenizer, Map<String, Double> variables)throws TokenException, SyntaxErrorException, ErrorException, LexicalErrorException {Token t = myTokenizer.readNextToken();if (t.getIdentifier().equals("let")) {letCommand(myTokenizer, variables);} else if (t.getIdentifier().equals("setprecision")) {precCommand(myTokenizer);} else if (t.getIdentifier().equals("reset")) {resetCommand(myTokenizer, variables);} else if (t.getIdentifier().equals("last")) {lastCommand(myTokenizer);} else if (t.getIdentifier().equals("save")) {saveCommand(myTokenizer, variables);} else if (t.getIdentifier().equals("saved")) {savedCommand(myTokenizer);}else if (t.getIdentifier().equals("load")){loadCommand(myTokenizer, variables);}else if (t.getIdentifier().equals("log")){logCommand(myTokenizer);}else if (t.getIdentifier().equals("logged")){loggerCommand(myTokenizer);}/** else if (t.getIdentifier().equals("define")){* }*/}/*** Command Process.* Different keywords, Factory use different method*/private void letCommand(Tokenizer myTokenizer, Map<String, Double> variables)throws SyntaxErrorException, TokenException {// only one "let" situtationif (!myTokenizer.hasNextToken()) {letCommandOutput(variables);return;}Token t = myTokenizer.readNextToken();if (!t.isIdentifier()) {throw new SyntaxErrorException("is not a vaild variable name");}String variable = t.getIdentifier();t = myTokenizer.readNextToken();if (!t.isEqual()) {throw new SyntaxErrorException("is not a vaild let command");}MathematicalEvaluator mathEvaluer = MathematicalEvaluator.getMathematicalEvaluator();Double value = mathEvaluer.calculate(myTokenizer, variables);if (value == null) {throw new SyntaxErrorException("is not a vaild let command");}variables.put(variable, value);ResOutput.getResOutput().println(value);}private void letCommandOutput(Map<String, Double> variables) {Iterator<String> it = variables.keySet().iterator();if (!it.hasNext()) {ResOutput.getResOutput().println("no variable defined");return;}while (it.hasNext()) {String var = it.next();ResOutput.getResOutput().println(var + " = " + variables.get(var));}}private void precCommand(Tokenizer myTokenizer) throws SyntaxErrorException, TokenException {// only one "setprecision" situtationif (!myTokenizer.hasNextToken()) {int precision = ResOutput.getResOutput().getPrecision();if (precision == -1) {ResOutput.getResOutput().println("current precision is default. You can set a precision");} else {ResOutput.getResOutput().println("current precision is " + precision);}return;}// if token is not a number or if myTokenizer has next token after the precision// value. Is worng.Token t = myTokenizer.readNextToken();if (!t.isNumber() || myTokenizer.hasNextToken()) {throw new SyntaxErrorException("is not a vaild precision");}// set the precisionString temp = String.valueOf(t.getNumber());String res = temp.substring(0, temp.indexOf("."));int prec = Integer.parseInt(res);ResOutput.getResOutput().setPrecision(prec);ResOutput.getResOutput().println("current precision is " + ResOutput.getResOutput().getPrecision());}private void resetCommand(Tokenizer myTokenizer, Map<String, Double> variables)throws SyntaxErrorException, TokenException {// only one "reset" situtation.if (!myTokenizer.hasNextToken()) {resetCommandOutput(variables);return;}while (myTokenizer.hasNextToken()) {Token t = myTokenizer.readNextToken();if (!t.isIdentifier()) {throw new SyntaxErrorException("is not a vaild variable name");}String variable = t.getIdentifier();if (variables.containsKey(variable)) {variables.remove(variable);ResOutput.getResOutput().println(variable + " has been reset");} else {ResOutput.getResOutput().println(variable + " not defined");}}}private void resetCommandOutput(Map<String, Double> variables) {Iterator<String> it = variables.keySet().iterator();if (!it.hasNext()) {ResOutput.getResOutput().println("no variable defined");return;}while (it.hasNext()) {String var = it.next();ResOutput.getResOutput().println(var + " has been reset");}variables.clear();}private void lastCommand(Tokenizer myTokenizer) throws SyntaxErrorException {if (myTokenizer.hasNextToken()) {throw new SyntaxErrorException("is not a vaild last command");}if (LastCaluNum.getLastCaluNum().getNum() == null) {ResOutput.getResOutput().println("no calculate resulet");return;}ResOutput.getResOutput().println(LastCaluNum.getLastCaluNum().getNum());}private void saveCommand(Tokenizer myTokenizer, Map<String, Double> variables) throws SyntaxErrorException, TokenException{// only one "save" situtationif (!myTokenizer.hasNextToken()) { throw new SyntaxErrorException("is not a vaild save command. Maybe try saved? "); }Token t = myTokenizer.readNextToken();if (!t.isString()){ throw new SyntaxErrorException("is not a vaild save command"); }String variable = t.getString();String file = variable.substring(1,variable.length()-1);if (myTokenizer.hasNextToken()){Token var = myTokenizer.readNextToken();if (var.isIdentifier()){StorVar.getStorVar().saveFileOneLetter(file, variables, var.getIdentifier());} else{throw new SyntaxErrorException("is not a vaild save command");}} else{StorVar.getStorVar().saveFile(file, variables);}if (myTokenizer.hasNextToken()) { throw new SyntaxErrorException("is not a vaild save command. You only can chose one variable."); }}private void savedCommand(Tokenizer myTokenizer) throws SyntaxErrorException{if (myTokenizer.hasNextToken()) { throw new SyntaxErrorException("is not a vaild saved command"); }StorVar.getStorVar().savedFile();}private void loadCommand(Tokenizer myTokenizer, Map<String, Double> variables) throws SyntaxErrorException, TokenException, ErrorException, LexicalErrorException {// only one "load" situtationif (!myTokenizer.hasNextToken()) { throw new SyntaxErrorException("is not a vaild load command. Please input the load file"); }Token t = myTokenizer.readNextToken();if (!t.isString()) { throw new SyntaxErrorException("is not a vaild load file."); }String file = t.getString().substring(1,t.getString().length()-1);ArrayList<String> res = StorVar.getStorVar().loadVar(file);for (int i = 0; i < res.size(); i++){myTokenizer = new Tokenizer(res.get(i));myTokenizer.readNextToken();letCommand(myTokenizer, variables);}}private void logCommand(Tokenizer myTokenizer) throws SyntaxErrorException, TokenException {// only "log" situtationif (!myTokenizer.hasNextToken()) { if (LogSe.getLoger().getLogActiveButton()) { ResOutput.getResOutput().println(LogSe.getLoger().getFile());}else {ResOutput.getResOutput().println("not in Logging session");}return;}Token t = myTokenizer.readNextToken();if (!t.isString()) {if (LogSe.getLoger().getLogActiveButton() && t.isIdentifier() && t.getIdentifier().equals("end")){ResOutput.getResOutput().println("session was logged to "+LogSe.getLoger().getFile());LogSe.getLoger().quitLoger();return;}else{throw new SyntaxErrorException("is not a vaild log command."); }}if (myTokenizer.hasNextToken()) { throw new SyntaxErrorException("is not a vaild log command."); }String file = t.getString().substring(1,t.getString().length()-1);LogSe.getLoger().setFile(file);ResOutput.getResOutput().println("logging session to "+file);LogSe.getLoger().activeLoger();}private void loggerCommand(Tokenizer myTokenizer) throws SyntaxErrorException {if (myTokenizer.hasNextToken()) { throw new SyntaxErrorException("is not a vaild logged command."); }Set<String> temp = LogSe.getLoger().getFileSet();temp.forEach( (str)->ResOutput.getResOutput().println(str) );}
}
package project;/*** last value trace class.* Because many class need to use last value, and reference transmit cause the reduency* so use this class to keep the last value.*/
public class LastCaluNum{private Double num;private static final LastCaluNum last = new LastCaluNum();private LastCaluNum(){}public static LastCaluNum getLastCaluNum(){return last;}public void setNum(Double num){this.num = num;}public Double getNum(){return this.num;}}
package project;import java.io.FileWriter;
import java.io.IOException;
import java.util.*;/*** this class for log situtation.*/
public class LogSe {private boolean logSesActiveButton;private String path;private Set<String> fileName;private String currentFile;public static final LogSe myLoger = new LogSe();private LogSe() {this.logSesActiveButton = false;this.path = "./"; // default situation to save logFile in project path.fileName = new HashSet<>();}public static LogSe getLoger(){return myLoger;}public void activeLoger() {this.logSesActiveButton = true;}public boolean getLogActiveButton() {return this.logSesActiveButton;}public void quitLoger(){this.logSesActiveButton = false;}public void setPath(String path) {this.path = path;}public String getPath() {return this.path;}public void setFile(String file){this.currentFile = file;if (!fileName.contains(currentFile)) { fileName.add(file); }}public String getFile(){return this.currentFile;}public Set<String> getFileSet(){return fileName;}public void writeLogFile(String input, boolean changeLenOrnNot) {try {FileWriter myFileWriter = new FileWriter(this.path + "/" + currentFile, true);write2File(myFileWriter, input, changeLenOrnNot);myFileWriter.close();} catch (Exception e) {e.printStackTrace();}}private void write2File(FileWriter myFileWriter, String text, boolean changeLenOrnNot) throws IOException {myFileWriter.write(text);if (changeLenOrnNot) { myFileWriter.write("\n"); }}
}
package project;
import java.util.*;public class MathematicalEvaluator{private Stack<Double> valueStack;private Stack<thisOp> operatorStack;private static final MathematicalEvaluator mathEvaluer = new MathematicalEvaluator();private MathematicalEvaluator(){valueStack = new Stack<>();operatorStack = new Stack<>();}public static MathematicalEvaluator getMathematicalEvaluator(){return mathEvaluer;}public Double calculate(Tokenizer tokenier, Map<String, Double> variables)throws TokenException, SyntaxErrorException{try{// init the stackif (!valueStack.isEmpty()) { valueStack.clear(); }if (!operatorStack.isEmpty()) { operatorStack.clear(); }while (tokenier.hasNextToken()){Token t = tokenier.readNextToken();if (t.isNumber()){valueStack.push(t.getNumber());}else if (t.isIdentifier()){idenProcess(t, variables);}else if (t.isOperator()){operaProcess(t);}else if (t.isDelimiter()){parenProces(t);}}while (!operatorStack.isEmpty()){loadNumCalu();}}catch(Exception e){throw new SyntaxErrorException("malformed expression");}if (!operatorStack.isEmpty() || valueStack.size() != 1){ throw new SyntaxErrorException("malformed expression"); }Double res = valueStack.pop();LastCaluNum.getLastCaluNum().setNum(res);return res;}private void idenProcess(Token t, Map<String, Double> variables) throws TokenException{if (moreMathFunAdd(t.getIdentifier())){operaIdenProcess(t);}else{if (t.getIdentifier().equals("last")){Double value = LastCaluNum.getLastCaluNum().getNum();valueStack.push(value);}else{Double value = variables.get(t.getIdentifier());valueStack.push(value);}}}private void operaIdenProcess(Token t) throws TokenException {thisOp op = new thisOp(t.getIdentifier());while (!operatorStack.isEmpty() && operatorStack.peek().getPriority() >= op.getPriority()){loadNumCalu();}operatorStack.push(op);}// add the more math fun.private boolean moreMathFunAdd(String operator){return operator.equals("cos")||operator.equals("sin")||operator.equals("tan")||operator.equals("abs");}private void parenProces(Token t) throws TokenException {if (t.getDelimiter().equals("(")){thisOp op = new thisOp("(");operatorStack.push(op);}else if (t.getDelimiter().equals(")")){while (!operatorStack.peek().getName().equals("(")){loadNumCalu();}operatorStack.pop();}}private void operaProcess(Token t) throws TokenException {thisOp op = new thisOp(t.getOperator());while (!operatorStack.isEmpty() && operatorStack.peek().getPriority() >= op.getPriority()){loadNumCalu();}operatorStack.push(op);}private void loadNumCalu() throws TokenException {thisOp op = operatorStack.pop();if (op.getArity() == 2){Double y = valueStack.pop();Double x = valueStack.pop();if (op.getName().equals("+")){add(x,y);}else if (op.getName().equals("-")){sub(x,y);}else if (op.getName().equals("*")){mul(x,y);}else if (op.getName().equals("/")){div(x,y);}else if (op.getName().equals("^")){exp(x,y);}}else if (op.getArity() == 1){Double x = valueStack.pop();if (op.getName().equals("~")){rev(x);}else if (op.getName().equals("cos")){cos(x);}else if (op.getName().equals("sin")){sin(x);}else if (op.getName().equals("tan")){tan(x);}else if (op.getName().equals("abs")){abs(x);}}}private void add(Double x, Double y){valueStack.push(x+y);}private void sub(Double x, Double y){valueStack.push(x-y);}private void mul(Double x, Double y){valueStack.push(x*y);}private void div(Double x, Double y){valueStack.push(x/y);}private void exp(Double x, Double y){valueStack.push(Math.pow(x, y));}private void rev(Double x){valueStack.push(-x);}private void cos(Double x){valueStack.push(Math.cos(x));}private void sin(Double x){valueStack.push(Math.sin(x));}private void tan(Double x){valueStack.push(Math.tan(x));}private void abs(Double x){valueStack.push(Math.abs(x));}}
package project;public class ResOutput{private int precision;private static final ResOutput outputer = new ResOutput();private ResOutput(){this.precision = -1; // Default precision. just Output.}public static ResOutput getResOutput(){return outputer;}public void setPrecision(int precision){this.precision = precision;}public int getPrecision(){return this.precision;}public void println(Double num){// user not set the precision. Just ouput the numif (this.precision == -1){String checkInt = String.valueOf(num);if (checkInt.indexOf('.') == checkInt.length() - 2 && checkInt.charAt(checkInt.length()-1) == '0'){myPrintln(checkInt.substring(0, checkInt.length() - 2));return;}myPrintln(checkInt);}else{String temp = String.valueOf(num);int index = temp.indexOf(".");if (this.precision == 0){// lose the decimal of num.String res = temp.substring(0, index);myPrintln(res);}else{if (index+1+this.precision >= temp.length()){myPrintln(temp);}else{String res = temp.substring(0, index+1+this.precision);myPrintln(res);}}}}private void myPrintln(String res){if (LogSe.getLoger().getLogActiveButton()) {LogSe.getLoger().writeLogFile(res, true);}System.out.println(res);}// overloadpublic void println(String len){if (LogSe.getLoger().getLogActiveButton()) {LogSe.getLoger().writeLogFile(len, true);}System.out.println(len);}public void print(String len){if (LogSe.getLoger().getLogActiveButton()) {LogSe.getLoger().writeLogFile(len, false);}System.out.print(len);}}
package project;import java.util.*;public class Smac{// path can be changed by client userpublic static final String VARPATH = "./varFile";public static final String LOGPATH = "./logFile";public static void main(String[] args) {Scanner console = new Scanner(System.in);// creat SMACIEvaluator smac = new Evaluator();smac.println("Welcome to SMAC");smac.print("> ");String input = console.nextLine().trim();smac.varFilePath(VARPATH);smac.logFilePath(LOGPATH);while (!input.equals("exit")) {try{smac.createInputToken(input);if (!smac.syntaxAnalysis()){smac.mathEvaluator();}}catch(Exception e){smac.println(e.toString());// use for debug// e.printStackTrace();}if(smac.logSession()){smac.print(">> ");input = console.nextLine();smac.logUserInput(input);}else{smac.print("> ");input = console.nextLine();}}console.close();smac.println("Thank you for using SMAC");}
}
package project;import java.util.*;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.IOException;/*** this class use IO to save variables and load(get saved) variables.*/public class StorVar {private static StorVar myStorer;private String path;private ArrayList<String> fileName;private StorVar(){ fileName = new ArrayList<>(); }public static StorVar getStorVar(){if (myStorer == null){myStorer = new StorVar();}return myStorer;}public void loadPath(String p){this.path = p;}public void saveFile(String file, Map<String, Double> variables){if (!fileName.contains(file)){ fileName.add(file); }if (variables.isEmpty()) { ResOutput.getResOutput().println("no variables to save"); return; }try{FileWriter myFileWriter = new FileWriter(this.path+"/"+file);writeVar2File(myFileWriter, variables);myFileWriter.close();ResOutput.getResOutput().println("variables saved in "+file);}catch (IOException e){e.toString();}}private void writeVar2File(FileWriter myFileWriter, Map<String, Double> variables) throws IOException {Iterator<String> it = variables.keySet().iterator();while (it.hasNext()){String var = it.next();Double value = variables.get(var);myFileWriter.write("let "+var+" = "+value);myFileWriter.write("\n");}}public void saveFileOneLetter(String file, Map<String, Double> variables, String variable){if (!fileName.contains(file)){ fileName.add(file); }if (variables.isEmpty()) { ResOutput.getResOutput().println("no variables to save"); return;}if (!variables.containsKey(variable)) { ResOutput.getResOutput().println("variable is not defined"); return;}try{FileWriter myFileWriter = new FileWriter(this.path+"/"+file);writeVar2File(myFileWriter, variable, variables);myFileWriter.close();ResOutput.getResOutput().println("variables saved in "+file);}catch (IOException e){e.toString();}}// overloadprivate void writeVar2File(FileWriter myFileWriter, String variable, Map<String, Double> variables) throws IOException {myFileWriter.write("let "+variable+" = "+variables.get(variable));}public void savedFile(){if (fileName.isEmpty()) { ResOutput.getResOutput().println("no file to save"); return; }for (String name : fileName) {ResOutput.getResOutput().println(name);}}public ArrayList<String> loadVar(String file) throws ErrorException {ArrayList<String> res = new ArrayList<>();try{BufferedReader myFileReader = new BufferedReader(new FileReader(this.path+"/"+file));readFile2Vars(myFileReader, res);myFileReader.close();ResOutput.getResOutput().println(file+" loaded");}catch (IOException e){throw new ErrorException("file is not exist");}return res;}private void readFile2Vars(BufferedReader myFileReader, ArrayList<String> res) throws IOException {String line;while ( (line = myFileReader.readLine()) != null) {res.add(line);}}
}
public class SyntaxAnalyzer{private static final SyntaxAnalyzer syntaxAnalyzer = new SyntaxAnalyzer();private SyntaxAnalyzer(){}public static SyntaxAnalyzer getSyntaxAnalyzer(){return syntaxAnalyzer;}public boolean analyse(Tokenizer myTokenizer, Set<String> keywords, Map<String, Double>variables)throws ErrorException, SyntaxErrorException, LexicalErrorException, TokenException {Token t = myTokenizer.peekNextToken();if (t.isNumber()) {return false;}else if (t.isDelimiter()){if (t.getDelimiter().equals("(")) { return false; }}else if (t.isIdentifier()){if (keywords.contains(t.getIdentifier())) {KeywordsCommFactory command = KeywordsCommFactory.getKeywordsCommFactory();command.factory(myTokenizer, variables);return true;}if (variables.containsKey(t.getIdentifier())) {return false;}else if (t.getIdentifier().equals("cos")||t.getIdentifier().equals("sin")||t.getIdentifier().equals("tan")||t.getIdentifier().equals("abs")){return false;}else {throw new ErrorException(t.getIdentifier() + " is not a variable");}}else {throw new SyntaxErrorException("not vaild input");}throw new SyntaxErrorException("not vaild input");}}
package project;public class thisOp{private String name;private int arity;private int priority;public thisOp(String name){this.name = name;this.arity = 0;this.priority = 0;}public String getName(){return this.name;}public int getArity() throws TokenException {switch(this.name){case"-":this.arity = 2;break;case"~":this.arity = 1;break;case"+":this.arity = 2;break;case"*":this.arity = 2;break;case"/":this.arity = 2;break;case"^":this.arity = 2;break;case"cos":this.arity = 1;break;case"sin":this.arity = 1;break;case"tan":this.arity = 1;break;case"abs":this.arity = 1;break;default:throw new TokenException("getArity worng");}return this.arity;}public int getPriority() throws TokenException {switch(this.name){case"-":this.priority = 1;break;case"~":this.priority = 2;break;case"+":this.priority = 1;break;case"*":this.priority = 2;break;case"/":this.priority = 2;break;case"^":this.priority = 3;break;case"(":this.priority = 0;break;case"cos":this.priority = 3;break;case"sin":this.priority = 3;break;case"tan":this.priority = 3;break;case"abs":this.priority = 3;break;default:throw new TokenException("getPriority worng");}return this.priority;}}
package project;import java.util.*;
import java.util.regex.Pattern;public class Tokenizer {private Deque<Token> que;private static final char[] DELIMITER = {'=', '(', ')', ',', '^', '*', '/', '+', '-'};public Tokenizer(String input)throws LexicalErrorException, TokenException{que = new LinkedList<>();String[] temp = input.trim().split("[ \u0009]+"); // [/t] will split the 't', so replace to [\u0009]inputToToken(temp);}/*** checks if there is more token to read*/public boolean hasNextToken() {return !que.isEmpty();}/*** returns the next token to be read* Throws a TokenException if there is* no more token to peek in the Tokenizer* YOU MAY ADD THROW CLAUSES TO THIS METHOD*/public Token peekNextToken() throws LexicalErrorException{if (!hasNextToken()) { throw new LexicalErrorException("no more token to peek"); }return que.peek();}/*** reads and returns the next token to be read* (i.e. the next token is removed from the tokenizer)* YOU MAY ADD THROW CLAUSES TO THIS METHOD*/public Token readNextToken() {return que.poll();}// add your private methods belowprivate void inputToToken(String myString[]) throws LexicalErrorException, TokenException {ArrayList<String> delier = new ArrayList<>();// split by delimiter(except space and tab) every line.for (int i = 0; i < myString.length; i++){splitEveryLine(delier, myString[i]);buildTokenList(delier);delier.clear();}}// split by delimiter(except space and tab) every line.private void splitEveryLine(ArrayList<String> delier, String myString){// split the string by delimiter.String temp = "";for (int i = 0; i < myString.length(); i++){if (findDeliChar(myString.charAt(i))){if (!temp.isEmpty()) { delier.add(temp); }delier.add(String.valueOf(myString.charAt(i)));temp = "";} else{temp = temp + myString.charAt(i);}}if (!temp.isEmpty()) { delier.add(temp); }}// search delimiter.private boolean findDeliChar(char target){for (int i = 0; i < DELIMITER.length; i++){if (target == DELIMITER[i]){ return true; }}return false;}// build token list.private void buildTokenList(ArrayList<String> delier) throws LexicalErrorException, TokenException {for (int i = 0; i < delier.size(); i++){factoryToken(delier.get(i));}}// use factory idea.private void factoryToken(String str) throws LexicalErrorException, TokenException {switch (str){case "=" :que.add(Token.makeEQUAL());break;case "(" :que.add(Token.makeOPENPAR());break;case ")" :que.add(Token.makeCLOSEPAR());break;case "," :que.add(Token.makeCOMMA());break;case "-" :if (que.isEmpty()){que.add(Token.makeUNARYMINUS());break;}if (que.getLast().isNumber() || que.getLast().isIdentifier() || (que.getLast().isDelimiter() && que.getLast().getDelimiter().equals(")")) ){que.add(Token.makeMINUS());break;}que.add(Token.makeUNARYMINUS());break;case "*":que.add(Token.makeTIMES());break;case "/":que.add(Token.makeDIVIDE());break;case "^":que.add(Token.makePOWER());break;case "+":que.add(Token.makePLUS());break;default:if (isNumeric(str)){double num = Double.parseDouble(str);que.add(Token.makeNUMBER(num));break;} else if (str.length() > 3 && str.charAt(0) == '"' && str.charAt(str.length()-1) == '"'){que.add(Token.makeSTRING(str));break;} else if (str.length() > 0 && isWord(str)){que.add(Token.makeIDENTIFIER(str));break;} else{throw new LexicalErrorException(str + " is not a valid character");}}}//use regex pattern to estimate is number or not.public boolean isNumeric(String str){ Pattern pattern = Pattern.compile("[.0-9]+");return pattern.matcher(str).matches();}// use regex pattern to estimate is legal variable or not.public static boolean isWord(String str){Pattern pattern = Pattern.compile("[a-zA-Z_0-9]+");Pattern firstChar = Pattern.compile("[_0-9]");return !firstChar.matcher(String.valueOf(str.charAt(0))).matches() && pattern.matcher(str).matches();}
}
Java课程project(SMAC计算器)----基于JavaSE相关推荐
- java计算机设计总结,java课程设计报告--计算器设计
java课程设计报告--计算器设计 1 课 程 Java 程序设计 题 目 计算器设计 年 级 2010 级 专 业 信息一班 学 号 姓 名 组 员 指导教师 课程设计题目计算器设计 2 课程设计论 ...
- Java课程设计-小学生计算器
功能 源码.经验交流QQ群:613879714,有问题QQ群提问,这里不能及时回复 1.功能 小学生计算器可以进行两位数的加减乘除运算 2.演示 B站演示视频链接 java课程设计-小学生计算器 3. ...
- java课程设计(计算器)
JAVA课程 设 计 报 告 1206401-18 瞿杰 一.设计时间 2013年6月 24日-----6月28日 二.设计地点 湖南城市学院实验楼计算机506机房 三.设计目的 1.巩固学习VB ...
- java课程设计拼图_基于Java拼图游戏的设计与实现(含录像)
基于拼图游戏的设计与实现(含录像) 摘 要 本拼图游戏是基于J2SE平台开发的,它是一个Application,它的游戏规则和诺亚舟里的拼图游戏是一样的.这个游戏将一张大图切割成N张小图,然后在 ...
- java课程设计简单计算器_JAVA课程设计--简易计算器(201521123022 黄俊麟)
1.团队课程设计博客链接 2.个人负责模板或任务说明 1.初始化业务逻辑. 2.开方.正负.清零.退格.数字内容输入拼接,输出结果的实现. 3.四则运算算法的实现. 4.每个按钮返回对应的业务(每个按 ...
- 计算器 毕业论文java_Java课程设计报告 计算器
文件大小:337.00KB 适用专业:Java 适用年级:大学 论文编号:37422 论文简介: Java课程设计报告 计算器,共22页,3333字. 目 录 目 录I 1需求分析1 1.1计算器的基 ...
- java课程设计 计算器_java课程设计-保存计算过程的计算器
java课程设计-保存计算过程的计算器 编号: <面向对象程序设计(JAVA) > 课程设计(论文)档案 题 目: 保存计算过程的计算器 学 院: 信息学院 专 业: 姓 名: 学 号: ...
- Java课程设计基于ssm的微信小程序
Java课程设计, 基于ssm的微信小程序 后端涉及技术spring.mysql等 效果查看请扫一扫 喜欢可以点赞哟
- 基于《悉尼协议》框架下Java课程案例教学研究
文章目录 基于<悉尼协议>框架下Java课程案例教学研究 一.Java课程教学存在问题 (一)Java课程目标定位不足 (二)Java课程教学存在的问题 1. 教材内容更新滞后 2. 学习 ...
最新文章
- 密码错误Neo.ClientError.Security.Unauthorized: The client is unauthorized due to authentication failure
- 使用ajaxfileupload.js实现文件上传
- How to Use Git
- 数组模拟队列(代码实现)
- 任正非:感谢美国,帮我把华为给全世界都宣传了
- 01-国内开源镜像站汇总
- PySide 简易教程二-------工欲善其事,必先利其器
- readonly 与 const
- 虚拟化系列-Windows server 2012 备份管理
- 对文字颜色从左到右(横向)渐变的一点理解(坑)
- Apollo添加新的can通信接口的GPS设备
- 苹果发布 iOS 14 Beta 8 iphone 14 GM要来咯
- J2SE - POI合并单元格相关
- 基于MATLAB的图像拼接实现
- python应该怎么样自学_Python该如何自学?
- ps剪贴蒙版教程(ps创建剪贴蒙版步骤)
- 计算机思维培训心得,计算机教师培训心得体会
- HOJ 2786 Convert Kilometers to Miles
- ASP.NET MVC 实现页落网资源分享网站+充值管理+后台管理(8)之文章管理
- Linux虚拟机的远程三种链接,以及各自的上网方式
热门文章
- mac os linux pageup pagedown,教你巧用Mac上的Page UpDown键
- 融合DE 端和FE端数据,利用小波变换生成时频图,再分别利用DCNN、KNN和DNN进行对比实验(python代码)
- 如何快速计算汉字笔画数
- java电话号码_java编程——电话号码查询系统
- AG7120与AG7220做HDMI信号延长放大器驱动方案讲解|AG7120与AG7220设计HDMI信号延长放大器电路参考
- sql 服务器停止运行,3.1.1 启动、停止、暂停和重新启动SQL Server服务
- shell常用语法之if [ $? -ne 0 ]
- MySQL练习(一)
- ITK 形态学中的开运算和闭运算 腐蚀 膨胀
- 数值计算笔记之非线性方程的求解(一)二分法