源码:https://files.cnblogs.com/files/heyang78/BasicInterpreter2-20200601-3.rar
改进后使得变量和字符串可以一起输出了。
输入脚本:
for x=1 to 9 for y=1 to x z=x*y print(y+"*"+x+"="+z+" ") next newline() next print("end")
输出:
原文=for x=1 to 9 for y=1 to x z=x*y print(y+"*"+x+"="+z+" ") next newline() next print("end") Tokens: 执行结果: 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 end
改进后的InterPreter类:
package com.heyang; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Stack; // 保存循环变量名,极限和for语句下首句起始位置的类 class LoopInfo{ public LoopInfo(String loopValueName,double limit,int startLocation) { this.loopValueName=loopValueName; this.limit=limit; this.startLocation=startLocation; } String loopValueName; double limit; int startLocation; } // 解释器类 public class InterPreter { private List<Token> tokens; private int tokenIdx; private Map<String,Double> varMap;// 用于存放变量的变量表 private Stack<LoopInfo> loopStack;// 用于存放循环的栈 // 构造函数 public InterPreter(List<Token> tokens){ this.tokens=tokens; this.tokenIdx=0; varMap=new HashMap<String,Double>(); loopStack=new Stack<LoopInfo>(); } // 执行程序 public void execute() throws Exception{ Token token; for(;;) { token=fetchToken(); if(token==null) { return; } if(token.getType()==Token.TYPE_VARIABLE) { returnToken(); doAssignment(); }else if(token.getType()==Token.TYPE_FUNCTION) { String fname=token.getText(); if("print".equalsIgnoreCase(fname)) { doPrint(); }if("newline".equalsIgnoreCase(fname)) { doNewline(); } }else if(token.getType()==Token.TYPE_IF) { returnToken(); doIf(); }else if(token.getType()==Token.TYPE_ELSE) { doElse(); }else if(token.getType()==Token.TYPE_FOR) { doFor(); }else if(token.getType()==Token.TYPE_NEXT) { doNext(); } } } // Next语句处理 private void doNext() throws Exception{ LoopInfo info=loopStack.pop(); String varName=info.loopValueName; Double value=loadVariable(varName); if(value==null) { throw new Exception("Not found variable:'"+varName); } double variableValue=value+1; saveVariable(info.loopValueName, variableValue); if(variableValue>info.limit) { // }else { loopStack.push(info); tokenIdx=info.startLocation; } } // For循环 private void doFor() throws Exception{ Token token=fetchToken(); if(token.getType()!=Token.TYPE_VARIABLE) { throw new Exception("Expected:variable actual:"+token.getText()+" "+token); } String varibleName=token.getText(); token=fetchToken(); if(token.getType()==Token.TYPE_ASSIGN) { token=fetchToken(); if(token.getType()==Token.TYPE_DIGITAL) { double value=Double.parseDouble(token.getText()); saveVariable(varibleName, value); } }else { throw new Exception("Expected:'=' actual:"+token.getText()+" "+token); } token=fetchToken(); if(token.getType()!=Token.TYPE_TO) { throw new Exception("Expected:to actual:"+token.getText()+" "+token); } double limit; token=fetchToken(); if(token.getType()==Token.TYPE_DIGITAL) { limit=Double.parseDouble(token.getText()); }else if(token.getType()==Token.TYPE_VARIABLE) { String varName=token.getText(); Double value=loadVariable(varName); if(value==null) { throw new Exception("Not found variable:'"+varName+" token:"+token); } limit=value; }else { throw new Exception("Expected:digital/variable actual:"+token.getText()+" "+token); } double variableValue=loadVariable(varibleName); if(variableValue<=limit) { loopStack.push(new LoopInfo(varibleName,limit,tokenIdx)); }else { fetchToken(); } } // Else语句处理 private void doElse() throws Exception{ // 走到这里说明是if的肯定分支,因此需要跳过去 Token token; do { token=fetchToken(); }while(token.getType()!=Token.TYPE_ENDIF) ; } // If语句处理 private void doIf() throws Exception{ Token token=fetchToken(); if(token.getType()!=Token.TYPE_IF) { throw new Exception("Expected:if actual:"+token.getText()+" "+token); } double left; token=fetchToken(); if(token.getType()==Token.TYPE_DIGITAL) { left=Double.parseDouble(token.getText()); }else if(token.getType()==Token.TYPE_VARIABLE) { String varName=token.getText(); Double value=loadVariable(varName); if(value==null) { throw new Exception("Not found variable:'"+varName+" token:"+token); } left=value; }else { throw new Exception("Expected:digital/variable actual:"+token.getText()+" "+token); } String oprand; token=fetchToken(); if(token.getType()!=Token.TYPE_EQUAL && token.getType()!=Token.TYPE_LESSTHAN && token.getType()!=Token.TYPE_LESSEUQALTHAN && token.getType()!=Token.TYPE_BIGGERTHAN && token.getType()!=Token.TYPE_BIGGEREQUALTHAN ) { throw new Exception("Expected:comparison symbol, actual:"+token.getText()+" "+token); } oprand=token.getText(); double right; token=fetchToken(); if(token.getType()==Token.TYPE_DIGITAL) { right=Double.parseDouble(token.getText()); }else if(token.getType()==Token.TYPE_VARIABLE) { String varName=token.getText(); Double value=loadVariable(varName); if(value==null) { throw new Exception("Not found variable:'"+varName+" token:"+token); } right=value; }else { throw new Exception("Expected:digital/variable actual:"+token.getText()+" "+token); } if(compare(left,oprand,right)) { token=fetchToken(); if(token.getType()!=Token.TYPE_THEN) { throw new Exception("Expected:'then' actual:"+token.getText()+" "+token); } }else { do { token=fetchToken(); }while(token.getType()!=Token.TYPE_ENDIF && token.getType()!=Token.TYPE_ELSE) ; } } // 左右比较 private boolean compare(double vLeft,String oprand,double vRight){ if("==".equals(oprand)) { return vLeft==vRight; }else if(">".equals(oprand)) { return vLeft>vRight; }else if(">=".equals(oprand)) { return vLeft>=vRight; }else if("<".equals(oprand)) { return vLeft<vRight; }else if("<=".equals(oprand)) { return vLeft<=vRight; }else { return false; } } // 打印新行 private void doNewline() throws Exception{ Token token=fetchToken(); if(token.getType()!=Token.TYPE_OPEN_PARENTHESIS) { throw new Exception("Expected:'(' actual:"+token.getText()+" "+token); } System.out.println(); token=fetchToken(); if(token.getType()!=Token.TYPE_CLOSE_PARENTHESIS) { throw new Exception("Expected:')' actual:"+token.getText()+" "+token); } } // 打印 private void doPrint() throws Exception{ Token token=fetchToken(); if(token.getType()!=Token.TYPE_OPEN_PARENTHESIS) { throw new Exception("Expected:'(' actual:"+token.getText()+" "+token); } do { token=fetchToken(); if(token.getType()==Token.TYPE_VARIABLE) { String varName=token.getText(); Double value=loadVariable(varName); if(value==null) { throw new Exception("Not found variable:'"+varName+" token:"+token); } try { int i=value.intValue(); System.out.print(i); }catch(Exception ex) { System.out.print(value); } }else if(token.getType()==Token.TYPE_STRING){ String str=token.getText(); if(str.startsWith(""") && str.endsWith(""") ) { System.out.print(str.substring(1, str.length()-1)); }else { System.out.print(str); } }else if(token.getType()==Token.TYPE_PLUS) { // do nothing }else { break; } }while(token.getType()!=Token.TYPE_CLOSE_PARENTHESIS); if(token.getType()!=Token.TYPE_CLOSE_PARENTHESIS) { throw new Exception("Expected:')' actual:"+token.getText()+" "+token); } } // 赋值 private void doAssignment() throws Exception{ Token token=fetchToken(); if(token.getType()!=Token.TYPE_VARIABLE) { throw new Exception("Expected:variable actual:"+token.getText()+" "+token); } String varName=token.getText(); token=fetchToken(); if(token.getType()!=Token.TYPE_ASSIGN) { throw new Exception("Expected:= actual:"+token.getText()+" "+token); } double varValue=parse_expression(); saveVariable(varName,varValue); } // 解析表达式 private double parse_expression() throws Exception{ double left,right; Token currentToken; left=parse_term(); for(;;) { currentToken=fetchToken(); if(currentToken==null) { return left; } if(currentToken.getType()!=Token.TYPE_PLUS && currentToken.getType()!=Token.TYPE_MINUS) { returnToken(); break; } right=parse_term(); if(currentToken.getType()==Token.TYPE_PLUS) { left+= right; }else if(currentToken.getType()==Token.TYPE_MINUS) { left-= right; }else { returnToken(); } } return left; } // 解析乘除 private double parse_term() throws Exception{ double left,right; Token currentToken; left=parse_primary_exp(); for(;;) { currentToken=fetchToken(); if(currentToken==null) { return left; } if(currentToken.getType()!=Token.TYPE_MULTI && currentToken.getType()!=Token.TYPE_DIVIDE) { returnToken(); break; } right=parse_primary_exp(); if(currentToken.getType()==Token.TYPE_MULTI) { left*= right; }else if(currentToken.getType()==Token.TYPE_DIVIDE) { left/= right; } } return left; } // 解析数字/变量/表达式 private double parse_primary_exp() throws Exception{ Token token; double retval=0.0; token=fetchToken(); if(token==null) { return 0; } if(token.getType()==Token.TYPE_DIGITAL) { retval= Double.parseDouble(token.getText()); return retval; }else if(token.getType()==Token.TYPE_VARIABLE) { String varName=token.getText(); Double d=loadVariable(varName); if(d==null) { throw new Exception("Not found variable:'"+varName+" token:"+token); } return d; }else if(token.getType()==Token.TYPE_OPEN_PARENTHESIS){ retval=parse_expression(); token=fetchToken(); if(token==null) { return retval; } if(token.getType()!=Token.TYPE_CLOSE_PARENTHESIS) { throw new Exception("missing )"); } return retval; }else { throw new Exception(token+" should be a digital."); } } // 取标记 private Token fetchToken() { if(tokenIdx>=tokens.size()) { return null; }else { Token t=tokens.get(tokenIdx); tokenIdx++; return t; } } // 退回标记 private void returnToken() { if(tokenIdx>0) { tokenIdx--; } } // 保存变量进变量表 private void saveVariable(String name,double value) { varMap.put(name, value); } // 取得变量值从变量表 private Double loadVariable(String name) { if(varMap.containsKey(name)) { return varMap.get(name); }else { return null; } } }
--2020年6月1日--