首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

ANTLR一个编译简略的两数相加的例子

2012-11-17 
ANTLR一个编译简单的两数相加的例子然后生成全新的Parser。稍微修改一下主程序,就可以对1+1进行编译计算了p

ANTLR一个编译简单的两数相加的例子

然后生成全新的Parser。稍微修改一下主程序,就可以对1+1进行编译计算了
public class Main {
??? public static void main(String[] args) throws Exception {
??????? CaculatorLexer lexer = new CaculatorLexer(System.in);
??????? CaculatorParser parser = new CaculatorParser(lexer);
??????? try {
??????????? System.out.println(parser.expr());
??????? } catch (Exception e) {
??????????? System.err.println(e);
??????? }
??? }
}
在输入的时候 输入1+1 就可以得到结果了。

<o:p>?</o:p>

DOM方式
使用DOM方式,首先需建立一个AST语法树:
建立AST的方式很简单,只要我们Antlr一个建立AST的选项即可,下面就是新的Parser:
class CaculatorParser extends Parser;<o:p></o:p>

options {
??? buildAST=true;
}<o:p></o:p>

expr:?? INT PLUS^ INT;<o:p></o:p>

稍微有些不同的地方在PLUS上面的“^”,这个符号用来告诉Antlr创建一个节点,以此作为当前树的根节点。<o:p></o:p>

下面将DOM方式的重点部分TreeParser:
class CaculatorTreeParser extends TreeParser;<o:p></o:p>

expr returns [int value = 0;] ?//定义规则
????? : #(PLUS a : INT b : INT) {
????????? int aValue = Integer.parseInt(a.getText());
????????? int bValue = Integer.parseInt(b.getText());
????????? value = aValue + bValue;
????? };
Antlr 可以接受三种类型语法规范——Lexer、Parser和Tree-Parser。如果说Lexer处理的是字符流、Parser处理的是Token流, 那么TreeParser处理的则是AST。前面Action的处理方式中,我们看到,规则同处理放到了一起,显得有些混乱,而采用了AST的处理方式, 规则同处理就完全分离了:在Parser中定义规则,在TreeParser中定义处理,如果我们需要对同样的语法进行另外的处理,我们只要重新 TreeParser,从而降低耦合度,Hibernate采用的就是这种方式!!<o:p></o:p>

可以参考前面ACTION,来看TreeParser如何编写也就简单许多,需要说明的就是:
#(PLUS a : INT b : INT)
除去变量的说明,简化一下这段代码
#(PLUS INT INT)
第一个符号PLUS对应了表示着根节点,两个INT则分别代表了两棵子树。<o:p></o:p>

再来看看重新打造的主程序
public class Main {
??? public static void main(String[] args) {
??????? CaculatorLexer lexer = new CaculatorLexer(System.in);
??????? CaculatorParser parser = new CaculatorParser(lexer);
??????? try {
??????????? parser.expr();
??????????? AST t = parser.getAST();
??????????? CaculatorTreeParser treeParser = new CaculatorTreeParser();
??????????? System.out.println(treeParser.expr(t));
??????? } catch (Exception e) {
??????????? System.err.println(e);
??????? }
??? }
}<o:p></o:p>

在输入的时候 输入1+1 就可以得到结果了。

<o:p>?</o:p>

由此再参考Hibernate的处理方式,会发现很容易理解:<o:p></o:p>

Session s = factory.openSession();<o:p></o:p>

List auctions = s.createQuery("…");<o:p></o:p>

createQuery()的调用过程<o:p></o:p>

通过QueryPlanCache的getHQLQueryPlan()方法获得查询计划HQLQueryPlan的一个实例,而后者主要是调用了 QueryTranslator的compile方法,编译HQL语句。在QueryTranslator的继承类 QueryTranslatorImpl的doCompile观察这个过程:<o:p></o:p>

PHASE 1 : Parse the HQL into an AST.<o:p></o:p>

PHASE 2 : Analyze the HQL AST, and produce an SQL AST.<o:p></o:p>

PHASE 3 : Generate the SQL.<o:p></o:p>

热点排行