zoukankan      html  css  js  c++  java
  • basicInterpreter1.01 支持分支语句

    源码:https://files.cnblogs.com/files/heyang78/basicInterpreter-20200531-1.rar

    输入:

    count=10
    print(count)
    if count==10 then print("count等于10")
    if count<20 then print("count小于20")
    if count>5 then print("count大于5")
    print("程序结束")

    输出:

    原文=count=10 print(count) if count==10 then print("count等于10") if count<20 then print("count小于20") if count>5 then print("count大于5") print("程序结束") 
    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                    9                    if                   if                   
    8                    6                    count                Variable             
    9                    8                    ==                   ==                   
    10                   4                    10                   Number               
    11                   10                   then                 then                 
    12                   7                    print                Function             
    13                   0                    (                    (                    
    14                   5                    "count等于10"          String               
    15                   1                    )                    )                    
    16                   9                    if                   if                   
    17                   6                    count                Variable             
    18                   10                   <                    then                 
    19                   4                    20                   Number               
    20                   10                   then                 then                 
    21                   7                    print                Function             
    22                   0                    (                    (                    
    23                   5                    "count小于20"          String               
    24                   1                    )                    )                    
    25                   9                    if                   if                   
    26                   6                    count                Variable             
    27                   11                   >                    >                    
    28                   4                    5                    Number               
    29                   10                   then                 then                 
    30                   7                    print                Function             
    31                   0                    (                    (                    
    32                   5                    "count大于5"           String               
    33                   1                    )                    )                    
    34                   7                    print                Function             
    35                   0                    (                    (                    
    36                   5                    "程序结束"               String               
    37                   1                    )                    )                    
    
    执行结果:
    
    10
    "count等于10"
    "count小于20"
    "count大于5"
    "程序结束"

    核心代码:

    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_ASSIGN=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
        public static final int TYPE_EQUAL=8;                    // ==
        public static final int TYPE_IF=9;                        // if
        public static final int TYPE_THEN=10;                    // then
        public static final int TYPE_LESSTHAN=10;                // <
        public static final int TYPE_BIGGERTHAN=11;                // >
        
        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_ASSIGN) {
                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";
            }else if(type==TYPE_EQUAL) {
                return "==";
            }else if(type==TYPE_IF) {
                return "if";
            }else if(type==TYPE_THEN) {
                return "then";
            }else if(type==TYPE_LESSTHAN) {
                return "<";
            }else if(type==TYPE_BIGGERTHAN) {
                return ">";
            }
            
            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 text) {
            tokens = new ArrayList<Token>();
    
            String swallowed = "";
            for (int i = 0; i < text.length(); i++) {
                char c = text.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_BIGGERTHAN));
                }else if (c == '<') {
                    addTextToList(swallowed);
                    swallowed="";
                    
                    tokens.add(new Token(c, Token.TYPE_LESSTHAN));
                } else if (c == '=') {
                    int next=i+1;
                    if(next<text.length() && text.charAt(next)=='=') {
                        // ==
                        addTextToList(swallowed);
                        swallowed="";
                        tokens.add(new Token("==",Token.TYPE_EQUAL));
                        i++;
                    }else {
                        // =
                        addTextToList(swallowed);
                        swallowed="";
                        tokens.add(new Token(c, Token.TYPE_ASSIGN));
                    }
                } else if(c == '"') {
                    addTextToList(swallowed);
                    swallowed="";
                    
                    int idx=i+1;
                    
                    while(idx<text.length()) {
                        char cEnd = text.charAt(idx);
                        
                        if (cEnd == '"') {
                            break;
                        }
                        
                        idx++;
                    }
                    
                    String sub=text.substring(i, idx+1);
                    tokens.add(new Token(sub, Token.TYPE_STRING));
                    i=idx;
                } else {
                    swallowed += c;
                }
            }
            
            setTokenIndexes();
        }
        
        private void addTextToList(String text) {
            if("if".equalsIgnoreCase(text)) {
                tokens.add(new Token(text, Token.TYPE_IF));
            }else if("then".equalsIgnoreCase(text)) {
                tokens.add(new Token(text, Token.TYPE_THEN));
            }else 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_ASSIGN) {
                        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.");
                            }
                        }
                    }
                }else if(token.getType()==Token.TYPE_IF) {
                    int vLeft,vRight;
                    String oprand;
                    
                    // get left value
                    token=fetchToken();                
                    if(token.getType()==Token.TYPE_VARIABLE) {
                        String varibleName=token.getText();
                        
                        if(varmap.containsKey(varibleName)) {
                            vLeft=varmap.get(varibleName);
                        }else {
                            throw new Exception("Variable:'"+varibleName+"' was not assigned.");
                        }
                    }else if(token.getType()==Token.TYPE_NUMBER) {
                        vLeft=Integer.parseInt(token.getText());
                    }else {
                        throw new Exception("Expected:number/variable actual:"+token.getText()+" "+token);
                    }
                    
                    // get ==,<,>
                    token=fetchToken();                
                    if(token.getType()!=Token.TYPE_EQUAL && token.getType()!=Token.TYPE_LESSTHAN && token.getType()!=Token.TYPE_BIGGERTHAN) {
                        throw new Exception("Expected:'== or > or <' actual:"+token.getText()+" "+token);
                    }
                    oprand=token.getText();
                    
                    // get right
                    token=fetchToken();                
                    if(token.getType()==Token.TYPE_VARIABLE) {
                        String varibleName=token.getText();
                        
                        if(varmap.containsKey(varibleName)) {
                            vRight=varmap.get(varibleName);
                        }else {
                            throw new Exception("Variable:'"+varibleName+"' was not assigned.");
                        }
                    }else if(token.getType()==Token.TYPE_NUMBER) {
                        vRight=Integer.parseInt(token.getText());
                    }else {
                        throw new Exception("Expected:number/variable actual:"+token.getText()+" "+token);
                    }
                    
                    // Compare
                    if(compare(vLeft,oprand,vRight)) {
                        // get then
                        token=fetchToken();                
                        if(token.getType()!=Token.TYPE_THEN) {
                            throw new Exception("Expected:'then' actual:"+token.getText()+" "+token);
                        }
                    }else {
                        // 跳过两个token(then及后面的dosth)
                        fetchToken();        
                        fetchToken();        
                    }
                }
            }
        }
        
        private boolean compare(int vLeft,String oprand,int vRight) throws Exception{
            if("==".equals(oprand)) {
                return vLeft==vRight;
            }else if(">".equals(oprand)) {
                return vLeft>vRight;
            }else if("<".equals(oprand)) {
                return vLeft<vRight;
            }else {
                throw new Exception("oprand should be == or > or < but not.");
            }
        }
        
        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--;
            }
        }
    }

    --2020年5月31日--

  • 相关阅读:
    关于CSS自文档的思考_css声明式语言式代码注释
    html5中contenteditable属性如果过滤标签,过滤富文本样式
    web前端工程化/构建自动化
    Python连载19-装饰器
    Java连载1-概述&常用的dos命令
    HTML连载18-id选择器与class区别&class选择器使用思路&后代选择器
    Python连载18-closure闭包解释及其注意点
    HTML连载17-id选择器&类选择器
    Python连载17-排序函数&返回函数的函数
    HTML连载16-颜色控制属性2&标签选择器
  • 原文地址:https://www.cnblogs.com/heyang78/p/12996536.html
Copyright © 2011-2022 走看看