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

基本参考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. iOS 不能加载电子签名

    问题: 1:使用WKWebView在iOS12.0以上的系统中,可以显示PDF中的电子图章,签名.在iOS12.0以下的系统中不能显示电子签名,图章. 2:  解决方案,使用PDF.js加载. pdf ...

  2. java之LinkedList详细介绍

    1 LinkedList介绍 LinkedList简介 LinkedList 是一个继承于AbstractSequentialList的双向链表.它也可以被当作堆栈.队列或双端队列进行操作.Linke ...

  3. PHP校验日期格式是否合法

    在后端开发中,我们常常需要校验前端传入参数的合法性,如果是校验日期参数,我们可以通过下面的方法来校验: /** * 校验日期格式是否合法 * @param string $date * @param ...

  4. 使用广播-BroadcastReceiver最详细解析

    女孩:BroadcastReceiver是什么呀? 男孩:Broadcast是广播的意思,在Android中应用程序之间的传输信息的机制,BroadcastReceiver是接收广播通知的组件,广播和 ...

  5. HoloLens开发手记 - 入门学习阶段总结

    伴随着数月的期待,终于拿到了预订的HoloLens开发者版本套件.随着VR/AR/MR技术的热潮,国内外均对它们的应用与盈利前景持有积极的预期,这也直接导致了国内外当前投资VR/AR/MR技术的热潮. ...

  6. eclipse clean和build作用

    由于eclipse的编译是基于时间戳的判断机制的. 因此当你按build   all的时候有些eclipse认为时间戳没有改变的类不会被编译. 因此你可以先clean一下再编译.这个时候eclipse ...

  7. 从零开始学 Web 之 HTML5(二)表单,多媒体新增内容,新增获取操作元素,自定义属性

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  8. SQL 必知必会·笔记<18>管理事务处理

    事务处理是一种机制,用来管理必须成批执行的SQL操作,保证数据库不包含不完整的操作结果.利用事务处理,可以保证一组操作不会中途停止,它们要 么完全执行,要么完全不执行(除非明确指示).如果没有错误发生 ...

  9. java ee期末项目相关

    1.项目简介 本项目是对纸杯生产进行管理的的一个系统,从前端接收到订单,然后根据订单内容进行纸杯的生产.如下为该系统的总流程图: 1.项目系统架构图 3.系统用例图 4.ER图 主要的代码和相关文件见 ...

  10. 记录线上与本地docker镜像一致,但Dockerfile却构建失败的问题

    背景 公司新开了某个项目,我在新的服务器部署了docker环境,本着ctrl+c 和ctrl+v的惯例,直接把以前的php环境的Dockerfile文件直接复制到新项目服务器那里,结果构建失败,失败的 ...