用Java实现自己的编程语言

前言

在工作中,由于需要,想在前端页面上实现一些逻辑,为了功能更强大一些,所以想着自己开发一个简单的编程语言,前端在文本框中即可实现自己的逻辑。

思路

使用字符串接收代码块,通过,正则表达式,实现拆分。

将代码分为4个部分:

  • 操作数:
    • 变量:以下划线开头,支持大小写,例:“_age”。
    • 数据:目前仅支持整型和布尔数据,例:“12”、“true”、“false”。
  • 操作符:支持+ - * / = > < 操作符,赋值用“~”表示。
  • 分句符:使用“;”分割语句。
  • 控制语句:目前支持IF语句,用“if 变量 then 操作”表示。

具体实现

依赖

  <dependencies>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.12</version>
    </dependency>
  </dependencies>

操作数和操作符实体

// 操作数
@Data
public class Operand {
  private int index;
  private String variable; // 变量名
  private boolean isVar; // 是否为变量
  private String value; // 值
}
// 操作符
@Data
public class Operator {
  private Operand previous; // 前一个操作数
  private Operand next; // 后一个操作数
  private int index; //
  private String var; // 操作符
  private int priority; // 优先级
}

核心处理

public class Core {

    // 自定义参数
    static Map<String, String> map = new HashMap<>();
    static String varStr = "[^+\\-*/?:~=><]+";
    static String varOperator = "[+\\-*/?:~=><]";

    // 新语言计算入口
    public static void total(String text){
        // 清除空字符
        text = text.replaceAll("\\s","");
        String[] split = text.split(";");
        for (String SingleStatement : split) {
            if (SingleStatement.contains("if")){
                ifThen(SingleStatement);
            }else {
                simpleCompile(SingleStatement);
            }
        }
        System.out.println(map);
        map.clear();
    }

    // 分离操作数
    private static List<Operand> separateOperand(String text) {
        List<Operand> list = new ArrayList<>();
        Pattern pattern = Pattern.compile(varStr);
        Matcher matcher = pattern.matcher(text);
        while (matcher.find()) {
            Operand operand = new Operand();
            String str = matcher.group();
            operand.setVariable(str);
            boolean isVar = str.contains("_");
            operand.setVar(isVar);
            // 将变量放入map中管理
            if (isVar){
                String value = map.get(str);
                if (value == null) {
                    map.put(str,null);
                }else {
                    operand.setValue(value);
                }
            }else {
                operand.setValue(str);
            }
            list.add(operand);
        }
        return list;
    }

    // 分离操作符
    private static List<Operator> separateOperator(String text, List<Operand> operandList) {
        List<Operator> list = new ArrayList<>();
        Pattern pattern = Pattern.compile(varOperator);
        Matcher matcher = pattern.matcher(text);
        int i = 0;
        while (matcher.find()) {
            Operator operator = new Operator();
            operator.setPrevious(operandList.get(i));
            operator.setNext(operandList.get(i + 1));
            operator.setIndex(i);
            operator.setVar(matcher.group());
            operator.setPriority(getPriority(matcher.group()));
            list.add(operator);
            i++;
        }
        return list;
    }

    // 获得优先级
    private static int getPriority(String operator) {
        if (operator.matches("[*/]")) {
            return 1;
        } else if (operator.matches("[+\\-]")) {
            return 2;
        } else if (operator.matches("[=><]")) {
            return 3;
        } else if (operator.matches("[~]")) {
            return 4;
        } else {
            return 9999;
        }
    }

    // 单个操作符计算
    private static String doSome(Operator operator) {
        String var = operator.getVar();
        String previous = operator.getPrevious().getValue();
        String next = operator.getNext().getValue();
        String result = "";
        if ("*".equals(var)) {
            result = String.valueOf(Integer.valueOf(previous) * Integer.valueOf(next));
        } else if ("/".equals(var)) {
            result = String.valueOf(Integer.valueOf(previous) / Integer.valueOf(next));
        } else if ("+".equals(var)) {
            result = String.valueOf(Integer.valueOf(previous) + Integer.valueOf(next));
        } else if ("-".equals(var)) {
            result = String.valueOf(Integer.valueOf(previous) - Integer.valueOf(next));
        }else if ("~".equals(var)){
            // 将后一个操作数的值赋予前一个操作数
            operator.getPrevious().setValue(operator.getNext().getValue());
            // 更新map
            map.put(operator.getPrevious().getVariable(),operator.getPrevious().getValue());
        }else if ("=".equals(var)){
            result = previous.equals(next)?"true":"false";
        }else if (">".equals(var)){
            result = Integer.valueOf(previous) > Integer.valueOf(next)?"true":"false";
        }else if ("<".equals(var)){
            result = Integer.valueOf(previous) < Integer.valueOf(next)?"true":"false";
        }
        return result;
    }

    // 操作符计算
    private static String compute(List<Operator> list) {

        // 根据优先级计算
        for (int i = 1; i <= 4; i++) {
            Iterator<Operator> iterator = list.iterator();
            while (iterator.hasNext()) {
                Operator operator = iterator.next();
                if (operator.getPriority() == i) {
                    // 计算该操作符计算后的值
                    String value = doSome(operator);
                    // 获得前后index注意0和last
                    int index = list.indexOf(operator);
                    // 将该操作符的值赋予前后操作符
                    if (index > 0){
                        list.get(index-1).getNext().setValue(value);
                    }
                    if (index<list.size()-1){
                        list.get(index+1).getPrevious().setValue(value);
                    }
                    iterator.remove();
                    if (list.size() == 0) {
                        return value;
                    }
                }
            }
        }
        return null;
    }

    // 简单计算,不包含if语句
    private static String simpleCompile(String text){
        List<Operand> operandList = separateOperand(text);
        List<Operator> operatorList = separateOperator(text, operandList);
        // 当只有一个值时
        if (operatorList.size()==0){
            return operandList.get(0).getValue();
        }
        String result = compute(operatorList);
        return result;
    }

    // if then 处理
    private static void ifThen(String text){
        Pattern pattern = Pattern.compile("[^(if|then)]+");
        Matcher matcher = pattern.matcher(text);
        int i = 0;
        String result = null;
        while (matcher.find()){
            if (i == 0){
                result = simpleCompile(matcher.group());
            }else {
                if ("true".equals(result)){
                    simpleCompile(matcher.group());
                }
            }
            i++;
        }
    }
}

测试

public class Test {
    public static void main(String[] args) {
        Core.total("_a~2*3<10;if _a then _b~10"); 
        // {_a=true, _b=10}
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值