BasicInterpreter2 改进版,简化了print函数

源码: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日--

posted @ 2020-06-01 16:42  逆火狂飙  阅读(145)  评论(0编辑  收藏  举报
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东