ANTLR和网络:一个简单的例子
网络上的ANTLR:为什么?
我开始在MS-DOS上编写我的第一个程序。 因此,我非常习惯在计算机上安装工具。 但是在2016年,网络无处不在,因此那里也可能需要我们的语言。
可能的情况:
- ANTLR 也在网络上:
- 用户可能还希望从网络访问DSL编写的较小更改文件,并可能对其进行细微更改,同时继续使用胖客户端执行复杂任务。
- ANTLR 仅在网络上:
- 您正在与不愿安装IDE的领域专家打交道,因此他们更喜欢使用一些Web应用程序编写DSL程序。
在第一种情况下,您可以使用Java目标和 Javascript目标来生成ANTLR解析器,而在第二种情况下,您可以仅以JavaScript为目标
一个简单的例子:待办事项清单
在此示例中,我们将使用的DSL非常简单:它将表示一个待办事项列表,其中每个待办事项都包含在单独的行中,并以星号开头。
有效输入的示例:
* do this
* do that* do something else after an empty line
这是我们的语法:
grammar todo;elements: (element|emptyLine)* EOF;element: '*' ( ' ' | '\t' )* CONTENT NL+;emptyLine: NL;NL: '\r' | '\n' ;CONTENT: [a-zA-Z0-9_][a-zA-Z0-9_ \t]*;
使用ANTLR Javascript目标
您将需要安装ANTLR工具来为我们的解析器生成Javascript代码。 您可以使用简单的Gradle脚本来代替手动下载ANTLR及其依赖项。 更新所使用的ANTLR版本也非常简单。
apply plugin: 'java'repositories {jcenter()
}dependencies {runtime 'org.antlr:antlr4:4.5.2'
}task generateParser(type:JavaExec) {main = 'org.antlr.v4.Tool'classpath = sourceSets.main.runtimeClasspathargs = ['-Dlanguage=JavaScript', 'todo.g4', '-o', 'static/generated-parser']
}
您现在可以通过运行以下命令来生成解析器:
gradle generateParser
好的,这很简单。
调用解析器
不幸的是,仅打开本地文件时,我们使用的JS库无法正常工作:这意味着对于我们的小示例,我们也需要使用HTTP。 我们的Web服务器只需要提供大量静态文件即可。 为此,我选择在flask中编写一个超级简单的应用程序。 提供静态文件的替代方案有数百万种,因此请选择您喜欢的一种。 我不会在这里详细说明如何通过flask提供静态文件,但是GitHub上提供了代码,如果您对此有疑问,可以在此帖子中添加评论以告知我。
我们的静态文件将包括:
- 通过运行gradle generateParser得到的生成的解析器
- Antlr4 JS运行时
- JS库require.js
- HTML和CSS
您可以从此处获取Antlr4 JS运行时。 为了避免必须手动导入数十个文件,我们将使用require.js。 您可以从此处获取我们需要的口味或require.js。
我们将添加一个文本区域和一个按钮。 当用户单击按钮时,我们将解析文本区域的内容。 简单吧?
这是此设计杰作HTML代码:
<div id="inputs">
<textarea id="code">
* play with antlr4
* write a tutorial
</textarea>
<br/>
<button id="parse">Parse</button>
</div>
首先,导入require.js:
<script type="text/javascript" src="lib/require.js"></script>
顺便说一句,我们没有使用jQuery,我知道这可能令人震惊。
好,现在我们必须调用解析器
<script type="text/javascript">
var antlr4 = require('antlr4/index');
var TodoLexer = require('generated-parser/todoLexer');
var TodoParser = require('generated-parser/todoParser');
document.getElementById("parse").addEventListener("click", function(){var input = document.getElementById("code").value;var chars = new antlr4.InputStream(input);var lexer = new TodoLexer.todoLexer(chars);var tokens = new antlr4.CommonTokenStream(lexer);var parser = new TodoParser.todoParser(tokens);parser.buildParseTrees = true;var tree = parser.elements();console.log("Parsed: "+ tree);
});
</script>
太好了,现在我们的代码已解析,但是我们不对其执行任何操作。 当然,我们可以在浏览器中启动开发者控制台,并打印有关树的一些信息,以验证树是否正常工作并熟悉ANTLR返回的树的结构。
显示结果
如果我们正在构建某种TODO应用程序,我们可能希望以某种方式表示用户通过DSL插入的信息。
让我们得到这样的东西:
为此,我们基本上需要添加函数updateTree来导航由ANTLR返回的树,并构建一些DOM节点来表示其内容
<script type="text/javascript">
var updateTree = function(tree, ruleNames) {var container = document.getElementById("tree");while (container.hasChildNodes()) {container.removeChild(container.lastChild);}for (var i = 0; i < tree.children.length; i++) {var child = tree.children[i];var nodeType = ruleNames[child.ruleIndex];if (nodeType == "element") {var newElement = document.createElement("div");newElement.className = "todoElement";var newElementText = document.createTextNode(child.children[2].getText());newElement.appendChild(newElementText);container.appendChild(newElement);}}
};var antlr4 = require('antlr4/index');
var TodoLexer = require('generated-parser/todoLexer');
var TodoParser = require('generated-parser/todoParser');
document.getElementById("parse").addEventListener("click", function(){var input = document.getElementById("code").value;var chars = new antlr4.InputStream(input);var lexer = new TodoLexer.todoLexer(chars);var tokens = new antlr4.CommonTokenStream(lexer);var parser = new TodoParser.todoParser(tokens);parser.buildParseTrees = true;var tree = parser.elements();console.log("Parsed: "+ tree);updateTree(tree, parser.ruleNames);
});
</script>
干得好!
码
如果这不是您第一次阅读此博客,则可能会怀疑某些代码即将到来。 和往常一样,代码在GitHub上: https : //github.com/ftomassetti/antlr-web-example
下一步
下一步是执行错误处理:我们要捕获错误并将其指向用户。 然后,我们可能想通过使用ACE来添加语法突出显示。 这似乎是一个很好的起点:
- https://github.com/antlr/antlr4/blob/master/doc/ace-javascript-target.md
我真的认为简单的文本DSL可以帮助使多个应用程序更加强大。 但是,在网络上创建良好的编辑体验并非易事。 我想花更多时间玩这个。
翻译自: https://www.javacodegeeks.com/2016/05/antlr-web-simple-example.html
ANTLR和网络:一个简单的例子相关推荐
- antlr4例子_ANTLR和网络:一个简单的例子
antlr4例子 网络上的ANTLR:为什么? 我开始在MS-DOS上编写我的第一个程序. 因此,我非常习惯在自己的机器上安装工具. 但是在2016年,网络无处不在,因此那里也可能需要我们的语言. 可 ...
- .net中的对象序列化(1): 序列化是什么, 以及一个简单的例子
1. 为什么需要序列化,什么是序列化 对于一个程序来说, 使用到的对象都是存在于内存中的.如果想保存这些对象的运行时状态, 或者需要在不同进程或者网络间传递对象,就需要序列化. 序列化就是讲运行中的对 ...
- blockchain 区块链200行代码:在JavaScript实现的一个简单的例子
blockchain 区块链200行代码:在JavaScript实现的一个简单的例子 了解blockchain的概念很简单(区块链,交易链块):它是分布式的(即不是放置在同一台机器上,不同的网络设备上 ...
- 一步一步解读神经网络编译器TVM(一)——一个简单的例子
@TOC 前言 这是一个TVM教程系列,计划从TVM的使用说明,再到TVM的内部源码?为大家大致解析一下TVM的基本工作原理.因为TVM的中文资料比较少,也希望贡献一下自己的力量,如有描述方面的错误, ...
- 一个简单的例子看java线程机制
一个简单的例子看java线程机制 作者: zyf0808 发表日期: 2006-03-26 11:20 文章属性: 原创 复制链接 import java.util.*; public class T ...
- pycharm安装scrapy失败_Scrapy ——环境搭配与一个简单的例子
在我刚接触爬虫的时候就已经听过Scrapy大名了,据说是一个很厉害的爬虫框架,不过那个时候沉迷于Java爬虫.现在终于要来揭开它神秘的面纱了,来一起学习一下吧 欢迎关注公众号:老白和他的爬虫 1.环境 ...
- java继承类型转换_#java 一个简单的例子理解java继承、成员函数重写、类型转换...
一个简单的例子理解java继承.成员函数重写.类型转换 1.继承简介 举一个简单的例子:笔分为很多种,比如毛笔.钢笔.圆珠笔等等,这些笔都有一些相同的属性比如长度.笔迹的粗细等等:但他们也有不同的特点 ...
- 类模板与运算符重载(一个简单的例子)
类模板与运算符重载(一个简单的例子) 标签(空格分隔): C++ 算法竞赛 下面是一段简单的代码,表示我们建立了一个类模板Vector,可以看做是对STL中vector的简单实现. 为了让这个Vect ...
- 一个简单的例子,学习自定义注解和AOP
转载自 一个简单的例子,学习自定义注解和AOP 记得今年年初刚开始面试的时候,被问的最多的就是你知道Spring的两大核心嘛?那你说说什么是AOP,什么是IOC?我相信你可能也被问了很多次了. 1 ...
最新文章
- 转载-如何应对在线故障
- Redis configuration
- java数据结构至对称矩阵压缩存储
- Python教程:快速掌握列表的常用方法
- Grafana Worldmap外网用户request地图监控
- HTML5+NodeJs实现WebSocket即时通讯
- linux wenj 立即生效_【新书连载】测试工程师核心开发技术(3)—远程登录Linux系统...
- LeetCode 775. 全局倒置与局部倒置(归并排序/二分查找/一次遍历)
- localdatetime 默认时间_java中的时间与时区:LocalDateTime和Date
- 网络压缩《network pruning 浅析》
- 基于php计算机等级考试系统毕业设计网站作品
- 交互软件Axure—高保真原型
- linux配置maven环境变量
- 软件测试工程师绩效考核细则,软件测试工程师绩效考核方案
- 安装 3dsMax 2020 错误 1625 系统策略禁止这个安装
- 装linux系统的工具箱,PE,Dos工具箱,自动安装linux的U盘制作
- 3、Latex学习笔记之表格篇
- 黑苹果传统BIOS引导安装
- 计算机教师使用计划书,信息技术教师个人发展计划
- oracle 监控内存和硬盘的排序比率_最好使它小于 .10,监控数据库性能的SQL