随笔-26  评论-4  文章-0  trackbacks-0
1、概念:
      antlr是 another tool for language recongnition,用于 词法、语法和语义分析。如果大家仔细看一些开源项目的lib包,会经常看到其包含有antlr.jar文件。

2、使用场景:
        设想一个运算的场景,“1+3”为多少,如果通过程序解析这个字符串,可以尝试使用拆解字符串的方法,识别其中的运算符“+”,然后将结果输出,感觉很简单。但是,如果场景变化呢?“1+3-6/2”这个样子的呢,也得改程序?是不是有些头大呢?那么antlr就可以帮助你来解决这个头大的问题。

3、主要内容:
          antlr重要包含三个重要的内容,分别是 词法分析、语法分析、语义分析,其各个部分的用途主要如下所示:
          词法分析:  (识别出 “1”,“+”,“3”)

               (1)逐个字符读取公式源文件

               (2)识别公式源文件中的词法单元(Token)

                (3)将词法单元传递给语法分析器

               (4)词法分析器又叫扫描器(Scanner)  
        语法分析:(识别1+3)

                (1)从词法分析器获得词法单元

                (2)利用文法定义验证词法单元组合

               (3)构造语法分析树

                (4)将语法分析树传递给下一阶段

               (5)语法分析器又叫解析器(Parser)
         语义分析:(计算结果)
              (1)完成语义动作定义

              (2)一般在语法分析器中完成语义分析

       大致各部分的含义就是,首先 识别出 输入的字符是否正确,其次检验字符之间的运算关系,然后计算得出相关的结果。

4、主要工作:
         需要写两个.g的文件,分别是 Expr.g和Eval.g文件,前者生成词法、语法分析相关的java文件,通过编译生成ExprLexer.java、ExprParser.java 和 Expr.tokens文件,后者生成语义分析文件,分别为Eval.java和Eval.tokens文件。
         相关的编译方法为:java org.antlr.Tool Expr.g

5、开发环境搭建:
          1、配置java环境变量
          2、将antlr的相关jar包添加到环境变量中
          3、运行 java org.antlr.Tool 进行验证

6、简单代码展示,用于计算简答的加减运算
          1)、expr.g
grammar Expr;
options {
 language=Java;
 output=AST;
 ASTLabelType=CommonTree; // type of $stat.tree ref etc...
}
@header {
 package test.tool;
}

 prog: ( stat {/* System.out.println($stat.tree.toStringTree()); */})+ ;

stat
 : expr  NEWLINE -> expr
 | NEWLINE    ->
 ;
expr: multExpr (('+' ^|'-' ^) multExpr)* ;
multExpr
 : atom (('/' ^|'*' ^) atom)*
 ;
 
atom
 : INT
 | DOUBLE
 | ID
 | '(' ! expr ')' !
 ; 

ID  :   ('N'|'R'|'A'|'C'|'I'|'D')'B'('S'|'H');
INT :   '0'..'9'+ ;
WS  :   (' '|'\t')+ {skip();} ;
NEWLINE:'\r'? '\n' ;
DOUBLE : (('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') ('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9')*) '.' (('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') ('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9')*); 

        2)Eval.g
           

tree grammar Eval;     
options {
 tokenVocab=Expr;    // read token types from Expr.tokens file
 ASTLabelType=CommonTree;  // what is Java type of nodes?
}
@header {
 package fanxiqian.tool;(可在此处添加 package和import等相关信息)
}
@members {
       …………(可在此处添加java方法) 
}

prog: stat+ ;
stat: expr+;

expr returns [double value]
 : ^('+' a=expr b=expr) {$value = a+b;}  //此处定义了 相关运算符的含义
 | ^('-' a=expr b=expr) {$value = a-b;}
 | ^('*' a=expr b=expr) {$value = a*b;}
 | ^('/' a=expr b=expr) {$value=a/b;}
 | INT {$value = Integer.parseInt($INT.text);}
 | DOUBLE {$value = Double.parseDouble($DOUBLE.text);}
 ; 

         3)通过编译命令,生成相关的java文件
                       java org.antlr.Tool Expr.g
                       java org.antlr.Tool Eval.g  

          4)编写相关的测试类
public class Test
{
    public static void main(String[] args) throws Exception
    {
     ANTLRStringStream input;
     ExprLexer lexer;
     CommonTokenStream tokens;
     ExprParser parser;
      String formula="1+3";
   //开始解析
   formula += "\n";
   input = new ANTLRStringStream(formula);
   lexer = new ExprLexer(input);
   tokens = new CommonTokenStream(lexer);
   parser = new ExprParser(tokens);
   ExprParser.prog_return r = parser.prog();
   // walk resulting tree
         CommonTree t = (CommonTree)r.getTree();
         CommonTreeNodeStream nodes = new CommonTreeNodeStream(t);
         Eval walker = new Eval(nodes);
         System.out.println(walker.expr());
//  }   

即可得到输出结果为4。

7,总结
       antlr是个强大的公式解析工具,本文只是简单的一个小结,以后遇到相关的使用继续补充吧,欢迎大家补充添加吧。
posted on 2011-05-16 20:12 mingsen 阅读(4521) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: