DSL構文解析器ジェネレータ:dropincc.java

2614 ワード

dropincc.javaは
  • 簡単で使いやすい構文解析器ジェネレータ.
  • はjava言語環境の下で、DSL方案を実施するために設計された.
  • 特徴:純java文法(Fluent Interface)を用いてユーザーの文法、文法規則を制定する.jdk 1.6 compiler APIはバイトコードに動的にコンパイルされる.バイトコードを自動的に管理し、ユーザーは具体的に生成された解析器のソースコードに関心を持つ必要はない.DSLのために作られ、他の一般的なツール(javacc、antlrなど)を使ってDSL解析を行うのに比べて、コード量が急激に低下しています.使いやすく、ユーザーが自分の業務内容にもっと関心を持つようにする
  • .
  • はjdk 1.6以上のバージョンで実行する必要があります.
  • に依存する他のバージョンはありません.
  • 認識LL(*)構文
  •  
    /**
     * EBNF of Calculator:
     * 
    
     * calc ::= expr $
     * expr ::= addend (('+'|'-') addend)*
     * addend ::= factor (('*'|'/') factor)*
     * factor ::= '(' expr ')'
     *          | '\\d+(\\.\\d+)?'
     * 
    */
    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