The Definitive Antlr 4 第4章学习笔记
来源:互联网 发布:开挂软件 编辑:程序博客网 时间:2024/05/24 06:08
The Definitive Antlr 4 Reference 2nd Edition 第4章第二小节 学习笔记
为了使用4.1节所定义的算数表达式能够计算值,需要编写一些Java代码。Antlr v4鼓励使用者保持文法整洁(clean),同时使用分析树的访问器(visitors)和其它的遍历工具来实现语言应用。本节使用访问者模式(visitor pattern)来实现计算器。代码中将使用Antlr自动生成的visitor接口和空visitor实现来完成计算器。
首先需要对4.1节所定义文法进行修改,这里需要标记各个规则(标记所用标签是不与规则名相冲突的标识符)。如果没有标签标记规则,那么Antlr仅仅为每个规则生成一个visitor方法。而这里需要使用不同的visitor方法,在输入的每个阶段处理不同的事件。标签写在规则右侧,并以 # 符号开始。
因此文法变为:
prog : stat+;stat : expr NEWLINE # printExpr | ID '=' expr NEWLINE # assign | NEWLINE # blank ;expr: expr op=('*' | '/') expr # MulDiv | expr op=('+' | '-') expr # AddSub | INT # int | ID # id | '(' expr ')' # parents ;
接下来为操作符常量定义一些符号,以后就可以在visitor中以Java常量的形式引用这些符号了。
MUL : '*' ;
DIV : '/' ;
ADD : '+' ;
SUB : '-' ;
定义好上述文件后,利用Antlr插件,生成Lexer与Parser,由于设置了 –visitor选项,生成的文件中会有LabeledExprBaseVisitor类,新建EvalVisitor类,继承LabeledExprBaseVisitor(继承自所生成的LabeledExprVisitor类,这是默认实现包含了未实现的visitXX空方法),实现各个visitXX方法完成表达式的计算。
LabeledExprLexer lexer = new LabeledExprLexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); LabeledExprParser parser = new LabeledExprParser(tokens); ParseTree tree = parser.prog(); EvalVisitor eval = new EvalVisitor(); eval.visit(tree);
public class EvalVisitor extends LabeledExprBaseVisitor<Integer>{ // 这个map用于赋值表达式和id表达式。ID '=' expr NEWLINE,ID //当遇到id = x 的表达式时, 计算表达式值并存储<id,计算结果> //若遇到id查表,寻找其对应的值。Map<String, Integer> memory = new HashMap<String, Integer>(); // 处理ID表达式@Overridepublic Integer visitId(IdContext ctx) { String id = ctx.ID().getText(); if ( memory.containsKey(id) ) return memory.get(id); return 0; } // 处理括号表达式'(' expr ')',通过ctx得到表达式对象,然后通过 // visit方法处理表达式并反回结果,调用visit后会通过使用者定义的 // visitor处理(此处为EvalVisitor)@Overridepublic Integer visitParents(ParentsContext ctx) {return visit(ctx.expr());} // 遇到赋值表达式,同样通过visit处理 = 号右侧的表达式@Overridepublic Integer visitAssign(AssignContext ctx) {// TODO Auto-generated method stubString id = ctx.ID().getText();int value = visit(ctx.expr());memory.put(id, value);return value;} // 通过visit处理表达式@Overridepublic Integer visitPrintExpr(PrintExprContext ctx) {Integer value = visit(ctx.expr());System.out.println(value);return 0;} // 遇到终结符,直接返回结果@Overridepublic Integer visitInt(IntContext ctx) {return Integer.valueOf(ctx.INT().getText());} // 遇到加减表达式,判断符号,并进行运算。 // 生成的parser中包含了所定义的词法符号,通过public static final // 修饰,所以可以直接通过类名来引用。Op定义为public Token op,通过getType获取类型;@Overridepublic Integer visitAddSub(AddSubContext ctx) {int left = visit(ctx.expr(0));int right = visit(ctx.expr(1));if(ctx.op.getType() == LabeledExprParser.ADD) {return left + right;}return left - right;} @Overridepublic Integer visitMulDiv(MulDivContext ctx) {int left = visit(ctx.expr(0));int right = visit(ctx.expr(1));if(ctx.op.getType() == LabeledExprParser.MUL) {return left * right;}return left / right;}}
0 0
- The Definitive Antlr 4 第4章学习笔记
- The Definitive Antlr 4 第4章学习笔记
- The Definitive Antlr 4 第5章学习笔记
- The Definitive Antlr 4 第6章学习笔记
- The Definitive Antlr 4 第7章学习笔记
- The Definitive Antlr 4 第8章学习笔记
- The Definitive ANTLR 4 Reference (2nd Edition) - Chapter 1
- 《Hadoop.The.Definitive.Guide.4th.Edition.2015.3》学习笔记
- The Definitive ANTLR Reference: Building Domain-Specific Languages
- JavaScript: The Definitive Guide, 4th Edition
- Camtasia Studio 4: The Definitive Guide
- Hadoop:The Definitive Guide 4th Edition
- Hadoop The Definitive Guide 4th Editon
- HBase读书笔记_HBase The Definitive Guide_第8章
- Hadoop- The Definitive Guide 笔记
- Antlr学习笔记1
- antlr学习笔记
- ANTLR v4学习笔记
- 重载求最大值
- 【Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性
- Android学习之获取系统应用信息列表的实现
- 每周学一点Egret(12) Egret 一些资源链接
- jsp page指令 九个内置对象 四种属性范围 两种跳转的区别
- The Definitive Antlr 4 第4章学习笔记
- 【Matlab函数】conv2的用法
- Android Studio 提示与技巧(官方文档翻译)
- Android (shape,gradient)使用总结 (2
- Matlab函数meshgrid的作用:
- POJ 2376 :Cleaning Shifts(贪心)
- 第9章:statements
- Spark Streaming的Exactly-One的事务处理和不重复输出详解
- Gson-更新中