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()
相关推荐
Yingye Zhu(HPXXZYY)1 小时前
ICPC 2023 Nanjing R L 题 Elevator
算法
坐吃山猪2 小时前
SpringBoot01-配置文件
java·开发语言
我叫汪枫3 小时前
《Java餐厅的待客之道:BIO, NIO, AIO三种服务模式的进化》
java·开发语言·nio
yaoxtao3 小时前
java.nio.file.InvalidPathException异常
java·linux·ubuntu
程序员Xu4 小时前
【LeetCode热题100道笔记】二叉树的右视图
笔记·算法·leetcode
Swift社区4 小时前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
笑脸惹桃花4 小时前
50系显卡训练深度学习YOLO等算法报错的解决方法
深度学习·算法·yolo·torch·cuda
阿维的博客日记5 小时前
LeetCode 48 - 旋转图像算法详解(全网最优雅的Java算法
算法·leetcode
GEO_YScsn5 小时前
Rust 的生命周期与借用检查:安全性深度保障的基石
网络·算法