ANTLR学习心得——表达式(2)

今天咱们来一句一句的解释一下这个expression.g文件。还是从最简单的几行开始:
 
class ExpressionLexer extends Lexer; //这是用来声明一个词法分析器,名字叫
                                                   //ExpressionLexer

PLUS  : '+' ;                                   //加号
MINUS : '-' ;                                   //减号
MUL   : '*' ;                                    //乘号
DIV   : '/' ;                                    //除号
MOD   : '%' ;                                  //求余
POW   : '^' ;                                  //开方
SEMI  : ';' ;                                    //结束号
                                                   //上面这些都太简单了,简直就不需要说明

protected DIGIT : '0'..'9' ;               //数字,这是一个受保护的单词,只能被
                                                   //词法分析器内部使用
INT   : (DIGIT)+ ;                           //出现了一次以上的数字的词,就是整数,
                                                   //它通过受保护的单词:“数字”来定义自己。
                                                   //如果DIGIT不是被保护的单词,则词法分析器就会
                                                   //无法分辨究竟是数字还是整数了
 
接下来看语法分析器的代码:
 
class ExpressionParser extends Parser;   //定义一个语法分析器,名字叫ExpressionParser
options { buildAST=true; }                  //告诉ANTLR,要帮我生成一个抽象语法树,
                                                       //留着以后有用
 
//接下来的部分就非常复杂了,主要是多出来了两个特殊的符号“!”、“^”
//这两个符号,不是EBNF原有的,而是ANTLR为了生成AST而增加的符号
//“!”,是告诉AST生成程序,不要把自己算进去
//“^”,是告诉AST生成程序,把这个符号,放在一颗树的根部,或者一颗子树的根部
//另外,“*”表示出现0次以上,“+”表示出现一次以上,“?”表示出现0或1次

expr     : sumExpr SEMI!;                                            //“;”作为结束符,不放入AST
sumExpr  : prodExpr ((PLUS^|MINUS^) prodExpr)* ;      //“+”“-”作为计算符号
                                                                              //放在树的顶部
prodExpr : powExpr ((MUL^|DIV^|MOD^) powExpr)* ;  //剩下的就不解释了,都能明白的
powExpr  : atom (POW^ atom)? ;
atom     : INT ;
 
再来看AST计算器的代码。这“AST计算器”是我起的名字,也就是通过对一个生成的抽象语法树,递归求值,得到最后的结果。
 
{import java.lang.Math;}                                      //ExpressionTreeWalker要用到的
class ExpressionTreeWalker extends TreeParser;    //声明一个树计算器

expr returns [double r]                                      //有一个方法叫expr
                                                                      //它的返回值是double类型
  {double a,b; r=0; }                                         //嵌入的代码,后面要用到

  : #(PLUS a=expr b=expr)  { r=a+b; }               //以下就是计算各种算符,不用多说了
  | #(MINUS a=expr b=expr) { r=a-b; }
  | #(MUL  a=expr b=expr)  { r=a*b; }
  | #(DIV  a=expr b=expr)  { r=a/b; }
  | #(MOD  a=expr b=expr)  { r=a%b; }
  | #(POW  a=expr b=expr)  { r=Math.pow(a,b); }
  | i:INT { r=(double)Integer.parseInt(i.getText()); }
  ;
 
(未完待续)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ANTLR2 是一个流行的生成语法分析器的工具。ANTLR2 源码是使用 Java 编写的,它的源码非常庞大且复杂。在这里,我们将简要介绍 ANTLR2 的一些关键组件和源码结构,以帮助您更好地理解其工作原理。 ANTLR2 的源码结构如下: - antlr:包含了 ANTLR2 的核心代码,包括语法分析器、词法分析器、AST(抽象语法树)等。 - antlr.collections:包含了 ANTLR2 中使用的一些集合类。这些集合类提供了比 Java 标准库更高效的实现。 - antlr.debug:包含了 ANTLR2 中用于调试的一些类。 - antlr.preprocessor:包含了 ANTLR2 中的预处理器,可以用来处理语法文件中的宏定义等。 ANTLR2 的核心代码位于 antlr 包中,其中最重要的类是 ANTLRParser、ANTLRLexer 和 ASTFactory。ANTLRParser 和 ANTLRLexer 类分别对应语法分析器和词法分析器。它们都继承自 ANTLRBaseParser 和 ANTLRBaseLexer 类,这两个类提供了一些基本的方法和变量,如语法规则、词法规则等。ANTLRParser 和 ANTLRLexer 的具体实现代码位于 antlr/ANTLRParser.java 和 antlr/ANTLRLexer.java 文件中。 ASTFactory 类用于创建和操作抽象语法树。ANTLR2 中的 AST 是由一些节点组成的树形结构,每个节点代表了一个语法元素。ASTFactory 提供了一些方法来创建和操作 AST,如 create()、dup()、addASTChild() 等。ASTFactory 的具体实现代码位于 antlr/ASTFactory.java 文件中。 除此之外,ANTLR2 还包含了用于生成 Java 代码的工具类。这些工具类包括 CodeGenerator、JavaBlockFinishingInfo、JavaCodeGenerator 等。它们的具体实现代码位于 antlr/build 包中。 总的来说,ANTLR2 的源码非常庞大且复杂,需要深入研究才能理解其工作原理。如果您想要了解更多关于 ANTLR2 的内容,建议阅读 ANTLR2 的官方文档或参考相关的书籍。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值