中文编程知乎专栏原文地址

基本参考https://pragprog.com/book/tpantlr2/the-definitive-antlr-4-reference 一书"Building a Calculator Using a Visitor"一节, 仅添加了数学乘除法符号的支持(×÷). 比如下面的算式:

3×2+8÷4-2×4

源码仍在program-in-chinese/quan5

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

至此, 感觉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;
}
} }

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

2018-01-11 Antlr4实现数学四则运算的更多相关文章

  1. IDEA(2018.01)安装和破解

    IDEA(2018.01)安装和破解 1.下载IDE https://www.jetbrains.com/idea/download/#section=windows 选择Ultimate版本 2.下 ...

  2. 20172319 2018.04.11 《Java程序设计教程》第7周课堂测验(补写博客)

    20172319 2018.04.11 <Java程序设计教程>第7周课堂测验 课程:<程序设计与数据结构> 班级:1723 学生:唐才铭 学号:20172319 指导老师:王 ...

  3. Apache Struts最新漏洞 远程代码执行漏洞预警 2018年11月08日

    2018年11月8日,SINE安全监控检测中心,检测到Apache Struts官方更新了一个Struts漏洞补丁,这个漏洞是Apache Struts目前最新的漏洞,影响范围较广,低于Apache ...

  4. CocoaPods管理iOS项目 2018年11月06日

    一.创建Test工程项目 二.打开终端 当前pod版本(1.6.0.beta.2最新版本2018年11月06日)和gem源路径(https://gems.ruby-china.com): 1.cd+当 ...

  5. 2018.09.11 poj2976Dropping tests(01分数规划)

    传送门 01分数规划板子题啊. 就是简单变形移项就行了. 显然 ∑i=1na[i]∑i=1nb[i]≤k" role="presentation" style=" ...

  6. Python 简单实现数学四则运算

    GitHub地址:https://github.com/compassblog/PythonExercise 一.题目描述 (1)能自动生成小学四则运算题目: (2)能支持真分数的四则运算: 二.实现 ...

  7. Cheatsheet: 2015 11.01 ~ 11.30

    Golang Roadomatic: Node vs. Go Quick Guide to Golang for Java Developers 3 Go Gotchas Web Choosing a ...

  8. 【2018.05.11 智能驾驶/汽车电子】非技术向:关于Simulink和AutoSar的几种观点

    最近看到几篇关于Simulink及AutoSar的Blog和Paper,感觉比较有意思,转载备忘之. 1. 看衰Simulink及AutoSar From:Tumiz的技术天地 https://blo ...

  9. Delphi及C++Builder经典图书一览表(持续更新中2018.01.02)

    序号 书名 原版书名 作者 译者 出版社 页数 年代 定价 备注 1 C++Builder 5程序设计大全 C++Builder 5 Developer's Guide Jarrod Hollingw ...

随机推荐

  1. 笔记:BroadcastReceiver的运行过程

    广播概述 广播用来在组件之间传递消息,可以是同进程或跨进程. 广播机制是基于发布订阅的事件驱动模型,使用上比Binder通信(跨进程接口回调)更低耦合.简单. ActivityManagerServi ...

  2. linux下报错bash: service: command not found

    在linux下操作的时候经常会遇到,bash: service: command not found这个错误,以前在网上找了,照着弄了,也没细看原因,今天又碰到这个问题,就顺便研究一下. 1.通常这种 ...

  3. Java 中的 HttpServletRequest 和 HttpServletResponse 对象

    HttpServletRequest对象详解 javax.servlet.http.HttpServletRequest是SUN制定的Servlet规范,是一个接口.表示请求,“HTTP请求协议”的完 ...

  4. JDK 安装目录中 native2ascii.exe 命令详解

    native2ascii 简介 native2ascii 是 sun java sdk提供的一个工具.用来将别的文本类文件(比如*.txt,*.ini,*.properties,*.java等等)编码 ...

  5. Android精通教程V

    前言 大家好,给大家带来Android精通教程V的概述,希望你们喜欢 前言 如果你想学习Android开发,那你就要了解Java编程,这是基础,也是重点,如果没学Java语法就先学习,再来学Andro ...

  6. postgresql-分页数据重复问题探索

    postgresql-分页数据重复探索 问题背景 许多开发和测试人员都可能遇到过列表的数据翻下一页的时候显示了上一页的数据,也就是翻页会有重复的数据. 如何处理? 这个问题出现的原因是因为选择的排序字 ...

  7. 【xsy1503】 fountain DP

    题目大意:给你$D$个格子,有$n$个喷水器,每个喷水器有一个喷水距离$r_i$. 现在你需要在这$D$个格子中选择$n$个位置按照任意顺序安装这$n$个喷水器,需要满足$n$个喷水器互相喷不到对方. ...

  8. [EXP]Apache Tika-server < 1.18 - Command Injection

    #################################################################################################### ...

  9. 疫苗:JAVA HASHMAP的死循环

    在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环.这个事情我4. ...

  10. Python之unittest测试代码

    前言 编写函数或者类时,还可以为其编写测试.通过测试,可确定代码面对各种输入都能够按要求的那样工作. 本次我将介绍如何使用Python模块unittest中的工具来测试代码. 测试函数 首先我们先编写 ...