scala 实现表达式解析

表达式解析

scala 复制代码
import org.junit.Test

import scala.collection.mutable

class ExprTestCase {


  private val orderSource = "source_1"
  private val saleChannel = "saleChannel"
  val datas = new mutable.HashMap[String, String]();
  //  p1, source1, sale1, source_1 & ( sale_channel_1 | sq )"
  datas.put("source_1", "source_1");
  datas.put("saleChannel", "saleChannel");
  datas.put("orderSource", "orderSource");

  val expr = s"orderSource:source_1 & ( saleChannel:saleChannel | orderSource:orderSource )"

  private val tokens: Array[String] = expr.split("\\s+")

  private val optStack = new mutable.ArrayStack[String]()
  private val memberStatck = new mutable.ArrayStack[String]()
  private var flag = false;

  def matchFiled(fieldName: String): String = {
    fieldName match {
      case "orderSource" => orderSource
      case "saleChannel" => saleChannel
      case _ => throw new IllegalArgumentException(s"unknown filed name: ${fieldName}, it's  can only be 'orderSource' or 'saleChannel'")
    }
  }

  @Test
  def expParseTestCase() = {

    var opt = ""

    def exprProcess = {
      if (opt == "" || opt == "(") opt = optStack.pop()
      while (opt != null && opt != "(" && memberStatck.nonEmpty) {
        opt match {
          case "|" => {
            if(memberStatck.size > 1) {
              val m1 = memberStatck.pop().split(":")
              val m2 = memberStatck.pop().split(":")
              flag = datas.getOrElse(m2(1), "N").eq(matchFiled(m2(0))) || datas.getOrElse(m1(1), "N").eq(matchFiled(m1(0)))
              println(
                s"""
                [&]: ${datas.getOrElse(m2(1), "N")}.eq("${matchFiled(m2(0))}") || ${datas.getOrElse(m1(1), "N")}.eq("${matchFiled(m1(0))}")
                """)
            } else {
              val m1 = memberStatck.pop().split(":")
              flag = flag || datas.getOrElse(m1(1), "N").eq(matchFiled(m1(0)))
              println(
                s"""
                [&]: ${flag} || ${datas.getOrElse(m1(1), "N")}.eq("${matchFiled(m1(0))}
                """)
            }
          }
          case "&" => {
            if (memberStatck.size > 1) {
              val m1 = memberStatck.pop().split(":")
              val m2 = memberStatck.pop().split(":")
              flag = datas.getOrElse(m1(1), "N").equals(matchFiled(m1(0))) && datas.getOrElse(m2(1), "N").equals(matchFiled(m2(0)))
              println(
                s"""
                [&]: ${datas.getOrElse(m1(1), "N")}.eq("${matchFiled(m1(0))}") && ${datas.getOrElse(m2(1), "N")}.eq("${matchFiled(m2(0))}")
                """)
            } else {
              val m1 = memberStatck.pop().split(":")
              flag = flag && datas.getOrElse(m1(1), "N").equals(matchFiled(m1(0)))
              println(
                s"""
                [&]: ${false} && ${datas.get(m1(1))}.eq("$saleChannel")}.eq("${matchFiled(m1(0))}")
                """)
            }
          }
        }
        if (optStack.nonEmpty) opt = optStack.pop()
      }
    }

    tokens.foreach {
      case ")" => {
        exprProcess
      }
      case token@("|" | "&" | "(") => {
        optStack.push(token)
      }
      case token => {
        memberStatck.push(token)
      }
    }

    println("expr match complete :) ")
    if(memberStatck.nonEmpty) {
      exprProcess
    }

    println(flag)
    println(optStack)
    println(memberStatck)

  }

}

输出

log 复制代码
                [&]: saleChannel.eq("saleChannel") || orderSource.eq("source_1")
                
expr match complete :) 

                [&]: false && Some(source_1).eq("saleChannel")}.eq("source_1")
                
true
ArrayStack()
ArrayStack()
相关推荐
路在脚下@7 分钟前
spring boot的配置文件属性注入到类的静态属性
java·spring boot·sql
森屿Serien10 分钟前
Spring Boot常用注解
java·spring boot·后端
苹果醋31 小时前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
Hello.Reader2 小时前
深入解析 Apache APISIX
java·apache
菠萝蚊鸭2 小时前
Dhatim FastExcel 读写 Excel 文件
java·excel·fastexcel
旭东怪2 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
007php0072 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程
∝请叫*我简单先生2 小时前
java如何使用poi-tl在word模板里渲染多张图片
java·后端·poi-tl
ssr——ssss2 小时前
SSM-期末项目 - 基于SSM的宠物信息管理系统
java·ssm
一棵星3 小时前
Java模拟Mqtt客户端连接Mqtt Broker
java·开发语言