DSL语法解析器生成器:dropincc.java

jopen 11年前

dropincc.java 是

  • 一个简单、好用的语法解析器生成器;
  • 专为java语言环境下,实施DSL方案而设计;
  • 特点:使用纯java语法(Fluent Interface)制定用户的词法、语法规则;jdk1.6 compiler API动态编译为字节码;自动管理字节码、用户无需关心具体生成的解析器源码;专为DSL打造,相对与使用其它常见工具(javacc, antlr等)做DSL解析,代码量急剧下降;上手较为容易,让用户更加关注自身业务内容
  • 需要jdk1.6或以上版本运行,无任何其它依赖
  • 识别LL(*)语法

/**   * EBNF of Calculator:   * <pre>   * calc ::= expr $   * expr ::= addend (('+'|'-') addend)*   * addend ::= factor (('*'|'/') factor)*   * factor ::= '(' expr ')'   *          | '\\d+(\\.\\d+)?'   * </pre>   */  public static void main(String... args) throws Throwable {      Lang c = new Lang("Calculator");      Grule expr = c.newGrule();      c.defineGrule(expr, CC.EOF).action(new Action() {          public Double act(Object matched) {              return (Double) ((Object[]) matched)[0];          }      });      TokenDef a = c.newToken("\\+");      Grule addend = c.newGrule();      expr.define(addend, CC.ks(a.or("\\-"), addend)).action(new Action() {          public Double act(Object matched) {              Object[] ms = (Object[]) matched;              Double a0 = (Double) ms[0];              Object[] aPairs = (Object[]) ms[1];              for (Object p : aPairs) {                  String op = (String) ((Object[]) p)[0];                  Double a = (Double) ((Object[]) p)[1];                  if ("+".equals(op)) {                      a0 += a;                  } else {                      a0 -= a;                  }              }              return a0;          }      });      TokenDef m = c.newToken("\\*");      Grule factor = c.newGrule();      addend.define(factor, CC.ks(m.or("/"), factor)).action(new Action() {          public Double act(Object matched) {              Object[] ms = (Object[]) matched;              Double f0 = (Double) ms[0];              Object[] fPairs = (Object[]) ms[1];              for (Object p : fPairs) {                  String op = (String) ((Object[]) p)[0];                  Double f = (Double) ((Object[]) p)[1];                  if ("*".equals(op)) {                      f0 *= f;                  } else {                      f0 /= f;                  }              }              return f0;          }      });      factor.define("\\(", expr, "\\)").action(new Action() {          public Double act(Object matched) {              return (Double) ((Object[]) matched)[1];          }      }).alt("\\d+(\\.\\d+)?").action(new Action() {          public Double act(Object matched) {              return Double.parseDouble((String) matched);          }      });      Exe exe = c.compile();      System.out.println(exe.eval("1 +2+3+(4 +5*6*7*(64/8/2/(2/1 )/1)*8  +9  )+   10"));  }

项目主页:http://www.open-open.com/lib/view/home/1377095164319