• BasicInterpreter1.00 运行简单Basic脚本 打印变量及字符串


    源码下载:https://files.cnblogs.com/files/heyang78/basicInterpreter-20200529-1.rar

    脚本:

    count=10
    print(count)
    count=20
    print(count)
    print(cnt)
    print("Hello!Interpreter!")

    说明:

    count=10      赋值语句,变量count赋值为10,变量count不需定义
    print(count)   打印变量count里的值
    count=20      赋值语句,变量count赋值为20
    print(count)  打印变量count里的值
    print(cnt)    打印变量cnt里的值
    print("Hello!Interpreter!") 打印字符串"Hello!Interpreter!"

    执行结果:

    原文=count=10 print(count) count=20 print(count) print(cnt) print("Hello!Interpreter!") 
    Index                Type No              Text                 Type Desc            
    ------------------------------------------------------------------------------------
    0                    6                    count                Variable             
    1                    2                    =                    =                    
    2                    4                    10                   Number               
    3                    7                    print                Function             
    4                    0                    (                    (                    
    5                    6                    count                Variable             
    6                    1                    )                    )                    
    7                    6                    count                Variable             
    8                    2                    =                    =                    
    9                    4                    20                   Number               
    10                   7                    print                Function             
    11                   0                    (                    (                    
    12                   6                    count                Variable             
    13                   1                    )                    )                    
    14                   7                    print                Function             
    15                   0                    (                    (                    
    16                   6                    cnt                  Variable             
    17                   1                    )                    )                    
    18                   7                    print                Function             
    19                   0                    (                    (                    
    20                   5                    "Hello!Interpreter!" String               
    21                   1                    )                    )                    
    
    执行结果:
    
    10
    20
    Variable:'cnt' was not assigned.
    "Hello!Interpreter!"

    核心程序:

    Token类:

    package com.heyang;
    
    public class Token {
        public static final int TYPE_OPEN_PARENTHESIS=0;        // (
        public static final int TYPE_CLOSE_PARENTHESIS=1;        // (
        public static final int TYPE_EQUAL=2;                    // =
        public static final int TYPE_NUMBER=4;                    // d+
        public static final int TYPE_STRING=5;                    // w+
        public static final int TYPE_VARIABLE=6;                // Variable
        public static final int TYPE_FUNCTION=7;                // Function
        
        private int type;
        private String text;
        private int index;// Used to remember location
        
        public Token(char c,int type) {
            this.text=String.valueOf(c);
            this.type=type;
        }
        
        public Token(String word,int type) {
            this.text=word;
            this.type=type;
        }
        
        public String toString() {
            return String.format("token(text=%s,type=%s,index=%d)", text,getTypeStr(),index);
        }
        
        public String getTypeStr() {
            if(type==TYPE_OPEN_PARENTHESIS) {
                return "(";
            }else if(type==TYPE_CLOSE_PARENTHESIS) {
                return ")";
            }else if(type==TYPE_EQUAL) {
                return "=";
            }else if(type==TYPE_NUMBER) {
                return "Number";
            }else if(type==TYPE_STRING) {
                return "String";
            }else if(type==TYPE_VARIABLE) {
                return "Variable";
            }else if(type==TYPE_FUNCTION) {
                return "Function";
            }
            
            return null;
        }
    
        public int getType() {
            return type;
        }
    
        public void setType(int type) {
            this.type = type;
        }
    
        public String getText() {
            return text;
        }
    
        public void setText(String text) {
            this.text = text;
        }
    
        public int getIndex() {
            return index;
        }
    
        public void setIndex(int index) {
            this.index = index;
        }
    }

    Lexer类:

    package com.heyang;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.regex.Pattern;
    
    /**
     * Parse json string to tokens
     * @author Heyang
     *
     */
    public class Lexer {
        private List<Token> tokens;
    
        public Lexer(String jsonTxt) {
            tokens = new ArrayList<Token>();
    
            String swallowed = "";
            for (int i = 0; i < jsonTxt.length(); i++) {
                char c = jsonTxt.charAt(i);
    
                if (Character.isWhitespace(c)) {
                    addTextToList(swallowed);
                    swallowed="";
                    continue;
                } else if (c == '(') {
                    addTextToList(swallowed);
                    swallowed="";
                    
                    tokens.add(new Token(c, Token.TYPE_OPEN_PARENTHESIS));
                } else if (c == ')') {
                    addTextToList(swallowed);
                    swallowed="";
                    
                    tokens.add(new Token(c, Token.TYPE_CLOSE_PARENTHESIS));
                } else if (c == '=') {
                    addTextToList(swallowed);
                    swallowed="";
                    
                    tokens.add(new Token(c, Token.TYPE_EQUAL));
                } else if(c == '"') {
                    addTextToList(swallowed);
                    swallowed="";
                    
                    int idx=i+1;
                    
                    while(idx<jsonTxt.length()) {
                        char cEnd = jsonTxt.charAt(idx);
                        
                        if (cEnd == '"') {
                            break;
                        }
                        
                        idx++;
                    }
                    
                    String sub=jsonTxt.substring(i, idx+1);
                    tokens.add(new Token(sub, Token.TYPE_STRING));
                    i=idx;
                } else {
                    swallowed += c;
                }
            }
            
            setTokenIndexes();
        }
        
        private void addTextToList(String text) {
            if(isFunction(text)) {
                tokens.add(new Token(text, Token.TYPE_FUNCTION));
            }else if(isNumber(text)) {
                tokens.add(new Token(text, Token.TYPE_NUMBER));
            }else if(isVarable(text)) {
                tokens.add(new Token(text, Token.TYPE_VARIABLE));
            }
        }
        
        private boolean isFunction(String text) {
            if("print".equalsIgnoreCase(text)) {
                return true;
            }
            
            return false;
        }
        
        private boolean isNumber(String code) {
            final String patternStr = "\d+";
            return Pattern.matches(patternStr, code);
        }
        
        private boolean isVarable(String code) {
            final String patternStr = "([a-zA-Z_])\w*";
            return Pattern.matches(patternStr, code);
        }
        
        public void printTokens() {
            final String continuousStar = createRepeatedStr("-", 84);
            final String layout = "%-20s %-20s %-20s %-20s %s";
            StringBuilder sb = new StringBuilder();
    
            sb.append(String.format(layout, "Index", "Type No","Text","Type Desc","
    "));
            sb.append(continuousStar + "
    ");
            int index=0;
            for(Token token:tokens) {
                sb.append(String.format(layout, String.valueOf(index),String.valueOf(token.getType()), token.getText(),token.getTypeStr(),"
    "));
                index++;
            }
            
            System.out.println(sb.toString());
        }
        
        private static String createRepeatedStr(String seed, int n) {
            return String.join("", Collections.nCopies(n, seed));
        }
    
        public void setTokenIndexes() {
            int idx = 0;
            for (Token t : tokens) {
                idx++;
                t.setIndex(idx);
            }
        }
        
        public String getCompactJsonTxt() {
            StringBuilder sb=new StringBuilder();
            
            for (Token t : tokens) {
                sb.append(t.getText());
            }
            
            return sb.toString();
        }
        
        public List<Token> getTokenList() {
            return tokens;
        }
    }

    Interpreter类:

    package com.heyang;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class Interpreter {
        private List<Token> tokens;
        private int tokenIdx;
        
        public Interpreter(List<Token> tokens) throws Exception{
            this.tokens=tokens;
            this.tokenIdx=0;
            
            execute();
        }
        
        private void execute() throws Exception{
            Map<String,Integer> varmap=new HashMap<String,Integer>();
            Token token;
            for(;;) {
                token=fetchToken();
                if(token==null) {
                    return;
                }
                
                if(token.getType()==Token.TYPE_VARIABLE) {
                    String varibleName=token.getText();
                    
                    token=fetchToken();
                    if(token.getType()==Token.TYPE_EQUAL) {
                        token=fetchToken();
                        
                        if(token.getType()==Token.TYPE_NUMBER) {
                            int variableValue=Integer.parseInt(token.getText());
                            
                            // 赋值核心语句
                            varmap.put(varibleName, variableValue);
                        }
                    }else {
                        throw new Exception("Expected:'=' actual:"+token.getText()+" "+token);
                    }
                }else if(token.getType()==Token.TYPE_FUNCTION) {
                    String functionName=token.getText();
                    
                    if("print".equalsIgnoreCase(functionName)) {
                        token=fetchToken();
                        if(token.getType()!=Token.TYPE_OPEN_PARENTHESIS) {
                            throw new Exception("Expected:'(' actual:"+token.getText()+" "+token);
                        }
                        
                        token=fetchToken();
                        if(token.getType()==Token.TYPE_STRING) {
                            // 打印字符串
                            String str=token.getText();
                            System.out.println(str);
                        }else if(token.getType()==Token.TYPE_VARIABLE) {
                            String varibleName=token.getText();
                            
                            // 打印变量
                            if(varmap.containsKey(varibleName)) {
                                int value=varmap.get(varibleName);
                                System.out.println(value);
                            }else {
                                System.out.println("Variable:'"+varibleName+"' was not assigned.");
                            }
                        }
                    }
                }
            }
        }
        
        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--;
            }
        }
    }

    整合:

    package com.heyang;
    
    import com.heyang.util.BracketChecker;
    import com.heyang.util.CommonUtil;
    import com.heyang.util.Renderer;
    
    public class EntryPoint {
        public static void main(String[] args) {
            try {
                // Read context from file
                String text=CommonUtil.readTextFromFile("C:\hy\files\basic\01.basic");
                System.out.println("原文="+text);
                
                // Is brackets balanced
                BracketChecker checker=new BracketChecker();
                boolean isBalanced=checker.isBalanced(text);
                if(isBalanced==false) {
                    System.out.println(Renderer.paintBrown(checker.getErrMsg()));
                    return;
                }
                
                // lex text to tokens
                Lexer lex=new Lexer(text);
                lex.printTokens();
                
                // Execute
                System.out.println("执行结果:
    ");
                new Interpreter(lex.getTokenList());
            }catch(Exception ex) {
                System.out.println(Renderer.paintBrown(ex.getMessage()));
                ex.printStackTrace();
            }
        }
    }

    感慨:在《Java编程艺术》的指引下,解释器的第一步踏出了。

    --2020年5月29日--

  • 相关阅读:
    代码之美
    一点对互联网的浅薄理解
    angularjs填写表单
    一种通用数据采集的schema定义形式
    maven常用命令
    find which process occupy the PORT
    Mac上安装boost开放环境
    codeforces 581B Luxurious Houses
    codeforces 599A Patrick and Shopping
    codeforces 597A Divisibility
  • 原文地址:https://www.cnblogs.com/heyang78/p/12988230.html
Copyright © 2020-2023  润新知