1、概念:
antlr是 another tool for language recongnition,用于 詞法、語法和語義分析。如果大家仔細看一些開源項目的lib包,會經??吹狡浒衋ntlr.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 閱讀(4524)
評論(0) 編輯 收藏