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()
相关推荐
艾莉丝努力练剑34 分钟前
【LeetCode&数据结构】单链表的应用——反转链表问题、链表的中间节点问题详解
c语言·开发语言·数据结构·学习·算法·leetcode·链表
武子康2 小时前
Java-72 深入浅出 RPC Dubbo 上手 生产者模块详解
java·spring boot·分布式·后端·rpc·dubbo·nio
_殊途2 小时前
《Java HashMap底层原理全解析(源码+性能+面试)》
java·数据结构·算法
椰椰椰耶3 小时前
【Spring】拦截器详解
java·后端·spring
没有bug.的程序员4 小时前
JAVA面试宝典 - 《MyBatis 进阶:插件开发与二级缓存》
java·面试·mybatis
没有羊的王K5 小时前
SSM框架学习——day1
java·学习
珊瑚里的鱼6 小时前
LeetCode 692题解 | 前K个高频单词
开发语言·c++·算法·leetcode·职场和发展·学习方法
又菜又爱coding6 小时前
安装Keycloak并启动服务(macOS)
java·keycloak
不知道叫什么呀6 小时前
【C】vector和array的区别
java·c语言·开发语言·aigc
wan_da_ren6 小时前
JVM监控及诊断工具-GUI篇
java·开发语言·jvm·后端