博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2018-01-11 Antlr4实现数学四则运算
阅读量:6937 次
发布时间:2019-06-27

本文共 1773 字,大约阅读时间需要 5 分钟。

中文编程原文

基本参考 一书"Building a Calculator Using a Visitor"一节, 仅添加了数学乘除法符号的支持(×÷). 比如下面的算式:

3×2+8÷4-2×4

源码仍在

相比上一版本语法文件去除了空格定义. 需要深究的是优先级问题. 是否因为"表达式 运算符=('*'|'/'|'×'|'÷') 表达式"写在了前面才使得乘除法的优先级在语法分析时更高.

至此, 感觉Antlr语法文件对中文命名的支持还是不错的. 唯一需要权宜之计的就是Token(词)规则必须要大写开头, 因此采用了前缀"T"):

grammar 圈5;程序 : 表达式 ;表达式 : 表达式 运算符=('*'|'/'|'×'|'÷') 表达式     #乘除   | 表达式 运算符=('+'|'-') 表达式         #加減   | T数                    #数 ;T数 : [0-9]+ ;T加 : '+';T減 : '-';T乘 : '*';T数乘: '×';T除 : '/';T数除: '÷';

第一次尝试#标号的辅助功能. 一个"表达式"语法规则生成了三个Visitor方法(如下), 访问器仍比较简单. 注: 语法规则中要么所有分支都有标号, 要么都没有. 不然生成分析器时报错:

public class 定制访问器 extends 圈5BaseVisitor
<节点>
{ @Override public 节点 visit数(数Context 上下文) { TerminalNode 数 = 上下文.T数(); return 数 instanceof ErrorNode ? null : new 数节点(数.getText()); } @Override public 节点 visit加減(加減Context 上下文) { 表达式节点 节点 = new 表达式节点(); 节点.运算符 = 上下文.运算符.getType() == 圈5Parser.T加 ? 运算符号.加 : 运算符号.減; 节点.左子节点 = visit(上下文.表达式(0)); 节点.右子节点 = visit(上下文.表达式(1)); return 节点; } @Override public 节点 visit乘除(乘除Context 上下文) { 表达式节点 节点 = new 表达式节点(); int 运算符 = 上下文.运算符.getType(); 节点.运算符 = (运算符 == 圈5Parser.T乘 || 运算符 == 圈5Parser.T数乘) ? 运算符号.乘 : 运算符号.除; 节点.左子节点 = visit(上下文.表达式(0)); 节点.右子节点 = visit(上下文.表达式(1)); return 节点; }}

语法树中稍微复杂一点的"表达式"节点, 代码很冗余:

public class 表达式节点 extends 节点 {  public 运算符号 运算符;  @Override  public Object 求值() {    if (运算符.equals(运算符号.加)) {      return (int)(左子节点.求值()) + ((int)右子节点.求值());    } else if (运算符.equals(运算符号.減)) {      return (int)(左子节点.求值()) - ((int)右子节点.求值());    } else if (运算符.equals(运算符号.乘)) {      return (int)(左子节点.求值()) * ((int)右子节点.求值());    } else if (运算符.equals(运算符号.除)) {      return (int)(左子节点.求值()) / ((int)右子节点.求值());    } else {      return null;    }  }}

已经要手动跑十个测试文件, 下面除了清理代码, 还需要加测试, 再加功能(应该是变量赋值).

转载地址:http://bsbnl.baihongyu.com/

你可能感兴趣的文章
小蚂蚁学习数据结构(10)——树的基本介绍
查看>>
linux apache
查看>>
在CMD命令行下关闭进程的命令
查看>>
puppet学习笔记之安装与配置
查看>>
ROS教程(6)---×××配置及应用
查看>>
Nginx服务器搭建和基本配置详解
查看>>
vSphere 4.1 的新增功能
查看>>
栈的实现,入栈判断是否Full,出栈判断是否Empty
查看>>
nagios 安装配置
查看>>
centos 6.5下搭建ipsec/xl2tpd ×××
查看>>
【BFS】POJ 3278
查看>>
Python字符串格式化
查看>>
计算时针与分针夹角的度数的算法
查看>>
访问者设计模式
查看>>
支持伍洲彤鄙视蔡国庆
查看>>
我的友情链接
查看>>
Apache Shiro学习笔记(七)Servlet3.0 Listener介绍
查看>>
zabbix2
查看>>
我的友情链接
查看>>
char、varchar的区别
查看>>