zoukankan      html  css  js  c++  java
  • 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日--

  • 相关阅读:
    机器学习(八) 多项式回归与模型泛化(上)
    机器学习(七) PCA与梯度上升法 (下)
    机器学习(七) PCA与梯度上升法 (上)
    机器学习(六) 梯度下降法 (下)
    机器学习(六) 梯度下降法 (上)
    机器学习(五) 线性回归法 (下)
    机器学习(五) 线性回归法 (上)
    机器学习(四) 机器学习(四) 分类算法--K近邻算法 KNN (下)
    获取字符串中img标签的url集合(转载)
    微信上传文章素材—ASP.NET MVC从View层传数据到Controller层
  • 原文地址:https://www.cnblogs.com/heyang78/p/13025971.html
Copyright © 2011-2022 走看看