2017-11-26 编程语言试验之Antlr4+Java实现"圈2"
此文涉及的源码版本: program-in-chinese/quan2
声明 代码来源 How to Create Language Using Antlr4
本作主要作为学习Antlr, 以及实践中文命名之用. 目标不是一个实用的编程语言.
个人感觉这样可以比较容易的用原型来尝试和演示不同语法设计, 如果有更简单的途径请不吝赐教. 欢迎各种自行修改~碰到任何问题也欢迎一同探讨.
下面是"圈2"语言的示例代码:
开始
使 甲 为 5
使 乙 为 10
加 3 到 乙
加 乙 到 甲
加 甲 到 乙
打印 乙
打印 3
结束
附上需要自行编写的三个文件:
Antlr4的语法定义文件:
按照README说明, Antlr可以据此自动生成四个分析器相关类文件. T前缀是由于Antlr约定大写开头是Token定义. 标识符支持中文.
grammar 圈2;
程序 : '开始' 声明+ '结束';
声明 : 赋值 | 加 | 打印 ;
赋值 : '使' T标识符 '为' (T数 | T标识符) ;
打印 : '打印' (T数 | T标识符) ;
加 : '加' (T数 | T标识符) '到' T标识符 ;
T标识符 : ('a' .. 'z' | 'A' .. 'Z' | '\u4E00'..'\u9FA5' | '\uF900'..'\uFA2D')+ ;
T数 : [0-9]+ ;
T空白 : [ \n\t]+ -> skip;
定制监听器:
通过对每种语句分析后进行对应处理, 实质上起了解释器的作用.
public class 定制监听器 extends 圈2BaseListener {
private Map<String, Integer> 变量表;
public 定制监听器() {
变量表 = new HashMap<>();
}
@Override
public void exit赋值(赋值Context 上下文) {
// 赋值语句分析结束时运行此方法
String 变量名 = 上下文.T标识符(0).getText();
// 如果语句中有两个变量(标识符), 那么取第二个变量的值, 否则取数的值
int 值 = 上下文.T标识符().size() > 1
? 变量表.get(上下文.T标识符(1).getText())
: Integer.parseInt(上下文.T数().getText());
// 更新变量值
变量表.put(变量名, 值);
}
@Override
public void exit加(加Context 上下文) {
// 加语句分析结束时运行此方法
String 变量名 = 上下文.T标识符().size() > 1 ? 上下文.T标识符(1).getText() : 上下文.T标识符(0).getText();
int 添加值 = 上下文.T标识符().size() > 1 ? 变量表.get(上下文.T标识符(0).getText())
: Integer.parseInt(上下文.T数().getText());
变量表.put(变量名, 变量表.get(变量名) + 添加值);
}
@Override
public void exit打印(打印Context 上下文) {
// 打印语句分析结束时运行此方法
String 输出 = 上下文.T标识符() == null ? 上下文.T数().getText() : 变量表.get(上下文.T标识符().getText()).toString();
System.out.println(输出);
}
}
运行器:
读取文件输入, 调用附着了定制监听器的分析器
public class 运行器 {
public static void main(String[] 参数) {
try {
ANTLRInputStream 输入 = new ANTLRInputStream(new FileInputStream(参数[0]));
圈2Lexer 词法分析器 = new 圈2Lexer(输入);
圈2Parser 语法分析器 = new 圈2Parser(new CommonTokenStream(词法分析器));
语法分析器.addParseListener(new 定制监听器());
// 开始分析
语法分析器.程序();
} catch (IOException e) {
e.printStackTrace();
}
}
}
尚未探索如何用Antlr4实现无空格语法设计(不允许标识符中出现关键字应该可以做到, 但那样限制太多)
2017-11-26 编程语言试验之Antlr4+Java实现"圈2"的更多相关文章
- 2017-12-02 编程语言试验之Antlr4+JavaScript实现"圈4"
参考: ANTLR4: Making a compiler with the JavaScript runtime 演示效果虽弱, 还是先上图吧: 在线演示: 地址. 源码库: program-in- ...
- [LOJ 6248]「CodePlus 2017 11 月赛」晨跑
Description “无体育,不清华”.“每天锻炼一小时,健康工作五十年,幸福生活一辈子” 在清华,体育运动绝对是同学们生活中不可或缺的一部分.为了响应学校的号召,模范好学生王队长决定坚持晨跑.不 ...
- TIOBE 2017 8月编程语言排行榜 后院“硝烟四起”
处于排名榜最前面的几个编程语言的分数长期以来一直都在下降:Java和C在TIOBE榜单中的分数一直比较低.而且几乎所有其他排名前十的语言每年都在下降. 那么哪个什么语言抓住了这个机遇呢?这发生在排行榜 ...
- jingchi.ai 2017.11.25-26 Onsite面试
时间:2017.11.25 - 11.26 地点:安徽安庆 来回路费报销,住宿报销. day1: 大哥哥问了我一个实际中他们遇到的问题.有n个点,将点进行分块输出,输出各个块的均值点.具体就是100* ...
- 2017/11/3 Leetcode 日记
2017/11/3 Leetcode 日记 654. Maximum Binary Tree Given an integer array with no duplicates. A maximum ...
- Atitit。Cas机制 软件开发 编程语言 无锁机制 java c# php
Atitit.Cas机制 软件开发 编程语言 无锁机制 java c# php 1. 为什么需要无锁操作1 2. 硬件支持 cas atomic2 3. 无锁编程(Lock-Free)就是在某些应用 ...
- 2020年的六种编程语言排名中,java排第几只有不到1%的人知道
前言 编程语言是开发的基础.有不同的类型和特征,并且开发人员针对不同的场景选择正确的语言,但是您知道使用哪种语言吗?中国和世界各地有多少开发人员正在使用它?他们的排名是多少?快来看看您知道多少个列表! ...
- 团队作业4——第一次项目冲刺(Alpha版本)2017.4.26
2017.04.26 天气热. 时间:上午 9:35 ---10:10分 地点:陆大304实验室 会议内容:今天将昨天的的一些问题进行了讨论,以及针对助教提出的问题进行了分析,是因为我们昨天经过讨论后 ...
- [LOJ 6249]「CodePlus 2017 11 月赛」汀博尔
Description 有 n 棵树,初始时每棵树的高度为 H_i,第 i 棵树每月都会长高 A_i.现在有个木料长度总量为 S 的订单,客户要求每块木料的长度不能小于 L,而且木料必须是整棵树(即不 ...
随机推荐
- 记一次安装VS2015后启动失败的修复过程
安装过程没有提示任何问题,然而启动vs时提示没有安装 .Net Framework 4.6,那就安装吧,但是安装 4.6 时却提示 Windows Moudle Installer 服务没有启动,于是 ...
- java之LinkedList详细介绍
1 LinkedList介绍 LinkedList简介 LinkedList 是一个继承于AbstractSequentialList的双向链表.它也可以被当作堆栈.队列或双端队列进行操作.Linke ...
- JSON 字符串解析技巧总结
在解析JSONObject的字符数据的时候,可以考虑去使用optString 解析网络JSON数据时,获取数据的两个方法optString和getString: 使用optString获取数据时,即使 ...
- vscode 开发 Java web 急速教程
1.确认在本机已安装 JAVA SDK 2.确认在本机已安装 maven 3.确认在本机已安装 tomcat 下面是我本机相关软件版本: java version "1.8.0_191&qu ...
- Dispatch Queue 内存结构
Dispatch 源代码版本是libdispatch-84.5.5  会根据这个结构来分析dispatch_queue 对应的代码实现 参考 GCD源码分析3 -- dispatch_queue篇 ...
- Linux - 查看文件信息的三个命令
ls命令 - list directory contents 显示文件详细信息:ls -l <file name> file命令 - determine file type determi ...
- Spring Boot开启的 2 种方式
Spring Boot依赖 使用Spring Boot很简单,先添加基础依赖包,有以下两种方式 1. 继承spring-boot-starter-parent项目 <parent> < ...
- JavaEmail-邮箱
package service; import com.sun.mail.util.MailSSLSocketFactory;import javax.mail.Message;import java ...
- python之线程(threading)
线程是属于进程的,一个进程可能包含多个线程 至于线程和进程在使用时哪个更好,只能看使用的场景了 话不多说,看下线程模块(threading)的使用方法: #导入模块 import threading, ...
- oracle中常见的查询操作
普通查询:select * from t; 去除重复值:select distinct f1,f2 from t; between用法:select * from t where f1 not/bet ...