ANTLR(语言识别的另一工具)的简介之四[翻译]

编译原理 专栏收录该内容
4 篇文章 0 订阅

通过抽象语法树(AST)求值

现在你已经看到了基本的语法指导的翻译/计算,在此文法/语法指示了什么时候去执行动作。一个更为强大的策略是创建一个中介表达,它拥有所有或绝大部分的输入符号,并在数据的结构中,将这些记号之间的关系编码。比如:输入“3+4”会被表达成如下所示的AST:

  +

 / /

3   4

对这种类型的树,你会使用一个树遍历程序(由ANTLR从树形语法生成)计算出和前面一样的值,但是却使用了不同的策略。

为了确定计算什么,或进行语法树的重写,或者向另一种语言进行树变形,你必须对语法树进行多重遍历。这时,AST的效果会变得清晰。

AST构造

对许多语法,让ANTLR生成一个有用的AST是相当简单的。在我们这里,打开buildAST选项并且添加少许后缀操作符来告诉ANTLR那些记号应该是子树的根。

class ExprParser extends Parser;

 

options {

        buildAST=true;

}

 

expr:   mexpr ((PLUS^|MINUS^) mexpr)*

    ;

 

mexpr

    :   atom (STAR^ atom)*

    ;

 

atom:   INT

    |   LPAREN! expr RPAREN!

    ;

同样,lexer不变。主程序询问目标语法树,并将其打印:

import antlr.*;

import antlr.collections.*;

 

public class Main {  

    public static void main(String[] args) throws Exception {   

        ExprLexer lexer = new ExprLexer(System.in);

        ExprParser parser = new ExprParser(lexer);

        parser.expr();

        AST t = parser.getAST();

        System.out.println(t.toStringTree());

    }   

}   

$ java Main

3+4

 ( + 3 4 )

$ java Main

3+4*5

 ( + 3 ( * 4 5 ) )

$ java Main

(3+4)*5

 ( * ( + 3 4 ) 5 )

$

AST解析和求值

有上面的parser创建的语法树非常简单。语法树解析程序中的单一规则就足够了。

class ExprTreeParser extends TreeParser;

 

options {

    importVocab=ExprParser;

}

 

expr returns [int r=0]

{ int a,b; }

    :   #(PLUS  a=expr b=expr)  {r = a+b;}

    |   #(MINUS a=expr b=expr)  {r = a-b;}  

    |   #(STAR  a=expr b=expr)  {r = a*b;}

    |   i:INT                   {r = (int)Integer.parseInt(i.getText());}

    ;

主程序则修改为使用新的语法树parser来求值:

import antlr.*;

import antlr.collections.*;

 

public class Main {

    public static void main(String[] args) throws Exception {   

        ExprLexer lexer = new ExprLexer(System.in);

        ExprParser parser = new ExprParser(lexer);

        parser.expr();

        AST t = parser.getAST();

        System.out.println(t.toStringTree());

        ExprTreeParser treeParser = new ExprTreeParser();

        int x = treeParser.expr(t);

        System.out.println(x);

    }   

}

现在你得到了树形结构和结果值。

$ java Main

3+4

 ( + 3 4 )

7

$ java Main

3+(4*5)+10

 ( + ( + 3 ( * 4 5 ) ) 10 )

33

$

展开阅读全文
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

ANTLR款强大语法分析器生成工具,可用于读取、处理、执行和翻译结构化文本或二进制文件。它被广泛应用于学术领域和工业生产实践,是众多语言工具和框架基石。Twitter搜索使用ANTLR进行语法分析,每天处理超过20亿次查询;Hadoop生态系统中Hive、Pig、数据仓库和分析系统所使用语言都用到了ANTLR;Lex Machina将ANTLR用于分析法律文本;Oracle公司在SQL开发者IDE和迁移工具中使用了ANTLR;NetBeans公司IDE使用ANTLR来解析C++;Hibernate对象-关系映射框架(ORM)使用ANTLR来处理HQL语言。   除了这些鼎鼎大名项目之外,还可以利用ANTLR构建各种各样实用工具,如配置文件读取器、遗留代码转换器、维基文本渲染器,以及JSON解析器。我编写了工具,用于创建数据库对象-关系映射、描述三维可视化以及在Java源代码中插入性能监控代码。我甚至为次演讲编写了个简单DNA模式匹配程序。   语言正式描述称为语法(grammar),ANTLR能够为该语言生成个语法分析器,并自动建立语法分析树——种描述语法与输入文本匹配关系数据结构。ANTLR也能够自动生成树遍历器,这样你就可以访问树中节点,执行自定义业务逻辑代码。   本书既是ANTLR 4参考手册,也是解决语言识别问题指南。你会学到如下知识:   识别语言样例和参考手册中语法模式,从而编写自定义语法。   循序渐进地为从简单JSON到复杂R语言编写语法。同时还能学会解决XML和Python中棘手识别问题。   基于语法,通过遍历自动生成语法分析树,实现自己语言类应用程序。   在特定应用领域中,自定义识别过程错误处理机制和错误报告机制。   通过在语法中嵌入Java动作(action),对语法分析过程进行完全掌控。   本书并非教科书,所有讨论都是基于实例,旨在令你巩固所学知识,并提供语言类应用程序基本范例。   本书读者对象本书尤其适用于对数据读取器、语言解释器和翻译器感兴趣开发者。虽然本书主要利用ANTLR来完成这些工作,你仍然可以学到很多有关词法分析器和语法分析器知识。初学者和专家都需要本书来高效地使用ANTLR 4。如果希望学习第三部分中高级特性,你需要先了解之前章节中ANTLR基础知识。此外,读者还需要具备Java功底。   Honey Badger版本ANTLR 4版本代号是“Honey Badger”,这个名字来源于段著名YouTube短片The Crazy Nastyass Honey Badger(网址为:http://www.youtube.com/watch?v=4r7wHMg5Yjg)中勇敢无畏主角——只蜜獾。它敢吃你给它任何东西,根本不在乎那是什么!   ANTLR 4有哪些神奇之处ANTLR 4引入了些新功能,降低了入门门槛,使得语法和语言类应用程序开发更加容易。最重要新特性在于,ANTLR 4几乎能够处理任何语法(除了间接左递归,稍后会提到)。在ANTLR将你语法转换成可执行、人类可读语法分析代码过程中,语法冲突或者歧义性警告不会再出现。   无论多复杂语法,只要你提供给ANTLR自动生成语法分析器输入是合法,该语法分析器就能够自动识别之。当然,你需要自行保证该语法能够准确地描述目标语言。   ANTLR语法分析器使用了种名为自适应LL(*)或者ALL(*)(读作“all star”)新技术,它是由我和Sam Harwell起开发。ALL(*)ANTLR 3中LL(*)扩展,在实际生成语法分析器执行前,它能够在运行时以动态方式对语法执行分析,而非先前静态方式。由于ALL(*)语法分析器能够访问实际输入文本,通过反复分析语法方式,它最终能够决定如何识别输入文本。相比之下,静态分析必须考虑所有可行(无限长)输入序列。   在实践中,拥有ALL(*)意味着你无须像在其他语法分析器生成工具(包括ANTLR 3)中那样,扭曲语法以适应底层语法分析策略。如果你曾经为ANTLR 3歧义性警告和yacc归约/归约冲突(reduce/reduce conflict)而抓狂,ANTLR 4就是你不二之选!   个强大新功能是ANTLR 4极大地简化了匹配某些句法结构(如编程语言算术表达式)所需语法规则。长久以来,处理表达式都是ANTLR语法(以及手工编写递归下降语法分析器)难题。识别表达式最自然语法对于传统自顶向下语法分析器生成器(如ANTLR 3)是无效。现在,利用ANTLR 4,你可以通过如下规则匹配表达式:   类
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值