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()
相关推荐
随意起个昵称2 小时前
线性dp-计数类题目10(ZBRKA)
算法·动态规划
云烟成雨TD7 小时前
Spring AI Alibaba 1.x 系列【69】Token 用量统计
java·人工智能·spring
Navigator_Z7 小时前
LeetCode //C - 1089. Duplicate Zeros
c语言·算法·leetcode
JAVA9657 小时前
JAVA面试-并发篇 03-使用synchronized doublecheck实现单例有什么坑
java·单例模式·面试
在繁华处7 小时前
Java从零到熟练(四):面向对象基础
java·开发语言
小江的记录本9 小时前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
在繁华处9 小时前
Java从零到熟练(三):流程控制
java·开发语言·python
唐青枫9 小时前
Java Optional 实战指南:优雅处理空值与链式转换
java
一起学开源9 小时前
一文读懂 ReAct 范式:让 AI Agent 真正学会“思考+行动“
java·javascript·react.js·ecmascript·react·alibaba·智能体开发
云泽80810 小时前
C++ 可调用对象通关指南:深度解析 Lambda 表达式、function 包装器与 bind 绑定器
开发语言·c++·算法