分类: Java工具开发

基于 JavaCC 生成权限校验语法表达式解析器

接上篇 《基于 PEG.js 生成权限校验语法表达式解析器》,前台校验完了,后端也不能省,后端开发依赖 JavaCC,即 Java Compiler Compiler。

JavaCC 简介

Java Compiler Compiler™ (JavaCC™) is the most popular parser generator for use with Java™ applications. A parser generator is a tool that reads a grammar specification and converts it to a Java program that can recognize matches to the grammar. In addition to the parser generator itself, JavaCC provides other standard capabilities related to parser generation such as tree building (via a tool called JJTree included with JavaCC), actions, debugging, etc.

JavaCC 是 Java 语言范围内最受欢迎的语法分析生成器,可以读取特定语法写好的范式并把它转换成可以识别且匹配该语法的 JAVA 程序,除了 javacc 也有配套的 JJTree 生成语法树,JJDoc 生成 BNF 范式文档等。

更多信息参见官网

直接上代码

options
{
  NODE_PACKAGE = "cn.lzxz1234.rbac";
  MULTI = true;
  NODE_USES_PARSER = true;
  STATIC = false;
  VISITOR = true;
}

PARSER_BEGIN(ActionExpression)

package cn.lzxz1234.rbac;
import java.io.StringReader;

public class ActionExpression
{
  public ActionExpression(String s)
  {
    this (new StringReader(s));
  }

  public static boolean evaluate(String src) throws ParseException
  {
    return new ActionExpression(src).expr();
  }

  public static boolean hasAction(String action)
  {
    return action.equals("User.Modify");
  }
}

PARSER_END(ActionExpression)

SKIP :
{
  " "
| "\t"
| "\n"
| "\r"
| < "//" (~[ "\n", "\r" ])*
    (
      "\n"
    | "\r"
    | "\r\n"
    ) >
| < "/*" (~[ "*" ])* "*"
    (
      ~[ "/" ] (~[ "*" ])* "*"
    )*
    "/" >
}

TOKEN : /* LITERALS */{
  < LOGICAL_AND :
    "&&"
  | "and" >
| 
  < LOGICAL_OR :
    "||"
  | "or" >
}

TOKEN : /* IDENTIFIERS */{
  < IDENTIFIER :
    < LETTER >
    (
      < LETTER >
    | < DIGIT >
    )* >
| 
  < #LETTER : [ "_", "-", "a"-"z", "A"-"Z", "." ] >
| 
  < #DIGIT : [ "0"-"9" ] >
}

boolean expr() :
{
}
{
  {
    return Expression();
  }
}

boolean Expression() :
{
  boolean tmp1 = false;
  boolean tmp2 = false;
}
{
  tmp1 = TermExpression() [< LOGICAL_OR > tmp2 = TermExpression()]
  {
    return tmp1 || tmp2;
  }
}

boolean TermExpression() :
{
  boolean tmp1 = true;
  boolean tmp2 = true;
}
{
  tmp1 = FactorExpression() [< LOGICAL_AND > tmp2 = FactorExpression()]
  {

    return tmp1 && tmp2;
  }
}

boolean FactorExpression() :
{
  boolean exp;
}
{
  "(" exp = Expression() ")"
  {
    return exp;
  }
|
  {
    {
      return Label();
    }
  }
}

boolean Label() :
{
  Token t;
}
{
  t = < IDENTIFIER >
  {
    return ActionExpression.hasAction(t.image);
  }
}

思路跟前篇是一样的,过程不细讲了,按文档研究下很容易。

测试

运行代码

public class ActionExpressionTest {

    public static void main(String[] args) throws ParseException {

        System.out.println(ActionExpression.evaluate("User.Edit or User.Modify or (User.List and Admin)"));
        System.out.println(ActionExpression.evaluate("User.Edit or (User.List and Admin)"));
    }

}

测试了前一篇的两个表达式,发现运行正常至此结束。

All Done!

Recent Posts

Docker 容器非 root 用户监听 80 端口

起因是基于 CentOS 的 …

2 年 之前

基于 Docker 定时打印文件

先说背景,喷墨打印机有个很大的…

3 年 之前

Java 运行时反射获取来自继承的泛型

背景 正常情况下 Java 的…

3 年 之前

Java 基于 ByteBuddy 重写系统当前时间

背景 一般单元测试时总会有些代…

3 年 之前

华硕 B450F-Gaming 主板 I211-AT 网卡驱动安装

事情起因是买了块华硕的 ROG…

3 年 之前

PHP 安装 Memcached 扩展

登录服务器挨步执行: # su…

4 年 之前